diff --git a/ui/src/lib/audio.svelte.ts b/ui/src/lib/audio.svelte.ts index 0299c74..9020d22 100644 --- a/ui/src/lib/audio.svelte.ts +++ b/ui/src/lib/audio.svelte.ts @@ -85,11 +85,16 @@ class AudioStore { nextChapter = $state(null); /** - * Set to true by the layout's onended handler (when autoNext fires a - * navigation). The AudioPlayer on the new page checks this on mount - * and, if true, immediately starts the play flow then clears the flag. + * Set to the chapter number that should auto-start by the layout's onended + * handler (when autoNext fires a navigation). The AudioPlayer on the new + * page checks this on mount: if it matches the component's own chapter prop + * it starts playback and clears the value. + * + * Using the target chapter number (instead of a plain boolean) prevents the + * still-mounted outgoing AudioPlayer from reacting to the flag before the + * navigation completes — it only matches the incoming chapter's component. */ - autoStartPending = $state(false); + autoStartChapter = $state(null); // ── Next-chapter pre-fetch state ───────────────────────────────────────── /** diff --git a/ui/src/lib/components/AudioPlayer.svelte b/ui/src/lib/components/AudioPlayer.svelte index 4066c2d..bb51f62 100644 --- a/ui/src/lib/components/AudioPlayer.svelte +++ b/ui/src/lib/components/AudioPlayer.svelte @@ -70,9 +70,11 @@ }); // Auto-start: if the layout navigated here via auto-next, kick off playback. + // We match against the chapter prop so the outgoing chapter's AudioPlayer + // (still mounted during the brief navigation window) never reacts to this. $effect(() => { - if (audioStore.autoStartPending) { - audioStore.autoStartPending = false; + if (audioStore.autoStartChapter === chapter) { + audioStore.autoStartChapter = null; startPlayback(); } }); diff --git a/ui/src/routes/+layout.svelte b/ui/src/routes/+layout.svelte index f56b6ef..16cdf9a 100644 --- a/ui/src/routes/+layout.svelte +++ b/ui/src/routes/+layout.svelte @@ -184,9 +184,11 @@ // we need. const targetSlug = audioStore.slug; const targetChapter = audioStore.nextChapter; - audioStore.autoStartPending = true; + // Store the target chapter number so only the newly-mounted AudioPlayer + // for that chapter reacts — not the outgoing chapter's component. + audioStore.autoStartChapter = targetChapter; goto(`/books/${targetSlug}/chapters/${targetChapter}`).catch(() => { - audioStore.autoStartPending = false; + audioStore.autoStartChapter = null; }); } }}