Deploy Ladill Meet / deploy (push) Successful in 1m29s
Split town_hall into a Conferences sidebar flow and Spaces-style Rooms with host/speaker/listener roles; enforce audio-only LiveKit UI for rooms; show schedule icon on mobile meetings index. Co-authored-by: Cursor <cursoragent@cursor.com>
177 lines
4.4 KiB
PHP
177 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Models\Concerns\BelongsToOwner;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
use Illuminate\Support\Str;
|
|
|
|
class Room extends Model
|
|
{
|
|
use BelongsToOwner, SoftDeletes;
|
|
|
|
protected $table = 'meet_rooms';
|
|
|
|
protected $fillable = [
|
|
'uuid', 'owner_ref', 'organization_id', 'branch_id', 'host_user_ref',
|
|
'title', 'description', 'type', 'status', 'slug', 'scheduled_at',
|
|
'duration_minutes', 'timezone', 'passcode', 'settings', 'source', 'calendar_event_id',
|
|
'template_id', 'recurring_series_id', 'recurrence_rule', 'recurrence_interval', 'recurrence_until',
|
|
];
|
|
|
|
protected function casts(): array
|
|
{
|
|
return [
|
|
'scheduled_at' => 'datetime',
|
|
'recurrence_until' => 'date',
|
|
'settings' => 'array',
|
|
'source' => 'array',
|
|
];
|
|
}
|
|
|
|
protected static function booted(): void
|
|
{
|
|
static::creating(function (Room $room) {
|
|
if (empty($room->uuid)) {
|
|
$room->uuid = (string) Str::uuid();
|
|
}
|
|
});
|
|
}
|
|
|
|
public function getRouteKeyName(): string
|
|
{
|
|
return 'uuid';
|
|
}
|
|
|
|
public function organization(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Organization::class, 'organization_id');
|
|
}
|
|
|
|
public function branch(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Branch::class, 'branch_id');
|
|
}
|
|
|
|
public function sessions(): HasMany
|
|
{
|
|
return $this->hasMany(Session::class, 'room_id');
|
|
}
|
|
|
|
public function invitations(): HasMany
|
|
{
|
|
return $this->hasMany(Invitation::class, 'room_id');
|
|
}
|
|
|
|
public function webinarRegistrations(): HasMany
|
|
{
|
|
return $this->hasMany(WebinarRegistration::class, 'room_id');
|
|
}
|
|
|
|
public function sessionFiles(): HasMany
|
|
{
|
|
return $this->hasMany(SessionFile::class, 'room_id');
|
|
}
|
|
|
|
public function isWebinar(): bool
|
|
{
|
|
return $this->type === 'webinar';
|
|
}
|
|
|
|
public function isConference(): bool
|
|
{
|
|
return $this->type === 'town_hall';
|
|
}
|
|
|
|
public function isSpace(): bool
|
|
{
|
|
return $this->type === 'space';
|
|
}
|
|
|
|
public function isAudioOnly(): bool
|
|
{
|
|
return $this->isSpace() || (bool) $this->setting('audio_only', false);
|
|
}
|
|
|
|
public function canRestart(): bool
|
|
{
|
|
if ($this->status === 'cancelled' || $this->activeSession()) {
|
|
return false;
|
|
}
|
|
|
|
return $this->status === 'ended'
|
|
|| $this->type === 'personal'
|
|
|| $this->status === 'scheduled';
|
|
}
|
|
|
|
public function restartLabel(): string
|
|
{
|
|
$restarting = $this->status === 'ended' || $this->sessions()->exists();
|
|
|
|
if ($this->isWebinar()) {
|
|
return $restarting ? 'Restart webinar' : 'Start webinar';
|
|
}
|
|
|
|
if ($this->isConference()) {
|
|
return $restarting ? 'Restart conference' : 'Start conference';
|
|
}
|
|
|
|
if ($this->isSpace()) {
|
|
return $restarting ? 'Reopen room' : 'Open room';
|
|
}
|
|
|
|
return $restarting ? 'Restart meeting' : 'Start meeting';
|
|
}
|
|
|
|
public function isTownHall(): bool
|
|
{
|
|
return $this->type === 'town_hall';
|
|
}
|
|
|
|
public function template(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Template::class, 'template_id');
|
|
}
|
|
|
|
public function isRecurring(): bool
|
|
{
|
|
return filled($this->recurrence_rule);
|
|
}
|
|
|
|
public function activeSession(): ?Session
|
|
{
|
|
return $this->sessions()->where('status', 'live')->latest()->first();
|
|
}
|
|
|
|
public function setting(string $key, mixed $default = null): mixed
|
|
{
|
|
return data_get($this->settings, $key, data_get(config('meet.default_settings'), $key, $default));
|
|
}
|
|
|
|
public function isLive(): bool
|
|
{
|
|
return $this->status === 'live';
|
|
}
|
|
|
|
public function requiresWaitingRoom(?User $user, string $role): bool
|
|
{
|
|
if (! $this->setting('waiting_room', true)) {
|
|
return false;
|
|
}
|
|
|
|
if ($role === 'host' || ($user && $user->ownerRef() === $this->host_user_ref)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function joinUrl(): string
|
|
{
|
|
return rtrim((string) config('app.meet_url', 'https://meet.ladill.com'), '/').'/r/'.$this->uuid;
|
|
}
|
|
}
|