feat: add plugin model

initial implementation of playlist

feat: added support for playlists
This commit is contained in:
Benjamin Nussbaum 2025-03-11 22:34:28 +01:00
parent 276511fc98
commit 4195269414
17 changed files with 669 additions and 15 deletions

View file

@ -4,6 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Device extends Model
{
@ -50,4 +51,29 @@ class Device extends Model
return 3; // Strong signal (3 bars)
}
}
public function playlists(): HasMany
{
return $this->hasMany(Playlist::class);
}
public function getNextPlaylistItem(): ?PlaylistItem
{
// Get all active playlists
$playlists = $this->playlists()
->where('is_active', true)
->get();
// Find the first active playlist with an available item
foreach ($playlists as $playlist) {
if ($playlist->isActiveNow()) {
$nextItem = $playlist->getNextPlaylistItem();
if ($nextItem) {
return $nextItem;
}
}
}
return null;
}
}

94
app/Models/Playlist.php Normal file
View file

@ -0,0 +1,94 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Playlist extends Model
{
use HasFactory;
protected $guarded = ['id'];
protected $casts = [
'is_active' => 'boolean',
'weekdays' => 'array',
'active_from' => 'datetime:H:i',
'active_until' => 'datetime:H:i',
];
public function device(): BelongsTo
{
return $this->belongsTo(Device::class);
}
public function items(): HasMany
{
return $this->hasMany(PlaylistItem::class);
}
public function isActiveNow(): bool
{
if (! $this->is_active) {
return false;
}
// Check weekday
if ($this->weekdays !== null) {
if (! in_array(now()->dayOfWeek, $this->weekdays)) {
return false;
}
}
// Check time range
if ($this->active_from !== null && $this->active_until !== null) {
if (! now()->between($this->active_from, $this->active_until)) {
return false;
}
}
return true;
}
public function getNextPlaylistItem(): ?PlaylistItem
{
if (! $this->isActiveNow()) {
return null;
}
// Get active playlist items ordered by display order
$playlistItems = $this->items()
->where('is_active', true)
->orderBy('order')
->get();
if ($playlistItems->isEmpty()) {
return null;
}
// Get the last displayed item
$lastDisplayed = $playlistItems
->sortByDesc('last_displayed_at')
->first();
if (! $lastDisplayed || ! $lastDisplayed->last_displayed_at) {
// If no item has been displayed yet, return the first one
return $playlistItems->first();
}
// Find the next item in sequence
$currentOrder = $lastDisplayed->order;
$nextItem = $playlistItems
->where('order', '>', $currentOrder)
->first();
// If there's no next item, loop back to the first one
if (! $nextItem) {
return $playlistItems->first();
}
return $nextItem;
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class PlaylistItem extends Model
{
use HasFactory;
protected $guarded = ['id'];
protected $casts = [
'is_active' => 'boolean',
'last_displayed_at' => 'datetime',
];
public function playlist(): BelongsTo
{
return $this->belongsTo(Playlist::class);
}
public function plugin(): BelongsTo
{
return $this->belongsTo(Plugin::class);
}
}

29
app/Models/Plugin.php Normal file
View file

@ -0,0 +1,29 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
class Plugin extends Model
{
use HasFactory;
protected $guarded = ['id'];
protected $casts = [
'data_payload' => 'json',
];
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
if (empty($model->uuid)) {
$model->uuid = Str::uuid();
}
});
}
}