Add conference stage layouts for plenary and panel discussions.
Deploy Ladill Meet / deploy (push) Successful in 37s
Deploy Ladill Meet / deploy (push) Successful in 37s
Speakers get a full-screen spotlight with overlapping audience avatars; hosts can configure panels in the green room and switch layouts live. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -98,6 +98,7 @@ class ConferenceController extends Controller
|
||||
'live_captions' => ['sometimes', 'boolean'],
|
||||
'green_room' => ['sometimes', 'boolean'],
|
||||
'practice_mode' => ['sometimes', 'boolean'],
|
||||
'panel_discussions' => ['sometimes', 'boolean'],
|
||||
]);
|
||||
|
||||
$presenterRefs = collect($validated['presenter_refs'] ?? [])
|
||||
@@ -114,6 +115,9 @@ class ConferenceController extends Controller
|
||||
'live_captions' => $request->boolean('live_captions'),
|
||||
'green_room' => $request->boolean('green_room', true),
|
||||
'practice_mode' => $request->boolean('practice_mode'),
|
||||
'panel_discussions' => $request->boolean('panel_discussions'),
|
||||
'stage_layout' => 'plenary',
|
||||
'panels' => [],
|
||||
'stage_mode' => true,
|
||||
'presenter_refs' => $presenterRefs,
|
||||
];
|
||||
@@ -201,6 +205,7 @@ class ConferenceController extends Controller
|
||||
'presenter_refs' => ['nullable', 'array'],
|
||||
'presenter_refs.*' => ['string', 'max:64'],
|
||||
'invite_emails' => ['nullable', 'string', 'max:2000'],
|
||||
'panel_discussions' => ['sometimes', 'boolean'],
|
||||
]);
|
||||
|
||||
$allowedRefs = Member::owned($this->ownerRef($request))
|
||||
@@ -217,6 +222,13 @@ class ConferenceController extends Controller
|
||||
|
||||
$this->conferences->syncPresenterRefs($room, $presenterRefs);
|
||||
|
||||
if ($request->has('panel_discussions')) {
|
||||
$settings = array_merge($room->settings ?? [], [
|
||||
'panel_discussions' => $request->boolean('panel_discussions'),
|
||||
]);
|
||||
$room->update(['settings' => $settings]);
|
||||
}
|
||||
|
||||
$inviteCount = 0;
|
||||
if ($emails = trim((string) ($validated['invite_emails'] ?? ''))) {
|
||||
$invites = collect(preg_split('/[\s,;]+/', $emails))
|
||||
|
||||
@@ -15,6 +15,7 @@ use App\Services\Meet\FileSharingService;
|
||||
use App\Services\Meet\LiveStreamService;
|
||||
use App\Services\Meet\PollService;
|
||||
use App\Services\Meet\QaService;
|
||||
use App\Services\Meet\StageLayoutService;
|
||||
use App\Services\Meet\TownHallService;
|
||||
use App\Services\Meet\WhiteboardService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -32,6 +33,7 @@ class MeetingFeaturesController extends Controller
|
||||
protected WhiteboardService $whiteboards,
|
||||
protected LiveStreamService $liveStreams,
|
||||
protected TownHallService $townHall,
|
||||
protected StageLayoutService $stageLayout,
|
||||
) {}
|
||||
|
||||
// --- Q&A ---
|
||||
@@ -320,6 +322,29 @@ class MeetingFeaturesController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateStage(Request $request, Session $session): JsonResponse
|
||||
{
|
||||
$this->hostOnly($request, $session);
|
||||
$room = $session->room;
|
||||
abort_unless($this->stageLayout->usesStageLayout($room), 422);
|
||||
|
||||
$validated = $request->validate([
|
||||
'panel_discussions' => ['sometimes', 'boolean'],
|
||||
'stage_layout' => ['sometimes', 'string', 'in:plenary,panel'],
|
||||
'active_panel_id' => ['nullable', 'string', 'max:64'],
|
||||
'spotlight_speaker_ref' => ['nullable', 'string', 'max:64'],
|
||||
'panels' => ['sometimes', 'array', 'max:12'],
|
||||
'panels.*.id' => ['nullable', 'string', 'max:64'],
|
||||
'panels.*.name' => ['required_with:panels', 'string', 'max:100'],
|
||||
'panels.*.speaker_refs' => ['nullable', 'array'],
|
||||
'panels.*.speaker_refs.*' => ['string', 'max:64'],
|
||||
]);
|
||||
|
||||
$room = $this->stageLayout->update($room, $validated);
|
||||
|
||||
return response()->json($this->stageLayout->config($room));
|
||||
}
|
||||
|
||||
protected function participant(Request $request, Session $session): Participant
|
||||
{
|
||||
$uuid = $request->session()->get("meet.participant.{$session->uuid}");
|
||||
|
||||
@@ -14,6 +14,7 @@ use App\Services\Meet\RecordingService;
|
||||
use App\Services\Meet\SecurityPolicyService;
|
||||
use App\Services\Meet\SessionService;
|
||||
use App\Services\Meet\SpaceService;
|
||||
use App\Services\Meet\StageLayoutService;
|
||||
use App\Services\Meet\TranscriptService;
|
||||
use App\Services\Meet\WebinarService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -64,6 +65,7 @@ class MeetingRoomController extends Controller
|
||||
$webinars = app(WebinarService::class);
|
||||
$spaces = app(SpaceService::class);
|
||||
$isAudioOnly = $room->isAudioOnly();
|
||||
$stageLayout = app(StageLayoutService::class);
|
||||
|
||||
return view('meet.room.show', [
|
||||
'session' => $session,
|
||||
@@ -86,6 +88,8 @@ class MeetingRoomController extends Controller
|
||||
? $spaces->canPublish($room, $participant)
|
||||
: $webinars->canPublish($room, $participant),
|
||||
'isAttendee' => $participant->isAttendee() || $spaces->isListener($room, $participant),
|
||||
'usesStageLayout' => $stageLayout->usesStageLayout($room),
|
||||
'stageConfig' => $stageLayout->config($room),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -241,7 +245,7 @@ class MeetingRoomController extends Controller
|
||||
->limit(20)
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
return response()->json(array_merge([
|
||||
'participants' => $session->participants->map(
|
||||
fn ($p) => ParticipantPresenter::toArray($p, $avatars, $session->room->host_user_ref)
|
||||
),
|
||||
@@ -287,7 +291,7 @@ class MeetingRoomController extends Controller
|
||||
'original_name' => $f->original_name,
|
||||
'file_size' => $f->file_size,
|
||||
]),
|
||||
]);
|
||||
], app(StageLayoutService::class)->config($session->room)));
|
||||
}
|
||||
|
||||
public function startRecording(Request $request, Session $session): JsonResponse
|
||||
|
||||
Reference in New Issue
Block a user