Add History API routing so browser/Android back navigates screens
- ui-store syncs screens to history (push on go/goGame, hash URLs like #/profile), back() = history.back(), initHistory anchors a home base + restores deep links - page.tsx listens to popstate; resolveScreen() guards transient screens (game/room/chat/matchmaking fall back to home when their state is gone) - ScreenHeader + ChatScreen back buttons use history back; chat cleans up on unmount Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+27
-1
@@ -14,7 +14,25 @@ import { ChatScreen } from "@/components/screens/ChatScreen";
|
||||
import { AuthScreen } from "@/components/screens/AuthScreen";
|
||||
import { DailyRewardModal } from "@/components/online/DailyRewardModal";
|
||||
import { useSessionStore } from "@/lib/session-store";
|
||||
import { useUIStore } from "@/lib/ui-store";
|
||||
import { useGameStore } from "@/lib/game-store";
|
||||
import { useOnlineStore } from "@/lib/online-store";
|
||||
import { screenFromHash, useUIStore, type Screen } from "@/lib/ui-store";
|
||||
|
||||
/** Transient screens can't be restored without their state — fall back to home. */
|
||||
function resolveScreen(s: Screen): Screen {
|
||||
switch (s) {
|
||||
case "game":
|
||||
return useGameStore.getState().started ? s : "home";
|
||||
case "room":
|
||||
return useOnlineStore.getState().room ? s : "home";
|
||||
case "chat":
|
||||
return useOnlineStore.getState().activeChatFriend ? s : "home";
|
||||
case "matchmaking":
|
||||
return useOnlineStore.getState().matchmaking.phase !== "idle" ? s : "home";
|
||||
default:
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
export default function Page() {
|
||||
const screen = useUIStore((s) => s.screen);
|
||||
@@ -23,6 +41,14 @@ export default function Page() {
|
||||
|
||||
useEffect(() => {
|
||||
init();
|
||||
useUIStore.getState().initHistory();
|
||||
|
||||
const onPop = (e: PopStateEvent) => {
|
||||
const raw = ((e.state?.screen as Screen) ?? screenFromHash());
|
||||
useUIStore.getState().syncFromPop(resolveScreen(raw));
|
||||
};
|
||||
window.addEventListener("popstate", onPop);
|
||||
return () => window.removeEventListener("popstate", onPop);
|
||||
}, [init]);
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user