global player pt. 4 more persistance sheanigans

This commit is contained in:
2026-02-06 01:48:22 -08:00
parent 938b3a3334
commit ccf3a6bc1f
2 changed files with 91 additions and 20 deletions

View File

@@ -8,7 +8,6 @@
import { browser } from "$app/environment";
import { onDestroy, onMount } from "svelte";
import {
getSnapshot,
jumpToTrack,
next,
nowPlayingLabel,
@@ -17,9 +16,11 @@
schedulePersistNow,
setUiOpen,
setVolume,
subscribe,
toggleShuffle,
toggleUiOpen,
toggleWrap,
type PlayerSnapshot,
} from "$lib/player/player.svelte";
import { createMediaSessionBindings } from "$lib/player/media-session";
@@ -32,15 +33,22 @@
// local UI derived from viewport; not persisted
let isMobile = $state(false);
let snap = $state(getSnapshot());
// IMPORTANT: Do not read `window` during SSR. Start with a safe snapshot and let
// the player module + subscription populate the real values on mount.
let snap = $state<PlayerSnapshot>({
queue: [],
currentIndex: null,
currentTrack: null,
shuffleEnabled: false,
wrapEnabled: false,
order: [],
history: [],
cursor: 0,
volume: 1,
uiOpen: false,
});
// Keep `snap` fresh. (This is a simple polling effect; if you later want a
// more "store-like" subscription API, we can refactor player module exports.)
let raf: number | null = null;
function tickSnapshot() {
snap = getSnapshot();
raf = requestAnimationFrame(tickSnapshot);
}
let unsubscribe: (() => void) | null = null;
function updateIsMobile() {
if (!browser) return;
@@ -169,7 +177,10 @@
window.addEventListener("resize", updateIsMobile);
}
raf = requestAnimationFrame(tickSnapshot);
// Subscribe to player changes instead of polling
unsubscribe = subscribe((s) => {
snap = s;
});
media.setPlaybackState("paused");
});
@@ -178,7 +189,7 @@
if (browser) {
window.removeEventListener("resize", updateIsMobile);
}
if (raf) cancelAnimationFrame(raf);
if (unsubscribe) unsubscribe();
media.destroy();
});
</script>