Implement conference breakouts with meeting mode and programme lineup UI.
Deploy Ladill Meet / deploy (push) Successful in 1m3s
Deploy Ladill Meet / deploy (push) Successful in 1m3s
Attendees reconnect to breakout rooms with publish access while hosts stay on stage; poll and media-token endpoints drive LiveKit reconnection, and the live room shows Events-linked programme when available. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -7,6 +7,7 @@ use App\Models\Participant;
|
||||
use App\Models\Recording;
|
||||
use App\Models\Room;
|
||||
use App\Models\Session;
|
||||
use App\Services\Meet\BreakoutService;
|
||||
use App\Services\Meet\ChatService;
|
||||
use App\Services\Meet\Media\MediaProviderInterface;
|
||||
use App\Services\Meet\ParticipantPresenter;
|
||||
@@ -69,6 +70,8 @@ class MeetingRoomController extends Controller
|
||||
$authUser = $request->user();
|
||||
$isRoomHost = $authUser && $authUser->ownerRef() === $room->host_user_ref;
|
||||
$canManageConference = $participant->isHost() || $isRoomHost;
|
||||
$breakoutService = app(BreakoutService::class);
|
||||
$inBreakout = $breakoutService->isInActiveBreakout($participant);
|
||||
|
||||
return view('meet.room.show', [
|
||||
'session' => $session,
|
||||
@@ -87,13 +90,14 @@ class MeetingRoomController extends Controller
|
||||
'presenterRefs' => (array) $session->presenter_refs,
|
||||
'isAudioOnly' => $isAudioOnly,
|
||||
'isSpace' => $room->isSpace(),
|
||||
'canPublish' => $room->isSpace()
|
||||
? $spaces->canPublish($room, $participant)
|
||||
: $webinars->canPublish($room, $participant),
|
||||
'canPublish' => $this->sessions->canParticipantPublish($participant),
|
||||
'isAttendee' => $participant->isAttendee() || $spaces->isListener($room, $participant),
|
||||
'usesStageLayout' => $stageLayout->usesStageLayout($room),
|
||||
'usesStageLayout' => $stageLayout->usesStageLayout($room) && ! $inBreakout,
|
||||
'inBreakout' => $inBreakout,
|
||||
'stageConfig' => $stageLayout->config($room),
|
||||
'canManageConference' => $canManageConference,
|
||||
'programmeSnapshot' => $room->setting('programme_snapshot'),
|
||||
'linkedProgrammeItems' => (array) $room->setting('linked_programme_items', []),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -229,7 +233,11 @@ class MeetingRoomController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
$this->currentParticipant($request, $session);
|
||||
$participant = $this->currentParticipant($request, $session);
|
||||
|
||||
app(BreakoutService::class)->closeExpired($session);
|
||||
|
||||
$participant->refresh();
|
||||
|
||||
$session->load(['participants' => fn ($q) => $q->whereIn('status', ['joined', 'waiting'])]);
|
||||
|
||||
@@ -295,9 +303,24 @@ class MeetingRoomController extends Controller
|
||||
'original_name' => $f->original_name,
|
||||
'file_size' => $f->file_size,
|
||||
]),
|
||||
'media' => $this->sessions->mediaSessionState($participant),
|
||||
'breakouts_active' => app(BreakoutService::class)->hasActiveBreakouts($session),
|
||||
], app(StageLayoutService::class)->config($session->room)));
|
||||
}
|
||||
|
||||
public function mediaToken(Request $request, Session $session): JsonResponse
|
||||
{
|
||||
abort_unless($session->isLive(), 404);
|
||||
|
||||
$participant = $this->currentParticipant($request, $session);
|
||||
|
||||
return response()->json(array_merge(
|
||||
['token' => $this->sessions->generateMediaToken($participant)],
|
||||
$this->sessions->mediaSessionState($participant->fresh()),
|
||||
['breakouts_active' => app(BreakoutService::class)->hasActiveBreakouts($session)],
|
||||
));
|
||||
}
|
||||
|
||||
public function startRecording(Request $request, Session $session): JsonResponse
|
||||
{
|
||||
$participant = $this->currentParticipant($request, $session);
|
||||
|
||||
Reference in New Issue
Block a user