Deploy Ladill Meet / deploy (push) Failing after 7s
Phases 0–18: core meetings, webinar, breakouts, team chat, live streaming, town hall, billing, and Ladill Mail calendar wiring. Co-authored-by: Cursor <cursoragent@cursor.com>
107 lines
3.7 KiB
PHP
107 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Meet;
|
|
|
|
use App\Models\BreakoutAssignment;
|
|
use App\Models\BreakoutRoom;
|
|
use App\Models\Message;
|
|
use App\Models\Participant;
|
|
use App\Models\Session;
|
|
use App\Services\Meet\Media\MediaProviderInterface;
|
|
use Illuminate\Support\Str;
|
|
|
|
class BreakoutService
|
|
{
|
|
public function __construct(
|
|
protected MediaProviderInterface $media,
|
|
) {}
|
|
|
|
/**
|
|
* @param array<int, array{participant_id: int, breakout_room_id?: int}>|null $assignments
|
|
* @return \Illuminate\Support\Collection<int, BreakoutRoom>
|
|
*/
|
|
public function createRooms(Session $session, int $count, ?int $timerMinutes = null, ?array $assignments = null)
|
|
{
|
|
$timerMinutes ??= config('meet.breakouts.default_timer_minutes', 15);
|
|
$closesAt = now()->addMinutes($timerMinutes);
|
|
$rooms = collect();
|
|
|
|
for ($i = 1; $i <= $count; $i++) {
|
|
$mediaName = $session->media_room_name.'-breakout-'.Str::random(8);
|
|
$this->media->createRoom($mediaName);
|
|
|
|
$rooms->push(BreakoutRoom::create([
|
|
'owner_ref' => $session->owner_ref,
|
|
'session_id' => $session->id,
|
|
'name' => 'Breakout '.$i,
|
|
'media_room_name' => $mediaName,
|
|
'status' => 'open',
|
|
'closes_at' => $closesAt,
|
|
]));
|
|
}
|
|
|
|
$participants = $session->participants()->where('status', 'joined')->get();
|
|
|
|
if ($assignments) {
|
|
foreach ($assignments as $assignment) {
|
|
$this->assignParticipant(
|
|
$rooms->firstWhere('id', $assignment['breakout_room_id']) ?? $rooms->first(),
|
|
Participant::findOrFail($assignment['participant_id']),
|
|
);
|
|
}
|
|
} else {
|
|
$participants->values()->each(function (Participant $participant, int $index) use ($rooms) {
|
|
$this->assignParticipant($rooms[$index % $rooms->count()], $participant);
|
|
});
|
|
}
|
|
|
|
return $rooms;
|
|
}
|
|
|
|
public function assignParticipant(BreakoutRoom $breakout, Participant $participant): void
|
|
{
|
|
BreakoutAssignment::updateOrCreate(
|
|
['breakout_room_id' => $breakout->id, 'participant_id' => $participant->id],
|
|
);
|
|
$participant->update(['breakout_room_id' => $breakout->id]);
|
|
}
|
|
|
|
public function moveParticipant(Participant $participant, BreakoutRoom $breakout): void
|
|
{
|
|
$this->assignParticipant($breakout, $participant);
|
|
}
|
|
|
|
public function returnToMain(Participant $participant): void
|
|
{
|
|
$participant->update(['breakout_room_id' => null]);
|
|
BreakoutAssignment::where('participant_id', $participant->id)->delete();
|
|
}
|
|
|
|
public function broadcast(Session $session, string $message, string $senderName): Message
|
|
{
|
|
return Message::create([
|
|
'owner_ref' => $session->owner_ref,
|
|
'session_id' => $session->id,
|
|
'sender_name' => $senderName,
|
|
'type' => 'breakout_broadcast',
|
|
'body' => $message,
|
|
]);
|
|
}
|
|
|
|
public function closeAll(Session $session): void
|
|
{
|
|
$session->breakoutRooms()->update(['status' => 'closed']);
|
|
$session->participants()->whereNotNull('breakout_room_id')->update(['breakout_room_id' => null]);
|
|
BreakoutAssignment::whereIn('breakout_room_id', $session->breakoutRooms()->pluck('id'))->delete();
|
|
}
|
|
|
|
public function mediaRoomForParticipant(Participant $participant): string
|
|
{
|
|
if ($participant->breakout_room_id) {
|
|
return $participant->breakoutRoom?->media_room_name ?? $participant->session->media_room_name;
|
|
}
|
|
|
|
return $participant->session->media_room_name;
|
|
}
|
|
}
|