mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 06:25:41 +00:00
fix(playback): pin queue playback to source server when browsing another library (#717)
* fix(playback): pin queue streams, cover art, and library links to queue server When the active server changes while a queue from another server is playing, keep streams and UI on queueServerId; switch back for artist/album links and queue or player-bar context menus. * fix(playback): switch to queue server when opening Now Playing Ensure active server matches queueServerId before Subsonic fetches on the Now Playing page, mobile player route, and queue info panel; scope caches by server id. * docs(credits): mention Now Playing in PR #717 contribution line * fix(playback): route scrobble and queue sync to queue server Address PR review: apiForServer for scrobble/now-playing/savePlayQueue, clear queueServerId on server removal, mini-player queueServerId sync, block cross-server enqueue with toast, and regression tests.
This commit is contained in:
@@ -4,6 +4,11 @@ import { lastfmGetTrackLoved, lastfmUpdateNowPlaying } from '../api/lastfm';
|
||||
import { setDeferHotCachePrefetch } from '../utils/cache/hotCacheGate';
|
||||
import { orbitBulkGuard } from '../utils/orbitBulkGuard';
|
||||
import { sameQueueTrackId } from '../utils/playback/queueIdentity';
|
||||
import {
|
||||
bindQueueServerForPlayback,
|
||||
getPlaybackServerId,
|
||||
shouldBindQueueServerForPlay,
|
||||
} from '../utils/playback/playbackServer';
|
||||
import { resolvePlaybackUrl } from '../utils/playback/resolvePlaybackUrl';
|
||||
import { resolveReplayGainDb } from '../utils/audio/resolveReplayGainDb';
|
||||
import { useAuthStore } from './authStore';
|
||||
@@ -173,6 +178,9 @@ export function runPlayTrack(
|
||||
setSeekFallbackVisualTarget(null);
|
||||
}
|
||||
const newQueue = queue ?? state.queue;
|
||||
if (shouldBindQueueServerForPlay(state.queue, newQueue, queue)) {
|
||||
bindQueueServerForPlayback();
|
||||
}
|
||||
// Prefer an explicit target index from the caller (next/previous/queue-row
|
||||
// click already know the exact slot). `findIndex` returns the *first*
|
||||
// matching id, which jumps backwards when the queue contains the same
|
||||
@@ -207,18 +215,19 @@ export function runPlayTrack(
|
||||
prevTrack
|
||||
&& sameQueueTrackId(prevTrack.id, track.id)
|
||||
&& authState.hotCacheEnabled
|
||||
&& authState.activeServerId,
|
||||
&& getPlaybackServerId(),
|
||||
);
|
||||
|
||||
const runPlayTrackBody = () => {
|
||||
const authStateNow = useAuthStore.getState();
|
||||
const url = resolvePlaybackUrl(track.id, authStateNow.activeServerId ?? '');
|
||||
const playbackSid = getPlaybackServerId();
|
||||
const url = resolvePlaybackUrl(track.id, playbackSid);
|
||||
recordEnginePlayUrl(track.id, url);
|
||||
const preloadedTrackId = get().enginePreloadedTrackId;
|
||||
const keepPreloadHint = preloadedTrackId === track.id;
|
||||
const playbackSourceHint = playbackSourceHintForResolvedUrl(
|
||||
track.id,
|
||||
authStateNow.activeServerId ?? '',
|
||||
playbackSid,
|
||||
url,
|
||||
);
|
||||
if (import.meta.env.DEV) {
|
||||
@@ -255,7 +264,7 @@ export function runPlayTrack(
|
||||
&& !sameQueueTrackId(prevTrack.id, track.id)
|
||||
&& authStateNow.hotCacheEnabled
|
||||
) {
|
||||
const prevPromoteSid = authStateNow.activeServerId;
|
||||
const prevPromoteSid = getPlaybackServerId();
|
||||
if (prevPromoteSid) {
|
||||
void promoteCompletedStreamToHotCache(
|
||||
prevTrack,
|
||||
@@ -326,7 +335,7 @@ export function runPlayTrack(
|
||||
|
||||
// Report Now Playing to Navidrome (for Live/getNowPlaying) + Last.fm
|
||||
const { nowPlayingEnabled: npEnabled, scrobblingEnabled: lfmEnabled, lastfmSessionKey: lfmKey } = useAuthStore.getState();
|
||||
if (npEnabled) reportNowPlaying(track.id);
|
||||
if (npEnabled) reportNowPlaying(track.id, getPlaybackServerId());
|
||||
if (lfmKey) {
|
||||
if (lfmEnabled) lastfmUpdateNowPlaying(track, lfmKey);
|
||||
lastfmGetTrackLoved(track.title, track.artist, lfmKey).then(loved => {
|
||||
@@ -338,10 +347,10 @@ export function runPlayTrack(
|
||||
});
|
||||
}
|
||||
syncQueueToServer(newQueue, track, initialTime);
|
||||
touchHotCacheOnPlayback(track.id, authStateNow.activeServerId ?? '');
|
||||
touchHotCacheOnPlayback(track.id, playbackSid);
|
||||
};
|
||||
|
||||
const hotPromoteSid = authState.activeServerId;
|
||||
const hotPromoteSid = getPlaybackServerId();
|
||||
if (needSameTrackHotPromote && hotPromoteSid) {
|
||||
void promoteCompletedStreamToHotCache(
|
||||
track,
|
||||
|
||||
Reference in New Issue
Block a user