You've already forked Atomcms-edit
1631 lines
71 KiB
PHP
Executable File
1631 lines
71 KiB
PHP
Executable File
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Filament\Pages\Radio;
|
|
|
|
use App\Models\Miscellaneous\WebsiteSetting;
|
|
use Filament\Actions\Action;
|
|
use Filament\Forms\Components\ColorPicker;
|
|
use Filament\Forms\Components\Select;
|
|
use Filament\Forms\Components\Textarea;
|
|
use Filament\Forms\Components\TextInput;
|
|
use Filament\Forms\Components\TimePicker;
|
|
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;
|
|
use Illuminate\Support\Facades\Artisan;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
final class RadioSettings extends Page implements HasForms
|
|
{
|
|
use InteractsWithForms;
|
|
|
|
#[\Override]
|
|
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-radio';
|
|
|
|
#[\Override]
|
|
protected static string|\UnitEnum|null $navigationGroup = 'Radio';
|
|
|
|
#[\Override]
|
|
protected static ?string $navigationLabel = null;
|
|
|
|
#[\Override]
|
|
protected static ?string $title = 'Radio Settings';
|
|
|
|
#[\Override]
|
|
public static function getNavigationLabel(): string
|
|
{
|
|
return __('Radio Settings');
|
|
}
|
|
|
|
#[\Override]
|
|
public function getTitle(): string
|
|
{
|
|
return __('radio.title');
|
|
}
|
|
|
|
#[\Override]
|
|
protected string $view = 'filament.pages.radio.radio-settings';
|
|
|
|
/** @var array<string, mixed> */
|
|
public array $data = [];
|
|
|
|
public ?string $currentDjId = null;
|
|
|
|
private const string CACHE_KEY = 'website_settings';
|
|
|
|
public function mount(): void
|
|
{
|
|
$this->fillForm();
|
|
}
|
|
|
|
protected function fillForm(): void
|
|
{
|
|
$this->data = [
|
|
'radio_enabled' => $this->getSettingBool('radio_enabled'),
|
|
'radio_stream_url' => $this->getSetting('radio_stream_url', ''),
|
|
'radio_stream_backup_url' => $this->getSetting('radio_stream_backup_url', ''),
|
|
'radio_style' => $this->getSetting('radio_style', 'dark'),
|
|
'radio_player_type' => $this->getSetting('radio_player_type', 'default'),
|
|
'radio_auto_play' => $this->getSettingBool('radio_auto_play'),
|
|
'radio_auto_play_delay' => (int) $this->getSetting('radio_auto_play_delay', '0'),
|
|
'radio_mute_on_start' => $this->getSettingBool('radio_mute_on_start'),
|
|
'radio_volume' => (int) $this->getSetting('radio_volume', '80'),
|
|
'radio_applications_enabled' => $this->getSettingBool('radio_applications_enabled'),
|
|
'radio_applications_max_per_day' => (int) $this->getSetting('radio_applications_max_per_day', '1'),
|
|
'radio_applications_require_approval' => $this->getSettingBool('radio_applications_require_approval'),
|
|
'radio_widget_enabled' => $this->getSettingBool('radio_widget_enabled'),
|
|
'radio_widget_show_globally' => $this->getSettingBool('radio_widget_show_globally'),
|
|
'radio_widget_position' => $this->getSetting('radio_widget_position', 'bottom-right'),
|
|
'radio_shouts_enabled' => $this->getSettingBool('radio_shouts_enabled'),
|
|
'radio_shouts_max_length' => (int) $this->getSetting('radio_shouts_max_length', '280'),
|
|
'radio_shouts_cooldown' => (int) $this->getSetting('radio_shouts_cooldown', '30'),
|
|
'radio_shouts_require_moderation' => $this->getSettingBool('radio_shouts_require_moderation'),
|
|
'radio_chat_enabled' => $this->getSettingBool('radio_chat_enabled'),
|
|
'radio_chat_position' => $this->getSetting('radio_chat_position', 'right'),
|
|
'radio_chat_width' => (int) $this->getSetting('radio_chat_width', '350'),
|
|
'radio_chat_height' => (int) $this->getSetting('radio_chat_height', '500'),
|
|
'radio_chat_messages_count' => (int) $this->getSetting('radio_chat_messages_count', '50'),
|
|
'radio_chat_show_timestamps' => $this->getSettingBool('radio_chat_show_timestamps'),
|
|
'radio_chat_allow_links' => $this->getSettingBool('radio_chat_allow_links'),
|
|
'radio_chat_allow_emojis' => $this->getSettingBool('radio_chat_allow_emojis'),
|
|
'radio_now_playing_enabled' => $this->getSettingBool('radio_now_playing_enabled'),
|
|
'radio_now_playing_api_url' => $this->getSetting('radio_now_playing_api_url', ''),
|
|
'radio_now_playing_cache_duration' => (int) $this->getSetting('radio_now_playing_cache_duration', '30'),
|
|
'radio_show_song_history' => $this->getSettingBool('radio_show_song_history'),
|
|
'radio_song_history_count' => (int) $this->getSetting('radio_song_history_count', '10'),
|
|
'radio_listeners_enabled' => $this->getSettingBool('radio_listeners_enabled'),
|
|
'radio_listeners_api_url' => $this->getSetting('radio_listeners_api_url', ''),
|
|
'radio_show_listener_peak' => $this->getSettingBool('radio_show_listener_peak'),
|
|
'radio_peak_reset_time' => $this->getSetting('radio_peak_reset_time', '00:00'),
|
|
'radio_listeners_update_interval' => (int) $this->getSetting('radio_listeners_update_interval', '30'),
|
|
'radio_store_listener_stats' => $this->getSettingBool('radio_store_listener_stats'),
|
|
'radio_stats_retention_days' => (int) $this->getSetting('radio_stats_retention_days', '30'),
|
|
'radio_min_listeners_threshold' => (int) $this->getSetting('radio_min_listeners_threshold', '0'),
|
|
'radio_listener_alerts_enabled' => $this->getSettingBool('radio_listener_alerts_enabled'),
|
|
'radio_listener_alert_threshold_high' => (int) $this->getSetting('radio_listener_alert_threshold_high', '100'),
|
|
'radio_listener_alert_threshold_low' => (int) $this->getSetting('radio_listener_alert_threshold_low', '5'),
|
|
'radio_show_listener_graph' => $this->getSettingBool('radio_show_listener_graph'),
|
|
'radio_listener_graph_period' => $this->getSetting('radio_listener_graph_period', '24h'),
|
|
'radio_show_average_listeners' => $this->getSettingBool('radio_show_average_listeners'),
|
|
'radio_show_unique_listeners' => $this->getSettingBool('radio_show_unique_listeners'),
|
|
'radio_show_current_dj' => $this->getSettingBool('radio_show_current_dj'),
|
|
'current_dj_id' => $this->getSetting('radio_current_dj_id', ''),
|
|
'radio_dj_avatar_size' => (int) $this->getSetting('radio_dj_avatar_size', '64'),
|
|
'radio_default_avatar_figure' => $this->getSetting('radio_default_avatar_figure', 'hr-893-45.hd-180-2.ch-210-62.lg-285-62.sh-295-62.ha-1012-62.wa-2007-0'),
|
|
'radio_default_dj_name' => $this->getSetting('radio_default_dj_name', 'Frank'),
|
|
'radio_show_dj_avatar_popup' => $this->getSettingBool('radio_show_dj_avatar_popup'),
|
|
'radio_dj_avatar_popup_duration' => (int) $this->getSetting('radio_dj_avatar_popup_duration', '5'),
|
|
'radio_show_dj_schedule' => $this->getSettingBool('radio_show_dj_schedule'),
|
|
'radio_auto_dj_detection' => $this->getSettingBool('radio_auto_dj_detection'),
|
|
'radio_dj_detection_interval' => (int) $this->getSetting('radio_dj_detection_interval', '60'),
|
|
'auto_dj_detected_action' => $this->getSetting('auto_dj_detected_action', 'set_dj'),
|
|
'radio_sambroadcaster_api_url' => $this->getSetting('radio_sambroadcaster_api_url', ''),
|
|
'radio_sambroadcaster_password' => $this->getSetting('radio_sambroadcaster_password', ''),
|
|
'radio_virtual_dj_url' => $this->getSetting('radio_virtual_dj_url', ''),
|
|
'radio_virtual_dj_password' => $this->getSetting('radio_virtual_dj_password', ''),
|
|
'radio_djs_api_url' => $this->getSetting('radio_djs_api_url', ''),
|
|
'radio_request_form_enabled' => $this->getSettingBool('radio_request_form_enabled'),
|
|
'radio_request_max_per_user' => (int) $this->getSetting('radio_request_max_per_user', '3'),
|
|
'radio_request_cooldown' => (int) $this->getSetting('radio_request_cooldown', '300'),
|
|
'radio_voting_enabled' => $this->getSettingBool('radio_voting_enabled'),
|
|
'radio_voting_show_song_requests' => $this->getSettingBool('radio_voting_show_song_requests'),
|
|
'radio_stats_show_daily' => $this->getSettingBool('radio_stats_show_daily'),
|
|
'radio_stats_show_weekly' => $this->getSettingBool('radio_stats_show_weekly'),
|
|
'radio_stats_show_monthly' => $this->getSettingBool('radio_stats_show_monthly'),
|
|
'radio_stats_show_top_djs' => $this->getSettingBool('radio_stats_show_top_djs'),
|
|
'radio_stats_show_top_songs' => $this->getSettingBool('radio_stats_show_top_songs'),
|
|
'radio_show_offline_message' => $this->getSettingBool('radio_show_offline_message'),
|
|
'radio_offline_message' => $this->getSetting('radio_offline_message', 'We zijn momenteel offline. Check onze socials voor updates!'),
|
|
'radio_offline_image' => $this->getSetting('radio_offline_image', ''),
|
|
'radio_background_image' => $this->getSetting('radio_background_image', ''),
|
|
'radio_logo_url' => $this->getSetting('radio_logo_url', ''),
|
|
'radio_player_color_primary' => $this->getSetting('radio_player_color_primary', '#eeb425'),
|
|
'radio_player_color_secondary' => $this->getSetting('radio_player_color_secondary', '#1a1a2e'),
|
|
'radio_player_color_text' => $this->getSetting('radio_player_color_text', '#ffffff'),
|
|
'radio_player_color_accent' => $this->getSetting('radio_player_color_accent', '#eeb425'),
|
|
'radio_custom_css' => $this->getSetting('radio_custom_css', ''),
|
|
'radio_custom_js' => $this->getSetting('radio_custom_js', ''),
|
|
'radio_social_facebook' => $this->getSetting('radio_social_facebook', ''),
|
|
'radio_social_twitter' => $this->getSetting('radio_social_twitter', ''),
|
|
'radio_social_instagram' => $this->getSetting('radio_social_instagram', ''),
|
|
'radio_social_discord' => $this->getSetting('radio_social_discord', ''),
|
|
'radio_social_youtube' => $this->getSetting('radio_social_youtube', ''),
|
|
'radio_social_twitch' => $this->getSetting('radio_social_twitch', ''),
|
|
'radio_contact_email' => $this->getSetting('radio_contact_email', ''),
|
|
'radio_contact_phone' => $this->getSetting('radio_contact_phone', ''),
|
|
'radio_about_text' => $this->getSetting('radio_about_text', ''),
|
|
'radio_azurecast_base_url' => $this->getSetting('radio_azurecast_base_url', ''),
|
|
'radio_azurecast_station_id' => (int) $this->getSetting('radio_azurecast_station_id', '1'),
|
|
'radio_azurecast_api_key' => $this->getSetting('radio_azurecast_api_key', ''),
|
|
'radio_azurecast_port' => (int) $this->getSetting('radio_azurecast_port', '8443'),
|
|
'radio_azurecast_protocol' => $this->getSetting('radio_azurecast_protocol', 'https'),
|
|
'radio_azurecast_use_proxy' => $this->getSettingBool('radio_azurecast_use_proxy'),
|
|
'radio_language' => $this->getSetting('radio_language', 'nl'),
|
|
'radio_multi_language_enabled' => $this->getSettingBool('radio_multi_language_enabled'),
|
|
'radio_discord_webhook_url' => $this->getSetting('radio_discord_webhook_url', ''),
|
|
'radio_discord_enabled' => $this->getSettingBool('radio_discord_enabled'),
|
|
'radio_discord_dj_live' => $this->getSettingBool('radio_discord_dj_live'),
|
|
'radio_discord_song_changes' => $this->getSettingBool('radio_discord_song_changes'),
|
|
'radio_discord_custom_message' => $this->getSetting('radio_discord_custom_message', 'DJ {dj_name} is nu live!'),
|
|
];
|
|
|
|
$this->currentDjId = $this->data['current_dj_id'] ?? null;
|
|
}
|
|
|
|
public function form(Schema $schema): Schema
|
|
{
|
|
return $schema
|
|
->components([
|
|
Section::make('Radio Auto-Setup')
|
|
->description('In 1 klik je radio installeren en configureren')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('install_azurecast')
|
|
->label('Installeer AzureCast')
|
|
->action('installAndSetupAzurecast')
|
|
->color('success'),
|
|
Action::make('auto_setup')
|
|
->label('Auto-Setup')
|
|
->action('fullAutoSetup')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
TextInput::make('radio_stream_url')
|
|
->label('Stream URL')
|
|
->placeholder('https://jouw-radio.nl/radio.mp3')
|
|
->url()
|
|
->columnSpan(2)
|
|
->hint('Voer je AzureCast stream URL in'),
|
|
Toggle::make('radio_enabled')
|
|
->label('Radio Inschakelen')
|
|
->columnSpanFull(),
|
|
]),
|
|
Section::make('AzureCast Configuratie')
|
|
->description('Handmatige AzureCast instellingen')
|
|
->collapsed()
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('save_azurecast')
|
|
->label('Opslaan')
|
|
->action('saveAzurecast')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
TextInput::make('radio_azurecast_base_url')
|
|
->label('AzureCast Basis URL')
|
|
->placeholder('https://radio.jouwdomein.nl')
|
|
->url()
|
|
->columnSpan(2),
|
|
TextInput::make('radio_azurecast_station_id')
|
|
->label('Station ID')
|
|
->numeric()
|
|
->default(1),
|
|
TextInput::make('radio_azurecast_api_key')
|
|
->label('API Key')
|
|
->password(),
|
|
TextInput::make('radio_azurecast_port')
|
|
->label('Poort')
|
|
->numeric()
|
|
->default(8443),
|
|
Select::make('radio_azurecast_protocol')
|
|
->label('Protocol')
|
|
->options([
|
|
'http' => 'HTTP',
|
|
'https' => 'HTTPS',
|
|
])
|
|
->default('https'),
|
|
Toggle::make('radio_azurecast_use_proxy')
|
|
->label('Proxy Gebruiken'),
|
|
]),
|
|
Section::make('Sambroadcaster & Virtual DJ')
|
|
->description('Verbinding met Sambroadcaster en Virtual DJ software')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('check_dj')
|
|
->label('Check DJ Verbinding')
|
|
->action('checkDjConnection')
|
|
->color('info'),
|
|
Action::make('save_sambroadcaster')
|
|
->label('Opslaan')
|
|
->action('saveSambroadcaster')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
TextInput::make('radio_sambroadcaster_api_url')
|
|
->label('Sambroadcaster API URL')
|
|
->url(),
|
|
TextInput::make('radio_sambroadcaster_password')
|
|
->label('Sambroadcaster Wachtwoord')
|
|
->password(),
|
|
TextInput::make('radio_virtual_dj_url')
|
|
->label('Virtual DJ URL')
|
|
->url(),
|
|
TextInput::make('radio_virtual_dj_password')
|
|
->label('Virtual DJ Wachtwoord')
|
|
->password(),
|
|
TextInput::make('radio_djs_api_url')
|
|
->label('DJs API URL')
|
|
->url(),
|
|
]),
|
|
Section::make('Player Configuratie')
|
|
->description('Basis player instellingen')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('save_player')
|
|
->label('Opslaan')
|
|
->action('savePlayer')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
Select::make('radio_style')
|
|
->label('Player Stijl')
|
|
->options([
|
|
'dark' => 'Donker',
|
|
'light' => 'Licht',
|
|
'blue' => 'Blauw',
|
|
'purple' => 'Paars',
|
|
'pink' => 'Roze',
|
|
'gold' => 'Goud',
|
|
])
|
|
->default('dark'),
|
|
Select::make('radio_player_type')
|
|
->label('Player Type')
|
|
->options([
|
|
'default' => 'Standaard',
|
|
'minimal' => 'Minimaal',
|
|
'embedded' => 'Ingebed',
|
|
])
|
|
->default('default'),
|
|
Toggle::make('radio_auto_play')
|
|
->label('Auto-Play'),
|
|
TextInput::make('radio_auto_play_delay')
|
|
->label('Auto-Play Vertraging (seconden)')
|
|
->numeric()
|
|
->default(0),
|
|
Toggle::make('radio_mute_on_start')
|
|
->label('Gedempt Starten'),
|
|
TextInput::make('radio_volume')
|
|
->label('Standaard Volume')
|
|
->numeric()
|
|
->minValue(0)
|
|
->maxValue(100)
|
|
->default(80),
|
|
Select::make('radio_language')
|
|
->label('Systeem Taal')
|
|
->options([
|
|
'nl' => 'Nederlands',
|
|
'en' => 'English',
|
|
'de' => 'Deutsch',
|
|
'fr' => 'Français',
|
|
'es' => 'Español',
|
|
'pt' => 'Português',
|
|
'it' => 'Italiano',
|
|
'br' => 'Português Brasil',
|
|
])
|
|
->default('nl'),
|
|
Toggle::make('radio_multi_language_enabled')
|
|
->label('Multi-taal Ondersteuning'),
|
|
]),
|
|
Section::make('Player Kleuren')
|
|
->description('Player kleuren aanpassen')
|
|
->columns(3)
|
|
->afterHeader([
|
|
Action::make('save_colors')
|
|
->label('Opslaan')
|
|
->action('saveColors')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
ColorPicker::make('radio_player_color_primary')
|
|
->label('Primaire Kleur')
|
|
->default('#eeb425'),
|
|
ColorPicker::make('radio_player_color_secondary')
|
|
->label('Secundaire Kleur')
|
|
->default('#1a1a2e'),
|
|
ColorPicker::make('radio_player_color_text')
|
|
->label('Tekst Kleur')
|
|
->default('#ffffff'),
|
|
ColorPicker::make('radio_player_color_accent')
|
|
->label('Accent Kleur')
|
|
->default('#eeb425'),
|
|
]),
|
|
Section::make('Nu Afspelen')
|
|
->description('Nu afspelen informatie')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('save_now_playing')
|
|
->label('Opslaan')
|
|
->action('saveNowPlaying')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
Toggle::make('radio_now_playing_enabled')
|
|
->label('Nu Afspelen Inschakelen'),
|
|
TextInput::make('radio_now_playing_api_url')
|
|
->label('API URL')
|
|
->url(),
|
|
TextInput::make('radio_now_playing_cache_duration')
|
|
->label('Cache Duur (seconden)')
|
|
->numeric()
|
|
->default(30),
|
|
Toggle::make('radio_show_song_history')
|
|
->label('Song Geschiedenis Tonen'),
|
|
TextInput::make('radio_song_history_count')
|
|
->label('Aantal Songs in Geschiedenis')
|
|
->numeric()
|
|
->default(10),
|
|
]),
|
|
Section::make('Luisteraars Statistieken')
|
|
->description('Luisteraars informatie en statistieken')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('save_listeners')
|
|
->label('Opslaan')
|
|
->action('saveListeners')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
Toggle::make('radio_listeners_enabled')
|
|
->label('Luisteraars Aantal Inschakelen'),
|
|
TextInput::make('radio_listeners_api_url')
|
|
->label('API URL')
|
|
->url(),
|
|
TextInput::make('radio_listeners_update_interval')
|
|
->label('Update Interval (seconden)')
|
|
->numeric()
|
|
->default(30),
|
|
Toggle::make('radio_show_listener_peak')
|
|
->label('Piek Luisteraars Tonen'),
|
|
TimePicker::make('radio_peak_reset_time')
|
|
->label('Piektijd Reset')
|
|
->seconds(false)
|
|
->format('H:i')
|
|
->default('00:00'),
|
|
Toggle::make('radio_store_listener_stats')
|
|
->label('Statistieken Opslaan'),
|
|
TextInput::make('radio_stats_retention_days')
|
|
->label('Retentie Dagen')
|
|
->numeric()
|
|
->default(30),
|
|
Toggle::make('radio_show_listener_graph')
|
|
->label('Luisteraars Grafiek Tonen'),
|
|
Select::make('radio_listener_graph_period')
|
|
->label('Grafiek Periode')
|
|
->options([
|
|
'1h' => '1 Uur',
|
|
'6h' => '6 Uur',
|
|
'12h' => '12 Uur',
|
|
'24h' => '24 Uur',
|
|
'7d' => '7 Dagen',
|
|
])
|
|
->default('24h'),
|
|
Toggle::make('radio_show_average_listeners')
|
|
->label('Gemiddelde Luisteraars Tonen'),
|
|
Toggle::make('radio_show_unique_listeners')
|
|
->label('Unieke Luisteraars Tonen'),
|
|
]),
|
|
Section::make('Luisteraars Meldingen')
|
|
->description('Meldingen bij luisteraars changes')
|
|
->columns(2)
|
|
->schema([
|
|
Toggle::make('radio_listener_alerts_enabled')
|
|
->label('Luisteraars Meldingen Inschakelen'),
|
|
TextInput::make('radio_min_listeners_threshold')
|
|
->label('Minimale Luisteraars Drempel')
|
|
->numeric()
|
|
->default(0),
|
|
TextInput::make('radio_listener_alert_threshold_high')
|
|
->label('Hoge Luisteraars Melding')
|
|
->numeric()
|
|
->default(100),
|
|
TextInput::make('radio_listener_alert_threshold_low')
|
|
->label('Lage Luisteraars Melding')
|
|
->numeric()
|
|
->default(5),
|
|
]),
|
|
Section::make('DJ Instellingen')
|
|
->description('Huidige DJ en schedule')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('save_dj')
|
|
->label('Opslaan')
|
|
->action('saveDj')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
Toggle::make('radio_show_current_dj')
|
|
->label('Huidige DJ Tonen'),
|
|
TextInput::make('current_dj_id')
|
|
->label('Handmatige DJ (User ID)')
|
|
->numeric(),
|
|
TextInput::make('radio_dj_avatar_size')
|
|
->label('Avatar Grootte (px)')
|
|
->numeric()
|
|
->default(64),
|
|
TextInput::make('radio_default_avatar_figure')
|
|
->label('Default Avatar Figure (geen DJ)')
|
|
->helperText('Habbo figure code voor wanneer er geen DJ live is (bijv. hr-893-45.hd-180-2...)')
|
|
->placeholder('hr-893-45.hd-180-2.ch-210-62.lg-285-62.sh-295-62.ha-1012-62.wa-2007-0'),
|
|
TextInput::make('radio_default_dj_name')
|
|
->label('Default DJ Naam (geen DJ)')
|
|
->default('Frank'),
|
|
Toggle::make('radio_show_dj_avatar_popup')
|
|
->label('DJ Avatar Popup Tonen')
|
|
->helperText('Toon een popup met DJ avatar wanneer een DJ live gaat'),
|
|
TextInput::make('radio_dj_avatar_popup_duration')
|
|
->label('Popup Duur (seconden)')
|
|
->numeric()
|
|
->default(5)
|
|
->helperText('Hoe lang de popup zichtbaar blijft'),
|
|
Toggle::make('radio_show_dj_schedule')
|
|
->label('DJ Schedule Tonen'),
|
|
]),
|
|
Section::make('Auto DJ Detectie')
|
|
->description('Automatisch DJ detecteren')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('check_connection')
|
|
->label('Check Verbinding')
|
|
->action('checkDjConnection')
|
|
->color('info'),
|
|
Action::make('save_auto_dj')
|
|
->label('Opslaan')
|
|
->action('saveAutoDj')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
Toggle::make('radio_auto_dj_detection')
|
|
->label('Auto DJ Detectie Inschakelen'),
|
|
TextInput::make('radio_dj_detection_interval')
|
|
->label('Detectie Interval (seconden)')
|
|
->numeric()
|
|
->default(60),
|
|
Select::make('auto_dj_detected_action')
|
|
->label('Bij Detectie')
|
|
->options([
|
|
'set_dj' => 'DJ Automatisch Instellen',
|
|
'notify' => 'Alleen Melding Sturen',
|
|
'both' => 'Instellen en Melden',
|
|
])
|
|
->default('set_dj'),
|
|
]),
|
|
Section::make('Shouts')
|
|
->description('Shoutbox instellingen')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('save_shouts')
|
|
->label('Opslaan')
|
|
->action('saveShouts')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
Toggle::make('radio_shouts_enabled')
|
|
->label('Shouts Inschakelen'),
|
|
TextInput::make('radio_shouts_max_length')
|
|
->label('Max. Karakters')
|
|
->numeric()
|
|
->default(280),
|
|
TextInput::make('radio_shouts_cooldown')
|
|
->label('Cooldown (seconden)')
|
|
->numeric()
|
|
->default(30),
|
|
Toggle::make('radio_shouts_require_moderation')
|
|
->label('Moderatie Vereist'),
|
|
]),
|
|
Section::make('Live Chat')
|
|
->description('Live chat naast de player')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('save_chat')
|
|
->label('Opslaan')
|
|
->action('saveChat')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
Toggle::make('radio_chat_enabled')
|
|
->label('Chat Inschakelen'),
|
|
Select::make('radio_chat_position')
|
|
->label('Chat Positie')
|
|
->options([
|
|
'left' => 'Links',
|
|
'right' => 'Rechts',
|
|
'bottom' => 'Onder',
|
|
])
|
|
->default('right'),
|
|
TextInput::make('radio_chat_width')
|
|
->label('Chat Breedte (px)')
|
|
->numeric()
|
|
->default(350),
|
|
TextInput::make('radio_chat_height')
|
|
->label('Chat Hoogte (px)')
|
|
->numeric()
|
|
->default(500),
|
|
TextInput::make('radio_chat_messages_count')
|
|
->label('Aantal Berichten')
|
|
->numeric()
|
|
->default(50),
|
|
Toggle::make('radio_chat_show_timestamps')
|
|
->label('Tijden Tonen'),
|
|
Toggle::make('radio_chat_allow_links')
|
|
->label('Links Toestaan'),
|
|
Toggle::make('radio_chat_allow_emojis')
|
|
->label('Emojis Toestaan'),
|
|
]),
|
|
Section::make('Song Verzoeken')
|
|
->description('Song request formulier instellingen')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('save_requests')
|
|
->label('Opslaan')
|
|
->action('saveRequests')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
Toggle::make('radio_request_form_enabled')
|
|
->label('Verzoekformulier Inschakelen'),
|
|
TextInput::make('radio_request_max_per_user')
|
|
->label('Max. Verzoeken per Gebruiker')
|
|
->numeric()
|
|
->default(3),
|
|
TextInput::make('radio_request_cooldown')
|
|
->label('Cooldown (seconden)')
|
|
->numeric()
|
|
->default(300),
|
|
Toggle::make('radio_voting_enabled')
|
|
->label('Stemmen Inschakelen'),
|
|
Toggle::make('radio_voting_show_song_requests')
|
|
->label('Verzoeken met Stemmen Tonen'),
|
|
]),
|
|
Section::make('Radio Widget')
|
|
->description('Kleine radio widget voor op de site')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('save_widget')
|
|
->label('Opslaan')
|
|
->action('saveWidget')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
Toggle::make('radio_widget_enabled')
|
|
->label('Widget Inschakelen'),
|
|
Toggle::make('radio_widget_show_globally')
|
|
->label('Widget Overal Tonen'),
|
|
Select::make('radio_widget_position')
|
|
->label('Widget Positie')
|
|
->options([
|
|
'bottom-right' => 'Rechts Onder',
|
|
'bottom-left' => 'Links Onder',
|
|
'top-right' => 'Rechts Boven',
|
|
'top-left' => 'Links Boven',
|
|
])
|
|
->default('bottom-right'),
|
|
]),
|
|
Section::make('Offline Pagina')
|
|
->description('Instellingen voor wanneer de radio offline is')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('save_offline')
|
|
->label('Opslaan')
|
|
->action('saveOffline')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
Toggle::make('radio_show_offline_message')
|
|
->label('Offline Bericht Tonen'),
|
|
Textarea::make('radio_offline_message')
|
|
->label('Offline Bericht')
|
|
->rows(3),
|
|
TextInput::make('radio_offline_image')
|
|
->label('Offline Afbeelding URL')
|
|
->url(),
|
|
TextInput::make('radio_background_image')
|
|
->label('Achtergrond Afbeelding URL')
|
|
->url(),
|
|
TextInput::make('radio_logo_url')
|
|
->label('Logo URL')
|
|
->url(),
|
|
]),
|
|
Section::make('DJ Aanmeldingen')
|
|
->description('Instellingen voor DJ sollicitaties')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('save_applications')
|
|
->label('Opslaan')
|
|
->action('saveApplications')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
Toggle::make('radio_applications_enabled')
|
|
->label('Aanmeldingen Inschakelen'),
|
|
TextInput::make('radio_applications_max_per_day')
|
|
->label('Max. Aanmeldingen per Dag')
|
|
->numeric()
|
|
->default(1),
|
|
Toggle::make('radio_applications_require_approval')
|
|
->label('Goedkeuring Vereist'),
|
|
]),
|
|
Section::make('Statistieken Weergave')
|
|
->description('Welke statistieken tonen op de site')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('save_stats')
|
|
->label('Opslaan')
|
|
->action('saveStats')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
Toggle::make('radio_stats_show_daily')
|
|
->label('Dagelijkse Statistieken'),
|
|
Toggle::make('radio_stats_show_weekly')
|
|
->label('Wekelijkse Statistieken'),
|
|
Toggle::make('radio_stats_show_monthly')
|
|
->label('Maandelijkse Statistieken'),
|
|
Toggle::make('radio_stats_show_top_djs')
|
|
->label('Top DJs'),
|
|
Toggle::make('radio_stats_show_top_songs')
|
|
->label('Top Songs'),
|
|
]),
|
|
Section::make('Social Media Links')
|
|
->description('Links naar je social media')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('save_social')
|
|
->label('Opslaan')
|
|
->action('saveSocial')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
TextInput::make('radio_social_facebook')
|
|
->label('Facebook URL')
|
|
->url(),
|
|
TextInput::make('radio_social_twitter')
|
|
->label('Twitter URL')
|
|
->url(),
|
|
TextInput::make('radio_social_instagram')
|
|
->label('Instagram URL')
|
|
->url(),
|
|
TextInput::make('radio_social_discord')
|
|
->label('Discord URL')
|
|
->url(),
|
|
TextInput::make('radio_social_youtube')
|
|
->label('YouTube URL')
|
|
->url(),
|
|
TextInput::make('radio_social_twitch')
|
|
->label('Twitch URL')
|
|
->url(),
|
|
]),
|
|
Section::make('Contact Informatie')
|
|
->description('Contact informatie')
|
|
->columns(2)
|
|
->schema([
|
|
TextInput::make('radio_contact_email')
|
|
->label('E-mail')
|
|
->email(),
|
|
TextInput::make('radio_contact_phone')
|
|
->label('Telefoon'),
|
|
Textarea::make('radio_about_text')
|
|
->label('Over Ons Tekst')
|
|
->rows(4),
|
|
]),
|
|
Section::make('Discord Webhook')
|
|
->description('Discord notificaties voor DJ live, nummers, etc.')
|
|
->columns(2)
|
|
->afterHeader([
|
|
Action::make('test_discord')
|
|
->label('Test Webhook')
|
|
->action('testDiscordWebhook')
|
|
->color('warning'),
|
|
Action::make('save_discord')
|
|
->label('Opslaan')
|
|
->action('saveDiscord')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
Toggle::make('radio_discord_enabled')
|
|
->label('Discord Inschakelen')
|
|
->columnSpanFull(),
|
|
TextInput::make('radio_discord_webhook_url')
|
|
->label('Webhook URL')
|
|
->url()
|
|
->columnSpanFull(),
|
|
Toggle::make('radio_discord_dj_live')
|
|
->label('DJ Live Melding'),
|
|
Toggle::make('radio_discord_song_changes')
|
|
->label('Nummer Wijziging Melding'),
|
|
Textarea::make('radio_discord_custom_message')
|
|
->label('Custom Bericht')
|
|
->rows(3)
|
|
->columnSpanFull()
|
|
->helperText('Gebruik {dj_name}, {song}, {listeners}'),
|
|
]),
|
|
Section::make('Custom Code')
|
|
->description('Aangepaste CSS en JavaScript')
|
|
->columns(1)
|
|
->afterHeader([
|
|
Action::make('save_custom')
|
|
->label('Opslaan')
|
|
->action('saveCustom')
|
|
->color('primary'),
|
|
])
|
|
->schema([
|
|
Textarea::make('radio_custom_css')
|
|
->label('Custom CSS')
|
|
->rows(10),
|
|
Textarea::make('radio_custom_js')
|
|
->label('Custom JavaScript')
|
|
->rows(10),
|
|
]),
|
|
])
|
|
->statePath('data');
|
|
}
|
|
|
|
public function savePlayer(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_style', 'radio_player_type', 'radio_auto_play',
|
|
'radio_auto_play_delay', 'radio_mute_on_start', 'radio_volume',
|
|
'radio_language', 'radio_multi_language_enabled',
|
|
]);
|
|
}
|
|
|
|
public function saveAzurecast(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_enabled', 'radio_azurecast_base_url', 'radio_azurecast_station_id',
|
|
'radio_azurecast_api_key', 'radio_azurecast_port', 'radio_azurecast_protocol',
|
|
'radio_azurecast_use_proxy', 'radio_stream_url', 'radio_stream_backup_url',
|
|
]);
|
|
}
|
|
|
|
public function saveSambroadcaster(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_sambroadcaster_api_url', 'radio_sambroadcaster_password',
|
|
'radio_virtual_dj_url', 'radio_virtual_dj_password', 'radio_djs_api_url',
|
|
]);
|
|
}
|
|
|
|
public function saveAutoDj(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_auto_dj_detection', 'radio_dj_detection_interval',
|
|
'auto_dj_detected_action',
|
|
]);
|
|
}
|
|
|
|
public function saveChat(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_chat_enabled', 'radio_chat_position', 'radio_chat_width',
|
|
'radio_chat_height', 'radio_chat_messages_count', 'radio_chat_show_timestamps',
|
|
'radio_chat_allow_links', 'radio_chat_allow_emojis',
|
|
]);
|
|
}
|
|
|
|
public function saveColors(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_player_color_primary', 'radio_player_color_secondary',
|
|
'radio_player_color_text', 'radio_player_color_accent',
|
|
]);
|
|
}
|
|
|
|
public function saveNowPlaying(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_now_playing_enabled', 'radio_now_playing_api_url',
|
|
'radio_now_playing_cache_duration', 'radio_show_song_history',
|
|
'radio_song_history_count',
|
|
]);
|
|
}
|
|
|
|
public function saveListeners(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_listeners_enabled', 'radio_listeners_api_url',
|
|
'radio_listeners_update_interval', 'radio_show_listener_peak',
|
|
'radio_peak_reset_time', 'radio_store_listener_stats',
|
|
'radio_stats_retention_days', 'radio_show_listener_graph',
|
|
'radio_listener_graph_period', 'radio_show_average_listeners',
|
|
'radio_show_unique_listeners',
|
|
]);
|
|
}
|
|
|
|
public function saveDj(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_show_current_dj', 'current_dj_id', 'radio_dj_avatar_size',
|
|
'radio_default_avatar_figure', 'radio_default_dj_name',
|
|
'radio_show_dj_avatar_popup', 'radio_dj_avatar_popup_duration',
|
|
'radio_show_dj_schedule',
|
|
]);
|
|
}
|
|
|
|
public function saveShouts(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_shouts_enabled', 'radio_shouts_max_length',
|
|
'radio_shouts_cooldown', 'radio_shouts_require_moderation',
|
|
]);
|
|
}
|
|
|
|
public function saveRequests(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_request_form_enabled', 'radio_request_max_per_user',
|
|
'radio_request_cooldown', 'radio_voting_enabled',
|
|
'radio_voting_show_song_requests',
|
|
]);
|
|
}
|
|
|
|
public function saveWidget(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_widget_enabled', 'radio_widget_show_globally',
|
|
'radio_widget_position',
|
|
]);
|
|
}
|
|
|
|
public function saveOffline(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_show_offline_message', 'radio_offline_message',
|
|
'radio_offline_image', 'radio_background_image',
|
|
'radio_logo_url',
|
|
]);
|
|
}
|
|
|
|
public function saveApplications(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_applications_enabled', 'radio_applications_max_per_day',
|
|
'radio_applications_require_approval',
|
|
]);
|
|
}
|
|
|
|
public function saveStats(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_stats_show_daily', 'radio_stats_show_weekly',
|
|
'radio_stats_show_monthly', 'radio_stats_show_top_djs',
|
|
'radio_stats_show_top_songs',
|
|
]);
|
|
}
|
|
|
|
public function saveSocial(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_social_facebook', 'radio_social_twitter',
|
|
'radio_social_instagram', 'radio_social_discord',
|
|
'radio_social_youtube', 'radio_social_twitch',
|
|
'radio_contact_email', 'radio_contact_phone',
|
|
'radio_about_text',
|
|
]);
|
|
}
|
|
|
|
public function saveCustom(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_custom_css', 'radio_custom_js',
|
|
]);
|
|
}
|
|
|
|
public function saveDiscord(): void
|
|
{
|
|
$this->saveSettings([
|
|
'radio_discord_enabled', 'radio_discord_webhook_url',
|
|
'radio_discord_dj_live', 'radio_discord_song_changes',
|
|
'radio_discord_custom_message',
|
|
]);
|
|
}
|
|
|
|
public function autoSetupAzurecast(): void
|
|
{
|
|
$streamUrl = $this->data['radio_stream_url'] ?? '';
|
|
$baseUrl = $this->data['radio_azurecast_base_url'] ?? '';
|
|
|
|
if (empty($streamUrl) && empty($baseUrl)) {
|
|
Notification::make()
|
|
->warning()
|
|
->title('URL Vereist')
|
|
->body('Vul de Stream URL of AzureCast Basis URL in.')
|
|
->send();
|
|
|
|
return;
|
|
}
|
|
|
|
try {
|
|
if (! empty($streamUrl)) {
|
|
$parsed = parse_url((string) $streamUrl);
|
|
if ($parsed) {
|
|
$scheme = $parsed['scheme'] ?? 'https';
|
|
$host = $parsed['host'] ?? '';
|
|
$detectedBaseUrl = $scheme . '://' . $host;
|
|
$testUrl = $detectedBaseUrl . '/api/nowplaying';
|
|
|
|
$response = Http::timeout(5)->get($testUrl);
|
|
if ($response->ok()) {
|
|
$data = $response->json();
|
|
if (is_array($data)) {
|
|
$stationId = $data[0]['station']['id'] ?? $data['station']['id'] ?? 1;
|
|
|
|
$this->saveSettings([
|
|
'radio_enabled' => true,
|
|
'radio_azurecast_base_url' => $detectedBaseUrl,
|
|
'radio_azurecast_station_id' => $stationId,
|
|
'radio_now_playing_enabled' => true,
|
|
'radio_listeners_enabled' => true,
|
|
'radio_show_current_dj' => true,
|
|
'radio_widget_enabled' => true,
|
|
'radio_widget_show_globally' => true,
|
|
]);
|
|
|
|
Notification::make()
|
|
->success()
|
|
->title('Success!')
|
|
->body("AzureCast gedetecteerd! Station ID: {$stationId}")
|
|
->send();
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (! empty($baseUrl)) {
|
|
$baseUrl = rtrim((string) $baseUrl, '/');
|
|
$response = Http::timeout(10)->get($baseUrl . '/api/stations');
|
|
|
|
if ($response->ok()) {
|
|
$stations = $response->json();
|
|
|
|
if (! empty($stations) && is_array($stations)) {
|
|
$station = $stations[0];
|
|
$stationId = $station['id'] ?? 1;
|
|
$stationName = $station['name'] ?? 'Radio';
|
|
|
|
$streamFromStation = $station['url'] ?? $station['mounts'][0]['url'] ?? $streamUrl ?? '';
|
|
|
|
$this->saveSettings([
|
|
'radio_enabled' => true,
|
|
'radio_azurecast_base_url' => $baseUrl,
|
|
'radio_azurecast_station_id' => $stationId,
|
|
'radio_stream_url' => $streamFromStation,
|
|
'radio_now_playing_enabled' => true,
|
|
'radio_listeners_enabled' => true,
|
|
'radio_show_current_dj' => true,
|
|
'radio_widget_enabled' => true,
|
|
'radio_widget_show_globally' => true,
|
|
]);
|
|
|
|
Notification::make()
|
|
->success()
|
|
->title('Success!')
|
|
->body("Station '{$stationName}' (ID: {$stationId}) is geconfigureerd!")
|
|
->send();
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
Notification::make()
|
|
->danger()
|
|
->title('Niet Gevonden')
|
|
->body('Kon AzureCast niet detecteren. Controleer de URL.')
|
|
->send();
|
|
|
|
} catch (\Exception $e) {
|
|
Notification::make()
|
|
->danger()
|
|
->title('Verbindingsfout')
|
|
->body('Kon geen verbinding maken: ' . $e->getMessage())
|
|
->send();
|
|
}
|
|
}
|
|
|
|
public function fullAutoSetup(): void
|
|
{
|
|
$streamUrl = $this->data['radio_stream_url'] ?? '';
|
|
|
|
if (empty($streamUrl)) {
|
|
Notification::make()
|
|
->warning()
|
|
->title('Stream URL Vereist')
|
|
->body('Voer je AzureCast stream URL in (bijv. https://jouw-radio.nl/radio.mp3)')
|
|
->send();
|
|
|
|
return;
|
|
}
|
|
|
|
Notification::make()
|
|
->info()
|
|
->title('Auto-Setup')
|
|
->body('Configuratie wordt gestart...')
|
|
->send();
|
|
|
|
$detectedBaseUrl = null;
|
|
$stationId = 1;
|
|
$apiKey = '';
|
|
|
|
$parsed = parse_url($streamUrl);
|
|
if ($parsed) {
|
|
$scheme = $parsed['scheme'] ?? 'https';
|
|
$host = $parsed['host'] ?? '';
|
|
$detectedBaseUrl = $scheme . '://' . $host;
|
|
$apiTestUrl = $detectedBaseUrl . '/api/nowplaying/1';
|
|
|
|
try {
|
|
$response = Http::timeout(10)->get($apiTestUrl);
|
|
if ($response->ok()) {
|
|
$npData = $response->json();
|
|
if (isset($npData['station']['id'])) {
|
|
$stationId = $npData['station']['id'];
|
|
}
|
|
}
|
|
} catch (\Exception) {
|
|
try {
|
|
$response = Http::timeout(10)->get($detectedBaseUrl . '/api/stations');
|
|
if ($response->ok()) {
|
|
$stations = $response->json();
|
|
if (! empty($stations)) {
|
|
$stationId = $stations[0]['id'] ?? 1;
|
|
if (! empty($stations[0]['url'])) {
|
|
$streamUrl = $stations[0]['url'];
|
|
}
|
|
}
|
|
}
|
|
} catch (\Exception) {
|
|
// Continue with defaults
|
|
}
|
|
}
|
|
}
|
|
|
|
if (empty($detectedBaseUrl)) {
|
|
Notification::make()
|
|
->danger()
|
|
->title('AzureCast Niet Gevonden')
|
|
->body('Kon AzureCast server niet bereiken. Controleer de stream URL.')
|
|
->send();
|
|
|
|
return;
|
|
}
|
|
|
|
$settings = [
|
|
'radio_enabled' => '1',
|
|
'radio_azurecast_base_url' => $detectedBaseUrl,
|
|
'radio_azurecast_station_id' => (string) $stationId,
|
|
'radio_stream_url' => $streamUrl,
|
|
'radio_now_playing_enabled' => '1',
|
|
'radio_listeners_enabled' => '1',
|
|
'radio_show_current_dj' => '1',
|
|
'radio_widget_enabled' => '1',
|
|
'radio_widget_show_globally' => '1',
|
|
'radio_azurecast_use_proxy' => '1',
|
|
'radio_shouts_enabled' => '1',
|
|
'radio_applications_enabled' => '1',
|
|
];
|
|
|
|
foreach ($settings as $key => $value) {
|
|
WebsiteSetting::updateOrCreate(
|
|
['key' => $key],
|
|
['value' => $value],
|
|
);
|
|
}
|
|
|
|
Cache::flush();
|
|
Artisan::call('config:clear');
|
|
Artisan::call('cache:clear');
|
|
|
|
Notification::make()
|
|
->success()
|
|
->title('🎉 Radio Klaar!')
|
|
->body("Alles is geconfigureerd! Stream: {$streamUrl}")
|
|
->send();
|
|
}
|
|
|
|
public function installAndSetupAzurecast(): void
|
|
{
|
|
Notification::make()
|
|
->info()
|
|
->title('Zoeken naar AzureCast...')
|
|
->body('Ik zoek naar een bestaande AzureCast server.')
|
|
->send();
|
|
|
|
$foundPort = null;
|
|
$commonPorts = [2000, 2250, 8000, 8080, 8443, 9000];
|
|
|
|
foreach ($commonPorts as $testPort) {
|
|
try {
|
|
$response = Http::timeout(2)->get("http://localhost:{$testPort}/api/nowplaying/1");
|
|
if ($response->ok()) {
|
|
$foundPort = $testPort;
|
|
break;
|
|
}
|
|
} catch (\Exception) {
|
|
// Try next port
|
|
}
|
|
}
|
|
|
|
if ($foundPort) {
|
|
Notification::make()
|
|
->success()
|
|
->title('AzureCast Gevonden!')
|
|
->body("AzureCast draait al op poort {$foundPort}")
|
|
->send();
|
|
|
|
$this->configureExistingAzureCast($foundPort);
|
|
|
|
return;
|
|
}
|
|
|
|
Notification::make()
|
|
->info()
|
|
->title('Geen AzureCast Gevonden')
|
|
->body('Voer je stream URL in en klik op Auto-Setup')
|
|
->send();
|
|
|
|
$this->fullAutoSetup();
|
|
}
|
|
|
|
private function configureExistingAzureCast(int $port): void
|
|
{
|
|
$baseUrl = "http://localhost:{$port}";
|
|
|
|
try {
|
|
$response = Http::timeout(5)->get($baseUrl . '/api/stations');
|
|
$stations = $response->ok() ? $response->json() : [];
|
|
$stationId = $stations[0]['id'] ?? 1;
|
|
$streamUrl = $stations[0]['url'] ?? $baseUrl . '/radio.mp3';
|
|
} catch (\Exception $e) {
|
|
$stationId = 1;
|
|
$streamUrl = $baseUrl . '/radio.mp3';
|
|
}
|
|
|
|
$settings = [
|
|
'radio_enabled' => '1',
|
|
'radio_azurecast_base_url' => $baseUrl,
|
|
'radio_azurecast_station_id' => (string) $stationId,
|
|
'radio_stream_url' => $streamUrl,
|
|
'radio_now_playing_enabled' => '1',
|
|
'radio_listeners_enabled' => '1',
|
|
'radio_show_current_dj' => '1',
|
|
'radio_widget_enabled' => '1',
|
|
'radio_widget_show_globally' => '1',
|
|
'radio_shouts_enabled' => '1',
|
|
];
|
|
|
|
foreach ($settings as $key => $value) {
|
|
WebsiteSetting::updateOrCreate(
|
|
['key' => $key],
|
|
['value' => $value],
|
|
);
|
|
}
|
|
|
|
Cache::flush();
|
|
Artisan::call('config:clear');
|
|
Artisan::call('cache:clear');
|
|
|
|
Notification::make()
|
|
->success()
|
|
->title('🎉 Alles Klaar!')
|
|
->body("Radio werkt op http://localhost:{$port}")
|
|
->send();
|
|
}
|
|
|
|
private function autoConfigureFromUrl(string $streamUrl): void
|
|
{
|
|
$parsed = parse_url($streamUrl);
|
|
if (! $parsed) {
|
|
Notification::make()
|
|
->danger()
|
|
->title('Ongeldige URL')
|
|
->body(' Voer een geldige stream URL in.')
|
|
->send();
|
|
|
|
return;
|
|
}
|
|
|
|
$scheme = $parsed['scheme'] ?? 'https';
|
|
$host = $parsed['host'] ?? '';
|
|
$baseUrl = $scheme . '://' . $host;
|
|
|
|
try {
|
|
$response = Http::timeout(10)->get($baseUrl . '/api/nowplaying/1');
|
|
if (! $response->ok()) {
|
|
$response = Http::timeout(10)->get($baseUrl . '/api/stations');
|
|
}
|
|
} catch (\Exception $e) {
|
|
Notification::make()
|
|
->danger()
|
|
->title('Verbindingsfout')
|
|
->body('Kon AzureCast niet bereiken.')
|
|
->send();
|
|
|
|
return;
|
|
}
|
|
|
|
$stationId = 1;
|
|
$actualStreamUrl = $streamUrl;
|
|
|
|
try {
|
|
$npResponse = Http::timeout(5)->get($baseUrl . '/api/nowplaying/1');
|
|
if ($npResponse->ok()) {
|
|
$npData = $npResponse->json();
|
|
$stationId = $npData['station']['id'] ?? 1;
|
|
}
|
|
|
|
$stationsResponse = Http::timeout(5)->get($baseUrl . '/api/stations');
|
|
if ($stationsResponse->ok()) {
|
|
$stations = $stationsResponse->json();
|
|
if (! empty($stations)) {
|
|
$stationId = $stations[0]['id'] ?? 1;
|
|
$actualStreamUrl = $stations[0]['url'] ?? $streamUrl;
|
|
}
|
|
}
|
|
} catch (\Exception) {
|
|
// Use defaults
|
|
}
|
|
|
|
$settings = [
|
|
'radio_enabled' => '1',
|
|
'radio_azurecast_base_url' => $baseUrl,
|
|
'radio_azurecast_station_id' => (string) $stationId,
|
|
'radio_stream_url' => $actualStreamUrl,
|
|
'radio_now_playing_enabled' => '1',
|
|
'radio_listeners_enabled' => '1',
|
|
'radio_show_current_dj' => '1',
|
|
'radio_widget_enabled' => '1',
|
|
'radio_widget_show_globally' => '1',
|
|
'radio_shouts_enabled' => '1',
|
|
];
|
|
|
|
foreach ($settings as $key => $value) {
|
|
WebsiteSetting::updateOrCreate(
|
|
['key' => $key],
|
|
['value' => $value],
|
|
);
|
|
}
|
|
|
|
Cache::flush();
|
|
Artisan::call('config:clear');
|
|
Artisan::call('cache:clear');
|
|
|
|
Notification::make()
|
|
->success()
|
|
->title('🎉 Radio Klaar!')
|
|
->body("Alles geconfigureerd op {$baseUrl}")
|
|
->send();
|
|
}
|
|
|
|
private function findFreePort(int $start = 2000, int $end = 9000): ?int
|
|
{
|
|
for ($port = $start; $port <= $end; $port++) {
|
|
$connection = @fsockopen('127.0.0.1', $port);
|
|
if ($connection === false) {
|
|
return $port;
|
|
}
|
|
fclose($connection);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function testDiscordWebhook(): void
|
|
{
|
|
$webhookUrl = $this->data['radio_discord_webhook_url'] ?? '';
|
|
|
|
if (empty($webhookUrl)) {
|
|
Notification::make()
|
|
->warning()
|
|
->title('Webhook URL Vereist')
|
|
->body('Vul eerst de Discord Webhook URL in.')
|
|
->send();
|
|
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$payload = ['content' => '🎵 Radio Discord integration test - Success!'];
|
|
$response = Http::post($webhookUrl, $payload);
|
|
|
|
if ($response->ok()) {
|
|
Notification::make()
|
|
->success()
|
|
->title('Test Verzonden!')
|
|
->body('Testbericht is succesvol naar Discord gestuurd.')
|
|
->send();
|
|
} else {
|
|
Notification::make()
|
|
->danger()
|
|
->title(__('Error'))
|
|
->body('Kon bericht niet versturen. Status: ' . $response->status())
|
|
->send();
|
|
}
|
|
} catch (\Exception $e) {
|
|
Notification::make()
|
|
->danger()
|
|
->title(__('Error'))
|
|
->body('Verbindingsfout: ' . $e->getMessage())
|
|
->send();
|
|
}
|
|
}
|
|
|
|
public function checkDjConnection(): void
|
|
{
|
|
$detectedDj = null;
|
|
$source = null;
|
|
|
|
$sambroadcasterUrl = $this->data['radio_sambroadcaster_api_url'] ?? '';
|
|
$virtualDjUrl = $this->data['radio_virtual_dj_url'] ?? '';
|
|
|
|
if (! empty($sambroadcasterUrl)) {
|
|
try {
|
|
$response = Http::timeout(5)->get($sambroadcasterUrl . '/dj');
|
|
|
|
if ($response->ok()) {
|
|
$data = $response->json();
|
|
$detectedDj = $data['dj_name'] ?? $data['dj'] ?? $data['current_dj'] ?? null;
|
|
$source = 'Sambroadcaster';
|
|
}
|
|
} catch (\Exception $e) {
|
|
Notification::make()
|
|
->warning()
|
|
->title('Sambroadcaster Fout')
|
|
->body('Kon geen verbinding maken met Sambroadcaster: ' . $e->getMessage())
|
|
->send();
|
|
}
|
|
}
|
|
|
|
if ($detectedDj === null && ! empty($virtualDjUrl)) {
|
|
try {
|
|
$response = Http::timeout(5)->withBasicAuth('admin', $this->data['radio_virtual_dj_password'] ?? '')
|
|
->get($virtualDjUrl . '/api/v1/status');
|
|
|
|
if ($response->ok()) {
|
|
$data = $response->json();
|
|
$detectedDj = $data['current_dj'] ?? $data['dj'] ?? null;
|
|
$source = 'Virtual DJ';
|
|
}
|
|
} catch (\Exception $e) {
|
|
Notification::make()
|
|
->warning()
|
|
->title('Virtual DJ Fout')
|
|
->body('Kon geen verbinding maken met Virtual DJ: ' . $e->getMessage())
|
|
->send();
|
|
}
|
|
}
|
|
|
|
if ($detectedDj !== null) {
|
|
$action = $this->data['auto_dj_detected_action'] ?? 'set_dj';
|
|
|
|
if (in_array($action, ['set_dj', 'both'])) {
|
|
Notification::make()
|
|
->success()
|
|
->title('DJ Gedetecteerd!')
|
|
->body("{$detectedDj} is verbonden via {$source}.")
|
|
->send();
|
|
} else {
|
|
Notification::make()
|
|
->info()
|
|
->title('DJ Gedetecteerd')
|
|
->body("{$detectedDj} is actief via {$source}.")
|
|
->send();
|
|
}
|
|
} else {
|
|
Notification::make()
|
|
->warning()
|
|
->title('Geen DJ Gevonden')
|
|
->body('Er kon geen actieve DJ worden gedetecteerd.')
|
|
->send();
|
|
}
|
|
}
|
|
|
|
private function saveSettings(array $keys): void
|
|
{
|
|
foreach ($keys as $key => $value) {
|
|
if (is_numeric($key)) {
|
|
$settingKey = $value;
|
|
$settingValue = $this->data[$value] ?? '';
|
|
} else {
|
|
$settingKey = $key;
|
|
$settingValue = $value;
|
|
}
|
|
|
|
$boolSettings = [
|
|
'radio_enabled', 'radio_auto_play', 'radio_mute_on_start',
|
|
'radio_multi_language_enabled', 'radio_show_current_dj',
|
|
'radio_now_playing_enabled', 'radio_show_song_history',
|
|
'radio_listeners_enabled', 'radio_show_listener_peak',
|
|
'radio_store_listener_stats', 'radio_show_listener_graph',
|
|
'radio_show_average_listeners', 'radio_show_unique_listeners',
|
|
'radio_show_dj_schedule', 'radio_auto_dj_detection',
|
|
'radio_shouts_enabled', 'radio_shouts_require_moderation',
|
|
'radio_chat_enabled', 'radio_chat_show_timestamps',
|
|
'radio_chat_allow_links', 'radio_chat_allow_emojis',
|
|
'radio_request_form_enabled', 'radio_voting_enabled',
|
|
'radio_voting_show_song_requests', 'radio_stats_show_daily',
|
|
'radio_stats_show_weekly', 'radio_stats_show_monthly',
|
|
'radio_stats_show_top_djs', 'radio_stats_show_top_songs',
|
|
'radio_show_offline_message', 'radio_widget_enabled',
|
|
'radio_widget_show_globally', 'radio_applications_enabled',
|
|
'radio_applications_require_approval', 'radio_discord_enabled',
|
|
'radio_discord_dj_live', 'radio_discord_song_changes',
|
|
'radio_listener_alerts_enabled', 'radio_azurecast_use_proxy',
|
|
];
|
|
|
|
$intSettings = [
|
|
'radio_auto_play_delay', 'radio_volume',
|
|
'radio_now_playing_cache_duration', 'radio_song_history_count',
|
|
'radio_listeners_update_interval', 'radio_stats_retention_days',
|
|
'radio_dj_avatar_size', 'radio_dj_detection_interval',
|
|
'radio_shouts_max_length', 'radio_shouts_cooldown',
|
|
'radio_chat_width', 'radio_chat_height', 'radio_chat_messages_count',
|
|
'radio_request_max_per_user', 'radio_request_cooldown',
|
|
'radio_min_listeners_threshold', 'radio_listener_alert_threshold_high',
|
|
'radio_listener_alert_threshold_low', 'radio_applications_max_per_day',
|
|
'radio_azurecast_station_id',
|
|
];
|
|
|
|
if (in_array($settingKey, $boolSettings)) {
|
|
$dbValue = $settingValue ? '1' : '0';
|
|
} elseif (in_array($settingKey, $intSettings)) {
|
|
$dbValue = (string) ($settingValue ?? 0);
|
|
} else {
|
|
$dbValue = (string) ($settingValue ?? '');
|
|
}
|
|
|
|
WebsiteSetting::updateOrCreate(
|
|
['key' => $settingKey],
|
|
['value' => $dbValue],
|
|
);
|
|
}
|
|
|
|
$this->clearCache();
|
|
|
|
Notification::make()
|
|
->success()
|
|
->title(__('Saved'))
|
|
->body('Alle instellingen zijn succesvol opgeslagen!')
|
|
->send();
|
|
}
|
|
|
|
private function clearCache(): void
|
|
{
|
|
Cache::forget(self::CACHE_KEY);
|
|
}
|
|
|
|
private function getSettingBool(string $key): bool
|
|
{
|
|
return (bool) WebsiteSetting::where('key', $key)->first()?->value;
|
|
}
|
|
|
|
private function getSetting(string $key, string $default = ''): string
|
|
{
|
|
return WebsiteSetting::where('key', $key)->first()?->value ?? $default;
|
|
}
|
|
|
|
#[\Override]
|
|
protected function getHeaderActions(): array
|
|
{
|
|
return [
|
|
Action::make('setup')
|
|
->label('🚀 ' . __('radio.setup.button_label'))
|
|
->icon('heroicon-o-rocket-launch')
|
|
->color('warning')
|
|
->size('lg')
|
|
->requiresConfirmation()
|
|
->modalHeading(__('radio.setup.modal_heading'))
|
|
->modalDescription(__('radio.setup.modal_description'))
|
|
->modalSubmitActionLabel(__('radio.setup.modal_submit'))
|
|
->action(function () {
|
|
$this->runAllInOneSetup();
|
|
})
|
|
->tooltip(__('radio.setup.tooltip')),
|
|
];
|
|
}
|
|
|
|
public function runAllInOneSetup(): void
|
|
{
|
|
try {
|
|
// Standard radio settings
|
|
$settings = [
|
|
'radio_enabled' => '1',
|
|
'radio_stream_url' => 'https://stream.radioking.com/radio/83232/radio.mp3',
|
|
'radio_style' => 'dark',
|
|
'radio_auto_play' => '0',
|
|
'points_enabled' => '1',
|
|
'points_per_minute' => '2',
|
|
'max_points_per_day' => '100',
|
|
'points_for_request' => '5',
|
|
'points_for_vote' => '2',
|
|
'points_for_giveaway_win' => '50',
|
|
'points_for_contest_win' => '100',
|
|
'radio_shouts_enabled' => '1',
|
|
'radio_now_playing_enabled' => '1',
|
|
'radio_listeners_enabled' => '1',
|
|
'radio_show_current_dj' => '1',
|
|
'radio_widget_enabled' => '1',
|
|
'radio_widget_show_globally' => '1',
|
|
'radio_widget_position' => 'bottom-right',
|
|
'radio_applications_enabled' => '1',
|
|
'radio_auto_dj_detection' => '1',
|
|
'radio_monitoring_enabled' => '1',
|
|
'radio_monitoring_timeout' => '5',
|
|
'radio_stream_fallback_url' => '',
|
|
'radio_stream_backup_enabled' => '0',
|
|
'radio_show_song_history' => '1',
|
|
'radio_show_schedule_preview' => '1',
|
|
'radio_max_history_items' => '10',
|
|
'radio_social_links_enabled' => '1',
|
|
'radio_facebook_url' => '',
|
|
'radio_twitter_url' => '',
|
|
'radio_discord_url' => '',
|
|
'radio_instagram_url' => '',
|
|
'radio_youtube_url' => '',
|
|
'radio_twitch_url' => '',
|
|
'radio_word_filter_enabled' => '1',
|
|
'radio_max_shout_length' => '280',
|
|
'radio_shout_cooldown' => '30',
|
|
'radio_contests_enabled' => '1',
|
|
'radio_giveaways_enabled' => '1',
|
|
'radio_auto_contest_creation' => '0',
|
|
];
|
|
|
|
// Update all settings
|
|
foreach ($settings as $key => $value) {
|
|
WebsiteSetting::updateOrCreate(
|
|
['key' => $key],
|
|
['value' => $value, 'comment' => 'Auto-configured by All-in-One Setup'],
|
|
);
|
|
}
|
|
|
|
// Clear cache
|
|
$this->clearCache();
|
|
|
|
// Reload form data
|
|
$this->fillForm();
|
|
|
|
Notification::make()
|
|
->success()
|
|
->title(__('radio.setup.success_title'))
|
|
->body(__('radio.setup.success_body'))
|
|
->send();
|
|
|
|
} catch (\Exception $e) {
|
|
Notification::make()
|
|
->danger()
|
|
->title(__('radio.setup.error_title'))
|
|
->body(__('radio.setup.error_body', ['message' => $e->getMessage()]))
|
|
->send();
|
|
}
|
|
}
|
|
}
|