Stop Chat and More from flashing on load in audio rooms.
Deploy Ladill Meet / deploy (push) Successful in 57s

Bootstrap room-type flags from meet-config before Alpine paints, gate toolbar and banners server-side per room type, and hide Alpine toolbar items until init completes.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-04 01:00:28 +00:00
co-authored by Cursor
parent 1d1a4cd877
commit 4dd7883763
3 changed files with 137 additions and 45 deletions
+112 -37
View File
@@ -1,17 +1,92 @@
import Alpine from 'alpinejs';
import { ConnectionState, Room, RoomEvent, Track } from 'livekit-client';
function readMeetBootState() {
function readMeetRoomBootState() {
const el = document.getElementById('meet-config');
if (!el) {
return {};
}
let presenterRefs = [];
let panels = [];
let sessionParticipants = [];
let roomHost = null;
try {
presenterRefs = JSON.parse(el.dataset.presenterRefs || '[]');
} catch {
presenterRefs = [];
}
try {
panels = JSON.parse(el.dataset.panels || '[]');
} catch {
panels = [];
}
try {
sessionParticipants = JSON.parse(el.dataset.initialParticipants || '[]');
} catch {
sessionParticipants = [];
}
try {
roomHost = JSON.parse(el.dataset.roomHost || 'null');
} catch {
roomHost = null;
}
const audioOnly = el.dataset.audioOnly === '1';
let stageLayout = el.dataset.stageLayout || 'plenary';
const panelDiscussions = el.dataset.panelDiscussions === '1';
if (!panelDiscussions && stageLayout === 'panel') {
stageLayout = 'plenary';
}
const participantUuid = el.dataset.participant || '';
const selfParticipant = sessionParticipants.find((person) => person.uuid === participantUuid);
return {
isRecording: el?.dataset.recordingActive === '1',
isLocked: el?.dataset.locked === '1',
isHost: el.dataset.isHost === '1',
canPublish: el.dataset.canPublish !== '0',
audioOnlyPublish: el.dataset.audioOnlyPublish === '1',
usesSpeakAccess: el.dataset.usesSpeakAccess === '1',
canManageSpeak: el.dataset.canManageSpeak === '1',
speakGranted: el.dataset.speakGranted === '1',
speakRequested: el.dataset.speakRequested === '1',
inBreakout: el.dataset.inBreakout === '1',
isWebinar: el.dataset.isWebinar === '1',
isConference: el.dataset.isConference === '1',
sessionNounLabel: el.dataset.sessionNoun || '',
isGreenRoom: el.dataset.isGreenRoom === '1',
audioOnly,
isSpace: el.dataset.isSpace === '1',
muteOnJoin: el.dataset.muteOnJoin === '1',
videoOffOnJoin: el.dataset.videoOffOnJoin === '1' || audioOnly,
isRecording: el.dataset.recordingActive === '1',
activeRecordingUuid: el.dataset.activeRecordingUuid || null,
isLocked: el.dataset.locked === '1',
watermark: el.dataset.watermark === '1',
liveCaptions: el.dataset.liveCaptions === '1',
displayName: el.dataset.displayName || '',
presenterRefs,
usesStageLayout: el.dataset.usesStageLayout === '1',
panelDiscussions,
stageLayout,
activePanelId: el.dataset.activePanelId || '',
spotlightSpeakerRef: el.dataset.spotlightSpeakerRef || '',
panels,
sessionParticipants,
roomHost,
waitingCount: sessionParticipants.filter((person) => person.status === 'waiting').length,
assignedBreakoutRoomId: selfParticipant?.breakout_room_id ?? null,
};
}
function meetRoom() {
const boot = readMeetBootState();
const roomBoot = readMeetRoomBootState();
// LiveKit Room must stay outside Alpine's reactive proxy — wrapping it breaks
// structuredClone inside the SDK during connect and media setup.
let room = null;
@@ -33,38 +108,43 @@ function meetRoom() {
isMuted: true,
isVideoOff: true,
isScreenSharing: false,
isRecording: boot.isRecording,
isLocked: boot.isLocked,
isHost: false,
watermark: false,
liveCaptions: false,
isRecording: roomBoot.isRecording ?? false,
isLocked: roomBoot.isLocked ?? false,
isHost: roomBoot.isHost ?? false,
watermark: roomBoot.watermark ?? false,
liveCaptions: roomBoot.liveCaptions ?? false,
displayName: roomBoot.displayName ?? '',
canPublish: roomBoot.canPublish ?? true,
muteOnJoin: roomBoot.muteOnJoin ?? true,
videoOffOnJoin: roomBoot.videoOffOnJoin ?? false,
waitingCount: roomBoot.waitingCount ?? 0,
isWebinar: roomBoot.isWebinar ?? false,
isConference: roomBoot.isConference ?? false,
sessionNounLabel: roomBoot.sessionNounLabel ?? '',
isGreenRoom: roomBoot.isGreenRoom ?? false,
presenterRefs: roomBoot.presenterRefs ?? [],
audioOnly: roomBoot.audioOnly ?? false,
audioOnlyPublish: roomBoot.audioOnlyPublish ?? false,
usesSpeakAccess: roomBoot.usesSpeakAccess ?? false,
canManageSpeak: roomBoot.canManageSpeak ?? false,
speakGranted: roomBoot.speakGranted ?? false,
speakRequested: roomBoot.speakRequested ?? false,
isSpace: roomBoot.isSpace ?? false,
usesStageLayout: roomBoot.usesStageLayout ?? false,
panelDiscussions: roomBoot.panelDiscussions ?? false,
stageLayout: roomBoot.stageLayout ?? 'plenary',
panels: roomBoot.panels ?? [],
activePanelId: roomBoot.activePanelId ?? '',
spotlightSpeakerRef: roomBoot.spotlightSpeakerRef ?? '',
inBreakout: roomBoot.inBreakout ?? false,
assignedBreakoutRoomId: roomBoot.assignedBreakoutRoomId ?? null,
activeRecordingUuid: roomBoot.activeRecordingUuid ?? null,
sessionParticipants: roomBoot.sessionParticipants ?? [],
roomHost: roomBoot.roomHost ?? null,
captionText: '',
displayName: '',
canPublish: true,
muteOnJoin: true,
videoOffOnJoin: false,
audioPlaybackBlocked: false,
needsMediaUnlock: false,
waitingCount: 0,
isWebinar: false,
isConference: false,
sessionNounLabel: '',
isGreenRoom: false,
goingLive: false,
presenterRefs: [],
audioOnly: false,
audioOnlyPublish: false,
usesSpeakAccess: false,
canManageSpeak: false,
speakGranted: false,
speakRequested: false,
isSpace: false,
usesStageLayout: false,
panelDiscussions: false,
stageLayout: 'plenary',
panels: [],
activePanelId: '',
spotlightSpeakerRef: '',
panelSetupOpen: false,
savingStageLayout: false,
_stageSnapshot: null,
@@ -72,10 +152,8 @@ function meetRoom() {
activePolls: [],
breakoutBroadcast: '',
breakoutBroadcastInput: '',
inBreakout: false,
breakoutsActive: false,
activeBreakouts: [],
assignedBreakoutRoomId: null,
breakoutRoomName: '',
breakoutClosesAt: '',
sidebarPanel: null,
@@ -87,15 +165,12 @@ function meetRoom() {
breakoutModalOpen: false,
breakoutCount: '4',
endMeetingConfirmOpen: false,
activeRecordingUuid: null,
joinUrl: '',
passcode: '',
roomTitle: '',
connectionStatus: 'Connecting…',
participants: [],
sessionParticipants: [],
activeSpeakerIds: [],
roomHost: null,
floatingReactions: [],
reactionsInitialized: false,
pollTimer: null,