You've already forked Atomcms-edit
Add radio embed widget, SSE real-time, song history, moderation panel, and Auto DJ
- Embed widget: standalone iframe player with dark/light/transparent themes, copy-paste embed code admin page - Real-time SSE: streaming now-playing/listeners/dj events, replaces polling in radio-player and embed - Song history: auto-records song changes to radio_song_plays table, Filament resource to view - DJ moderation: unified panel for shouts approval, song request queue, DJ applications - Auto DJ: playlist management with round-robin playback when no DJ is live - Refactored radio-player Alpine component to use EventSource API with auto-reconnect
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Pages\Radio;
|
||||
|
||||
use App\Models\Miscellaneous\WebsiteSetting;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
final class EmbedCode extends Page implements HasForms
|
||||
{
|
||||
use InteractsWithForms;
|
||||
|
||||
#[\Override]
|
||||
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-code-bracket';
|
||||
|
||||
#[\Override]
|
||||
protected static string|\UnitEnum|null $navigationGroup = 'Radio';
|
||||
|
||||
#[\Override]
|
||||
protected static ?string $navigationLabel = 'Embed Code';
|
||||
|
||||
#[\Override]
|
||||
protected static ?string $title = 'Radio Embed Code';
|
||||
|
||||
#[\Override]
|
||||
protected string $view = 'filament.pages.radio.embed-code';
|
||||
|
||||
public array $data = [];
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->form->fill([
|
||||
'embed_theme' => $this->getSetting('radio_embed_theme', 'dark'),
|
||||
'embed_height' => $this->getSetting('radio_embed_height', '400'),
|
||||
'embed_width' => $this->getSetting('radio_embed_width', '100%'),
|
||||
'embed_auto_play' => $this->getSetting('radio_embed_auto_play', '0'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Section::make('Embed Configuratie')
|
||||
->description('Pas het uiterlijk van de embed player aan')
|
||||
->schema([
|
||||
Select::make('embed_theme')
|
||||
->label('Thema')
|
||||
->options([
|
||||
'dark' => 'Donker',
|
||||
'light' => 'Licht',
|
||||
'transparent' => 'Transparant',
|
||||
])
|
||||
->default('dark'),
|
||||
TextInput::make('embed_height')
|
||||
->label('Hoogte (px)')
|
||||
->numeric()
|
||||
->default(400),
|
||||
TextInput::make('embed_width')
|
||||
->label('Breedte')
|
||||
->placeholder('100% of 400px')
|
||||
->default('100%'),
|
||||
Toggle::make('embed_auto_play')
|
||||
->label('Auto-Play'),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function getIframeCode(): string
|
||||
{
|
||||
$theme = $this->data['embed_theme'] ?? 'dark';
|
||||
$height = $this->data['embed_height'] ?? '400';
|
||||
$width = $this->data['embed_width'] ?? '100%';
|
||||
$autoPlay = ($this->data['embed_auto_play'] ?? false) ? '&autoplay=1' : '';
|
||||
$url = route('radio.embed', ['theme' => $theme]) . $autoPlay;
|
||||
|
||||
return '<iframe src="' . e($url) . '" width="' . e($width) . '" height="' . e($height) . '" frameborder="0" allow="autoplay" style="border-radius: 12px;"></iframe>';
|
||||
}
|
||||
|
||||
public function getJsSnippet(): string
|
||||
{
|
||||
$theme = $this->data['embed_theme'] ?? 'dark';
|
||||
$autoPlay = ($this->data['embed_auto_play'] ?? false) ? '&autoplay=1' : '';
|
||||
$url = route('radio.embed', ['theme' => $theme]) . $autoPlay;
|
||||
|
||||
return '<div id="radio-embed"></div>
|
||||
<script>
|
||||
(function() {
|
||||
var iframe = document.createElement(\'iframe\');
|
||||
iframe.src = \'' . e($url) . '\';
|
||||
iframe.width = \'100%\';
|
||||
iframe.height = \'400\';
|
||||
iframe.frameBorder = \'0\';
|
||||
iframe.style.borderRadius = \'12px\';
|
||||
iframe.allow = \'autoplay\';
|
||||
document.getElementById(\'radio-embed\').appendChild(iframe);
|
||||
})();
|
||||
</script>';
|
||||
}
|
||||
|
||||
public function getDirectUrl(): string
|
||||
{
|
||||
$theme = $this->data['embed_theme'] ?? 'dark';
|
||||
$autoPlay = ($this->data['embed_auto_play'] ?? false) ? '&autoplay=1' : '';
|
||||
|
||||
return route('radio.embed', ['theme' => $theme]) . $autoPlay;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
private function getSetting(string $key, mixed $default = null): mixed
|
||||
{
|
||||
$setting = WebsiteSetting::where('key', $key)->first();
|
||||
|
||||
return $setting?->value ?? $default;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user