import { useState, useEffect, lazy, Suspense } from "react"; import "./+Page.css"; import { MenuScreen } from "@/shared/components/MenuScreen"; import { useAnalytics } from "@/shared/analytics"; // Lazy load components that aren't needed immediately const GameContainer = lazy(() => import("./GameContainer.client").then(m => ({ default: m.GameContainer }))); const AlphaWarningModal = lazy(() => import("@/shared/components/AlphaWarningModal")); function App() { const [showMenu, setShowMenu] = useState(true); const [isHydrated, setIsHydrated] = useState(false); const analytics = useAnalytics(); // Mark as hydrated after first render to prevent hydration mismatch useEffect(() => { setIsHydrated(true); }, []); // Prefetch components after initial render useEffect(() => { const timer = setTimeout(() => { // Trigger chunk downloads without rendering import("./GameContainer.client"); import("@/shared/components/AlphaWarningModal"); }, 2000); return () => clearTimeout(timer); }, []); // Track app started on mount useEffect(() => { if (!analytics) return; analytics.track("app_started", { platform: __DESKTOP__ ? "desktop" : "browser", }); }, [analytics]); const handleStartSingleplayer = () => { setShowMenu(false); }; const handleExit = async () => { if (__DESKTOP__) { const { invoke } = await import("@tauri-apps/api/core"); await invoke("request_exit").catch((err) => { console.error("Failed to request exit:", err); }); } }; // Don't render game components until hydration is complete if (!isHydrated) { return null; } return ( <> {/* Menu Screen - pre-renderable, covers everything when visible */} {showMenu && } {/* Game Container - client-only, lazy loaded when game starts */} {!showMenu && ( setShowMenu(true)} /> )} ); } export default App;