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,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('radio_api_keys', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('key', 64)->unique();
|
||||
$table->string('allowed_ips')->nullable();
|
||||
$table->json('permissions')->nullable();
|
||||
$table->integer('rate_limit')->default(300);
|
||||
$table->timestamp('last_used_at')->nullable();
|
||||
$table->timestamp('expires_at')->nullable();
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('radio_api_keys');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('radio_song_plays', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title');
|
||||
$table->string('artist')->nullable();
|
||||
$table->string('album')->nullable();
|
||||
$table->string('artwork_url')->nullable();
|
||||
$table->unsignedInteger('duration')->nullable();
|
||||
$table->timestamp('played_at');
|
||||
$table->unsignedBigInteger('dj_id')->nullable()->index();
|
||||
$table->json('metadata')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('played_at');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('radio_song_plays');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('radio_shouts', function (Blueprint $table) {
|
||||
$table->boolean('approved')->default(true)->after('reported_by');
|
||||
$table->unsignedBigInteger('approved_by')->nullable()->after('approved');
|
||||
$table->timestamp('approved_at')->nullable()->after('approved_by');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('radio_shouts', function (Blueprint $table) {
|
||||
$table->dropColumn(['approved', 'approved_by', 'approved_at']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('radio_auto_dj_playlist', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title');
|
||||
$table->string('artist')->nullable();
|
||||
$table->string('album')->nullable();
|
||||
$table->string('artwork_url')->nullable();
|
||||
$table->unsignedInteger('duration')->nullable();
|
||||
$table->unsignedInteger('play_count')->default(0);
|
||||
$table->timestamp('last_played_at')->nullable();
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->unsignedInteger('sort_order')->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('radio_auto_dj_playlist');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user