diff --git a/apps/web/app/play/page.tsx b/apps/web/app/play/page.tsx index 42a0ae2..4db467f 100644 --- a/apps/web/app/play/page.tsx +++ b/apps/web/app/play/page.tsx @@ -2,7 +2,7 @@ import Link from "next/link"; import { useRouter, useSearchParams } from "next/navigation"; -import { Suspense, useEffect, useRef, useState } from "react"; +import { Suspense, useCallback, useEffect, useRef, useState } from "react"; import { PlayCanvas, type Phase } from "@/components/PlayCanvas"; import { PRESETS } from "@/lib/presets"; import type { @@ -29,11 +29,59 @@ function PlayInner() { } | null>(null); const [turnNum, setTurnNum] = useState(0); const [error, setError] = useState(null); + const [presentation, setPresentation] = useState(false); const startedRef = useRef(false); const prefetchAbortRef = useRef(null); const prefetchRef = useRef>>({}); + const togglePresentation = useCallback(async () => { + const entering = !presentation; + if (entering) { + try { + if (!document.fullscreenElement) { + await document.documentElement.requestFullscreen(); + } + } catch { + // Browser may refuse fullscreen — still enter chrome-less mode + } + setPresentation(true); + } else { + try { + if (document.fullscreenElement) { + await document.exitFullscreen(); + } + } catch { + // ignore + } + setPresentation(false); + } + }, [presentation]); + + useEffect(() => { + function onKey(e: KeyboardEvent) { + if (e.key === "f" || e.key === "F") { + if (e.metaKey || e.ctrlKey || e.altKey) return; + e.preventDefault(); + void togglePresentation(); + } else if (e.key === "Escape" && presentation) { + setPresentation(false); + } + } + function onFullscreenChange() { + // Sync if user exited browser fullscreen via Esc / system gesture + if (!document.fullscreenElement && presentation) { + setPresentation(false); + } + } + window.addEventListener("keydown", onKey); + document.addEventListener("fullscreenchange", onFullscreenChange); + return () => { + window.removeEventListener("keydown", onKey); + document.removeEventListener("fullscreenchange", onFullscreenChange); + }; + }, [togglePresentation, presentation]); + useEffect(() => { if (startedRef.current) return; startedRef.current = true; @@ -241,6 +289,20 @@ function PlayInner() { ); } + if (presentation) { + return ( +
+ +
+ ); + } + return (
@@ -300,10 +362,18 @@ function PlayInner() {
-