Files
ladill-meet/app/Services/Meet/TownHallService.php
T
isaaccladandCursor 8162827957
Deploy Ladill Meet / deploy (push) Successful in 2m1s
Auto-join host into live session when going live from green room.
Green room poll was racing go-live and sending the host to the ended page; carry participant session into the new live session instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-02 06:57:33 +00:00

126 lines
3.9 KiB
PHP

<?php
namespace App\Services\Meet;
use App\Models\Participant;
use App\Models\Room;
use App\Models\Session;
use App\Models\User;
class TownHallService
{
public function startGreenRoom(Room $room, User $host): Session
{
abort_unless($room->type === 'town_hall', 422);
$session = Session::create([
'owner_ref' => $room->owner_ref,
'room_id' => $room->id,
'media_room_name' => app(RoomService::class)->mediaRoomName($room, 'green'),
'status' => 'live',
'session_mode' => 'green_room',
'presenter_refs' => [$host->ownerRef()],
'started_at' => now(),
]);
$room->update(['status' => 'live']);
app(\App\Services\Meet\Media\MediaProviderInterface::class)->createRoom($session->media_room_name);
app(SessionService::class)->joinParticipant($session, $host, 'host');
return $session;
}
public function goLive(Session $greenRoomSession, User $host): Session
{
abort_unless($greenRoomSession->session_mode === 'green_room', 422);
$room = $greenRoomSession->room;
$presenters = $greenRoomSession->presenter_refs ?? [];
$greenRoomSession->update(['status' => 'ended', 'ended_at' => now()]);
$liveSession = Session::create([
'owner_ref' => $room->owner_ref,
'room_id' => $room->id,
'media_room_name' => app(RoomService::class)->mediaRoomName($room),
'status' => 'live',
'session_mode' => 'live',
'presenter_refs' => $presenters,
'started_at' => now(),
]);
$room->update(['status' => 'live']);
app(\App\Services\Meet\Media\MediaProviderInterface::class)->createRoom($liveSession->media_room_name);
app(SessionService::class)->joinParticipant($liveSession, $host, 'host');
foreach ($greenRoomSession->participants()->where('status', 'joined')->get() as $participant) {
if ($participant->user_ref && ! in_array($participant->user_ref, $presenters, true)) {
continue;
}
}
return $liveSession;
}
public function successorLiveSession(Session $greenRoomSession): ?Session
{
if ($greenRoomSession->session_mode !== 'green_room' || $greenRoomSession->isLive()) {
return null;
}
return $greenRoomSession->room->sessions()
->where('status', 'live')
->where('session_mode', 'live')
->where('id', '!=', $greenRoomSession->id)
->latest('started_at')
->first();
}
public function handoffCoHost(Session $session, Participant $from, string $toUserRef): Participant
{
abort_unless(in_array($from->role, ['host', 'co_host'], true), 403);
$target = $session->participants()
->where('user_ref', $toUserRef)
->where('status', 'joined')
->firstOrFail();
$from->update(['role' => 'participant']);
$target->update(['role' => 'co_host']);
$presenters = collect($session->presenter_refs ?? [])
->reject(fn ($ref) => $ref === $from->user_ref)
->push($toUserRef)
->unique()
->values()
->all();
$session->update(['presenter_refs' => $presenters]);
return $target->fresh();
}
public function addPresenter(Session $session, string $userRef): Session
{
$presenters = collect($session->presenter_refs ?? [])
->push($userRef)
->unique()
->values()
->all();
$session->update(['presenter_refs' => $presenters]);
$session->participants()
->where('user_ref', $userRef)
->where('status', 'joined')
->whereNotIn('role', ['host', 'co_host'])
->update(['role' => 'panelist']);
return $session->fresh();
}
}