feat(web): add smooth page transitions and WASM loading states

- Implement navigation state tracking with optimistic UI updates
- Add loading spinner and error handling for WASM initialization
- Insert browser yield points during game initialization to prevent freezing
- Redesign leaderboard with tabbed navigation and mock data structure
- Add utility CSS classes for consistent page layouts
This commit is contained in:
2025-12-29 03:33:43 -06:00
parent d3514b84e9
commit 3bb3908853
22 changed files with 602 additions and 328 deletions
+24
View File
@@ -0,0 +1,24 @@
import { useSyncExternalStore } from "react";
type Listener = (pendingUrl: string | null) => void;
let pendingUrl: string | null = null;
const listeners = new Set<Listener>();
export function setPendingNavigation(url: string | null) {
pendingUrl = url;
listeners.forEach((listener) => listener(pendingUrl));
}
export function getPendingNavigation(): string | null {
return pendingUrl;
}
export function subscribeToPendingNavigation(listener: Listener): () => void {
listeners.add(listener);
return () => listeners.delete(listener);
}
export function usePendingNavigation(): string | null {
return useSyncExternalStore(subscribeToPendingNavigation, getPendingNavigation, () => null);
}
+9
View File
@@ -5,11 +5,20 @@ export interface PacmanModule {
_restart_game?: () => void;
locateFile: (path: string) => string;
preRun: unknown[];
// Emscripten error hooks
onAbort?: (what: unknown) => void;
onRuntimeInitialized?: () => void;
}
export type LoadingError =
| { type: "timeout" }
| { type: "script"; message: string }
| { type: "runtime"; message: string };
export interface PacmanWindow extends Window {
Module?: PacmanModule;
pacmanReady?: () => void;
pacmanError?: (error: LoadingError) => void;
SDL_CANVAS_ID?: string;
}