P12: persistent live session across navigation
- Player room connection lifted out of the /play route to an app-level hook (usePlayerConnection in RootLayout), keyed by a persisted joinIntent — so a player stays connected while browsing their sheet, the compendium, anywhere, and a reload reconnects automatically. - Header "● Live: CODE · Leave" badge (PlayerSessionBadge); leaving is explicit (leaveRoom clears intent + disconnects). /play renders the table from the store. - Realtime e2e: player navigates away, badge persists, returns to a synced table. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,8 @@ import { Button } from '@/components/ui/Button';
|
||||
import { SessionControl } from '@/features/play/SessionControl';
|
||||
import { HandoutControl } from '@/features/play/HandoutControl';
|
||||
import { useSessionBroadcaster } from '@/features/play/useSessionBroadcaster';
|
||||
import { usePlayerConnection } from '@/features/play/usePlayerConnection';
|
||||
import { PlayerSessionBadge } from '@/features/play/PlayerConnection';
|
||||
|
||||
const NAV = [
|
||||
{ to: '/', label: 'Campaigns', exact: true },
|
||||
@@ -62,6 +64,7 @@ export function RootLayout() {
|
||||
const activeCampaign = useActiveCampaign();
|
||||
// While the GM is hosting, mirror state to players (inert unless hosting).
|
||||
useSessionBroadcaster(activeCampaign ?? null);
|
||||
usePlayerConnection();
|
||||
|
||||
// Global Ctrl/Cmd+K opens the command palette.
|
||||
useEffect(() => {
|
||||
@@ -99,6 +102,7 @@ export function RootLayout() {
|
||||
})}
|
||||
</nav>
|
||||
<div className="ml-auto flex items-center gap-2">
|
||||
<PlayerSessionBadge />
|
||||
{activeCampaign && <HandoutControl />}
|
||||
<SessionControl />
|
||||
<Button size="sm" variant="ghost" onClick={() => setPaletteOpen(true)} title="Command palette (Ctrl/Cmd+K)" aria-label="Open command palette">
|
||||
|
||||
Reference in New Issue
Block a user