fix(site): repair onboarding audio cleanup, redirect, and manifest fetches

- loadDialogueManifest: cache the resolved manifest at module level and
  dedupe concurrent fetches so each screen no longer re-downloads it
- useGameStore: completeIntroState now also advances intro.currentStep
  to "playing" so callers do not need a separate setIntroStep call
- SiteNamingScreen and SiteTransitionOverlay: replace ref-based guards
  with an isCancelled flag captured per effect. The previous guards
  persisted across StrictMode remounts, leaving mount 2 unable to
  re-run the effect after mount 1's chain was cancelled, which broke
  the fade animations, the second narrator dialogue and the redirect.
  Both screens now also call stopCurrentDialogue on unmount so audio
  cannot bleed across routes, and the transition gets a safety timeout
  in case the dialogue audio fails to fire its "ended" event
- SiteTransitionOverlay: keep the <Subtitles /> mount inside the
  overlay so it renders inside the z-index 1000 stacking context
  (above the black screen); the one in SiteLayout sits behind it
- IntroDialogueOverlay: route through playDialogueById instead of
  AudioManager.playSoundWithCallback so the narrator subtitles play
  in sync, and add the same isCancelled cleanup pattern
- IntroRevealOverlay: rely on completeIntro alone now that it advances
  intro.currentStep, and skip the fade when reduced motion is requested
- SiteMobileBlocker: correct logo path from public/... to /...
This commit is contained in:
Tom Boullay
2026-05-30 18:43:53 +02:00
parent 0f6860f1ae
commit 07b09c22af
7 changed files with 206 additions and 104 deletions
+1
View File
@@ -121,6 +121,7 @@ function completeIntroState(state: GameState): GameStateUpdate {
mainState: "ebike",
intro: {
...state.intro,
currentStep: "playing",
hasCompleted: true,
isEbikeUnlocked: true,
},