From 712dc487c650511efb6eb69996e77c6d50c75744 Mon Sep 17 00:00:00 2001 From: isaacclad Date: Wed, 1 Jul 2026 22:54:15 +0000 Subject: [PATCH] Fix green room Go live and Panels hidden for conference hosts. Stop registerPresenter from demoting hosts to panelists, recognize room owners as managers, and show stage controls in the green room banner. Co-authored-by: Cursor --- .../Meet/MeetingFeaturesController.php | 11 +++++- .../Meet/MeetingRoomController.php | 4 ++ app/Services/Meet/SessionService.php | 6 +++ app/Services/Meet/TownHallService.php | 1 + resources/views/meet/room/show.blade.php | 14 +++---- tests/Feature/MeetWebTest.php | 38 +++++++++++++++++++ 6 files changed, 66 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/Meet/MeetingFeaturesController.php b/app/Http/Controllers/Meet/MeetingFeaturesController.php index 1f64c0e..b0291a0 100644 --- a/app/Http/Controllers/Meet/MeetingFeaturesController.php +++ b/app/Http/Controllers/Meet/MeetingFeaturesController.php @@ -356,7 +356,16 @@ class MeetingFeaturesController extends Controller protected function hostOnly(Request $request, Session $session): Participant { $participant = $this->participant($request, $session); - abort_unless($participant->isHost(), 403); + $user = $request->user(); + $isRoomHost = $user && $user->ownerRef() === $session->room->host_user_ref; + + abort_unless($participant->isHost() || $isRoomHost, 403); + + if ($isRoomHost && ! $participant->isHost()) { + $participant->update(['role' => 'host']); + + return $participant->fresh(); + } return $participant; } diff --git a/app/Http/Controllers/Meet/MeetingRoomController.php b/app/Http/Controllers/Meet/MeetingRoomController.php index af11c57..53b7cdf 100644 --- a/app/Http/Controllers/Meet/MeetingRoomController.php +++ b/app/Http/Controllers/Meet/MeetingRoomController.php @@ -66,6 +66,9 @@ class MeetingRoomController extends Controller $spaces = app(SpaceService::class); $isAudioOnly = $room->isAudioOnly(); $stageLayout = app(StageLayoutService::class); + $authUser = $request->user(); + $isRoomHost = $authUser && $authUser->ownerRef() === $room->host_user_ref; + $canManageConference = $participant->isHost() || $isRoomHost; return view('meet.room.show', [ 'session' => $session, @@ -90,6 +93,7 @@ class MeetingRoomController extends Controller 'isAttendee' => $participant->isAttendee() || $spaces->isListener($room, $participant), 'usesStageLayout' => $stageLayout->usesStageLayout($room), 'stageConfig' => $stageLayout->config($room), + 'canManageConference' => $canManageConference, ]); } diff --git a/app/Services/Meet/SessionService.php b/app/Services/Meet/SessionService.php index 1aa9867..99d9193 100644 --- a/app/Services/Meet/SessionService.php +++ b/app/Services/Meet/SessionService.php @@ -108,6 +108,12 @@ class SessionService $updates['joined_at'] = $existing->joined_at ?? now(); } + if (in_array($role, ['host', 'co_host'], true)) { + $updates['role'] = $role; + } elseif ($existing->role === 'guest' && $role !== 'guest') { + $updates['role'] = $role; + } + $existing->update($updates); return $existing; diff --git a/app/Services/Meet/TownHallService.php b/app/Services/Meet/TownHallService.php index 3e330af..4f88f39 100644 --- a/app/Services/Meet/TownHallService.php +++ b/app/Services/Meet/TownHallService.php @@ -103,6 +103,7 @@ class TownHallService $session->participants() ->where('user_ref', $userRef) ->where('status', 'joined') + ->whereNotIn('role', ['host', 'co_host']) ->update(['role' => 'panelist']); return $session->fresh(); diff --git a/resources/views/meet/room/show.blade.php b/resources/views/meet/room/show.blade.php index eeb4bb9..b235934 100644 --- a/resources/views/meet/room/show.blade.php +++ b/resources/views/meet/room/show.blade.php @@ -34,7 +34,7 @@ data-configured="{{ $mediaConfigured ? '1' : '0' }}" data-participant="{{ $participant->uuid }}" data-display-name="{{ $participant->display_name }}" - data-is-host="{{ $participant->isHost() ? '1' : '0' }}" + data-is-host="{{ ($canManageConference ?? $participant->isHost()) ? '1' : '0' }}" data-poll-url="{{ route('meet.room.poll', $session) }}" data-ended-url="{{ route('meet.ended', $session) }}" data-chat-url="{{ route('meet.room.chat', $session) }}" @@ -59,9 +59,9 @@ data-is-conference="{{ ($isConference ?? false) ? '1' : '0' }}" data-is-green-room="{{ ($isGreenRoom ?? false) ? '1' : '0' }}" data-session-mode="{{ $session->session_mode }}" - data-go-live-url="{{ ($isConference ?? false) && ($isGreenRoom ?? false) && $participant->isHost() ? route('meet.room.townhall.live', $session) : '' }}" - data-add-presenter-url="{{ ($isConference ?? false) && $participant->isHost() ? route('meet.room.townhall.presenters', $session) : '' }}" - data-stage-update-url="{{ ($usesStageLayout ?? false) && $participant->isHost() ? route('meet.room.stage.update', $session) : '' }}" + data-go-live-url="{{ ($isConference ?? false) && ($isGreenRoom ?? false) && ($canManageConference ?? $participant->isHost()) ? route('meet.room.townhall.live', $session) : '' }}" + data-add-presenter-url="{{ ($isConference ?? false) && ($canManageConference ?? $participant->isHost()) ? route('meet.room.townhall.presenters', $session) : '' }}" + data-stage-update-url="{{ ($usesStageLayout ?? false) && ($canManageConference ?? $participant->isHost()) ? route('meet.room.stage.update', $session) : '' }}" data-uses-stage-layout="{{ ($usesStageLayout ?? false) ? '1' : '0' }}" data-panel-discussions="{{ ($stageConfig['panel_discussions'] ?? false) ? '1' : '0' }}" data-stage-layout="{{ $stageConfig['stage_layout'] ?? 'plenary' }}" @@ -143,13 +143,13 @@
+ class="flex shrink-0 flex-col gap-2 border-b border-violet-500/30 bg-violet-500/15 px-4 py-2.5 sm:flex-row sm:items-center sm:justify-between sm:gap-3">

Green room

Only hosts and speakers are visible. Attendees join after you go live.

-
-