/** * Content entry. Runs in the page's main world via the manifest declaration. * Coordinates: detector → layout → drawer mount/unmount on phase change. */ import { startDetector, currentPhase } from './detector'; import { ensureHost, applyHomeLayout, applyInGameLayout } from './layout'; import { mountDrawer, unmountDrawer } from './chat-drawer'; import { instrumentWS } from './util/ws-proxy'; function bootstrap(): void { // 1. Always inject a host element so we can mount UI. ensureHost(); // 2. Lightly instrument WebSocket so we can confirm auth is alive (no payload capture). instrumentWS(); // 3. React to phase changes document.addEventListener('bbp:phase', (e) => { const phase = (e as CustomEvent).detail?.phase as string; applyHomeLayoutIfHome(phase); applyInGameLayoutIfInGame(phase); drawerForPhase(phase); }); // 4. Start detector startDetector(); // 5. Initial layout based on current phase (the detector emit() handles this // too, but we double-call here so the first frame isn't unstyled.) const phase = currentPhase(); applyHomeLayoutIfHome(phase); applyInGameLayoutIfInGame(phase); drawerForPhase(phase); } function applyHomeLayoutIfHome(phase: string): void { if (phase === 'home' || phase === 'lobby-list') applyHomeLayout(); } function applyInGameLayoutIfInGame(phase: string): void { if (phase === 'in-game') applyInGameLayout(); } function drawerForPhase(phase: string): void { if (phase === 'in-game') mountDrawer(); else unmountDrawer(); } // Wait for body so we can append to it. if (document.body) bootstrap(); else document.addEventListener('DOMContentLoaded', bootstrap);