diff --git a/src/workspaces/officerdev/src/MusicPlayer/MusicPlayerHost.tsx b/src/workspaces/officerdev/src/MusicPlayer/MusicPlayerHost.tsx index 1453d9be..461b1d2e 100644 --- a/src/workspaces/officerdev/src/MusicPlayer/MusicPlayerHost.tsx +++ b/src/workspaces/officerdev/src/MusicPlayer/MusicPlayerHost.tsx @@ -60,6 +60,13 @@ export const MusicPlayerHost = () => { const isRestoringRef = useRef(false); const seekToRef = useRef(null); const engineIndexRef = useRef(0); + // The engine is created once, so its callbacks would capture first-render closures. useMusicPlayer's + // functional setters (syncIndex/setPlaying) read the state captured at THAT render (the initial EMPTY + // queue) — calling them from a stale closure wipes the queue. Route them through refs kept current. + const syncIndexRef = useRef(syncIndex); + syncIndexRef.current = syncIndex; + const setPlayingRef = useRef(setPlaying); + setPlayingRef.current = setPlaying; const withToken = (u: string) => (token ? `${u}${u.includes('?') ? '&' : '?'}token=${encodeURIComponent(token)}` : u); const streamUrl = (t: PlayerTrack) => @@ -92,9 +99,9 @@ export const MusicPlayerHost = () => { }, onIndex: (i) => { engineIndexRef.current = i; // engine advanced on its own → mirror to UI without restarting - syncIndex(i); + syncIndexRef.current(i); }, - onEndOfQueue: () => setPlaying(false), + onEndOfQueue: () => setPlayingRef.current(false), onLoadingChange: setLoading, }); engineRef.current = engine;