fix(web): gate play-page un-mute prefetch on actual mute transitions

On mount the mute effect fired alongside the scene effect (both call
prefetchSceneAudio), so the initial /api/beat-audio batch was dispatched
twice — the first set aborted mid-flight. Track the previous muted value
in a ref and only re-prefetch on a real transition, leaving the mount-time
synthesis to the scene effect. Addresses Copilot review on PR #9.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
yuanzonghao
2026-06-02 01:29:33 +08:00
parent 8f94d3aa65
commit 54fda1914c
+9
View File
@@ -414,7 +414,16 @@ function PlayInner() {
// skips synthesis while muted, so a scene entered muted has no audio to play
// back otherwise. (Clearing the map re-synthesizes already-fetched beats on a
// mid-scene un-mute, but that's bounded to one scene and a rare toggle.)
//
// Gate on actual mute *transitions*: on mount this effect would otherwise
// fire alongside the scene effect above (both call prefetchSceneAudio),
// doubling the initial /api/beat-audio batch — the first set is dispatched
// only to be aborted mid-flight, burning TTS quota.
const prevMutedRef = useRef(muted);
useEffect(() => {
const prev = prevMutedRef.current;
prevMutedRef.current = muted;
if (prev === muted) return;
cancelBeatAudioFetches();
if (muted) return;
setBeatAudioMap({});