Compare commits

...

1 Commits

Author SHA1 Message Date
root
836c9855af fix(player): use untrack() in toggleRequest effect to prevent play/pause loop
All checks were successful
Release / Test backend (push) Successful in 37s
Release / Check ui (push) Successful in 1m40s
Release / Docker / caddy (push) Successful in 46s
Release / Docker / backend (push) Successful in 2m29s
Release / Docker / runner (push) Successful in 2m43s
Release / Upload source maps (push) Successful in 1m31s
Release / Docker / ui (push) Successful in 2m21s
Release / Gitea Release (push) Successful in 30s
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.
2026-04-06 14:57:27 +05:00

View File

@@ -2,7 +2,7 @@
import '../app.css';
import { page, navigating } from '$app/state';
import { goto } from '$app/navigation';
import { setContext } from 'svelte';
import { setContext, untrack } from 'svelte';
import type { Snippet } from 'svelte';
import type { LayoutData } from './$types';
import { audioStore } from '$lib/audio.svelte';
@@ -156,15 +156,23 @@
});
// 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(() => {
// Read toggleRequest to subscribe; ignore value 0 (initial).
const _req = audioStore.toggleRequest;
if (!audioEl || _req === 0) return;
if (audioStore.isPlaying) {
audioEl.pause();
} else {
audioEl.play().catch(() => {});
}
untrack(() => {
if (audioStore.isPlaying) {
audioEl!.pause();
} else {
audioEl!.play().catch(() => {});
}
});
});
// Handle seek requests from AudioPlayer controller.