fix(player): use untrack() in toggleRequest effect to prevent play/pause loop
Reading audioStore.isPlaying inside the toggleRequest $effect caused Svelte 5 to subscribe to it, so the effect re-ran on every isPlaying change. When resuming from ListeningMode, play() would fire onplay → isPlaying=true → effect re-ran → called pause() → onpause → isPlaying=false → effect re-ran → called play() → infinite loop. Wrapping the isPlaying read in untrack() limits the effect's subscription to toggleRequest only.
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
import '../app.css';
|
import '../app.css';
|
||||||
import { page, navigating } from '$app/state';
|
import { page, navigating } from '$app/state';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { setContext } from 'svelte';
|
import { setContext, untrack } from 'svelte';
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
import type { LayoutData } from './$types';
|
import type { LayoutData } from './$types';
|
||||||
import { audioStore } from '$lib/audio.svelte';
|
import { audioStore } from '$lib/audio.svelte';
|
||||||
@@ -156,15 +156,23 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Handle toggle requests from AudioPlayer controller.
|
// Handle toggle requests from AudioPlayer controller.
|
||||||
|
// IMPORTANT: isPlaying must be read inside untrack() so the effect only
|
||||||
|
// re-runs when toggleRequest increments, not every time isPlaying changes.
|
||||||
|
// Without untrack the effect subscribes to both toggleRequest AND isPlaying,
|
||||||
|
// causing an infinite play/pause loop: play() fires onplay → isPlaying=true
|
||||||
|
// → effect re-runs → sees isPlaying=true → calls pause() → onpause fires
|
||||||
|
// → isPlaying=false → effect re-runs → calls play() → …
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
// Read toggleRequest to subscribe; ignore value 0 (initial).
|
// Read toggleRequest to subscribe; ignore value 0 (initial).
|
||||||
const _req = audioStore.toggleRequest;
|
const _req = audioStore.toggleRequest;
|
||||||
if (!audioEl || _req === 0) return;
|
if (!audioEl || _req === 0) return;
|
||||||
if (audioStore.isPlaying) {
|
untrack(() => {
|
||||||
audioEl.pause();
|
if (audioStore.isPlaying) {
|
||||||
} else {
|
audioEl!.pause();
|
||||||
audioEl.play().catch(() => {});
|
} else {
|
||||||
}
|
audioEl!.play().catch(() => {});
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle seek requests from AudioPlayer controller.
|
// Handle seek requests from AudioPlayer controller.
|
||||||
|
|||||||
Reference in New Issue
Block a user