mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 15:25:46 +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:
@@ -1,9 +1,11 @@
|
||||
import { star, unstar } from '../api/subsonicStarRating';
|
||||
import { buildCoverArtUrl, coverArtCacheKey } from '../api/subsonicStreamUrl';
|
||||
import { usePlaybackCoverArt } from '../hooks/usePlaybackCoverArt';
|
||||
import type { Track } from '../store/playerStoreTypes';
|
||||
import { getPlaybackProgressSnapshot, subscribePlaybackProgress } from '../store/playbackProgress';
|
||||
import React, { useState, useCallback, useMemo, useRef, useEffect, useSyncExternalStore, CSSProperties } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { usePlaybackLibraryNavigate } from '../hooks/usePlaybackLibraryNavigate';
|
||||
import { useEnsurePlaybackServerOnMount } from '../hooks/useEnsurePlaybackServerOnMount';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
ChevronDown, Play, Pause, SkipBack, SkipForward,
|
||||
@@ -152,6 +154,8 @@ function LyricsDrawer({ onClose, currentTrack }: { onClose: () => void; currentT
|
||||
export default function MobilePlayerView() {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const navigatePlaybackLibrary = usePlaybackLibraryNavigate();
|
||||
useEnsurePlaybackServerOnMount();
|
||||
|
||||
// Lock body scroll while full-screen player is mounted
|
||||
useEffect(() => {
|
||||
@@ -185,12 +189,7 @@ export default function MobilePlayerView() {
|
||||
|
||||
const duration = currentTrack?.duration ?? 0;
|
||||
|
||||
// Cover art
|
||||
const coverFetchUrl = useMemo(
|
||||
() => currentTrack?.coverArt ? buildCoverArtUrl(currentTrack.coverArt, 800) : '',
|
||||
[currentTrack?.coverArt]
|
||||
);
|
||||
const coverKey = currentTrack?.coverArt ? coverArtCacheKey(currentTrack.coverArt, 800) : '';
|
||||
const { src: coverFetchUrl, cacheKey: coverKey } = usePlaybackCoverArt(currentTrack?.coverArt, 800);
|
||||
const resolvedCover = useCachedUrl(coverFetchUrl, coverKey);
|
||||
|
||||
// Dynamic background color extracted from cover art
|
||||
@@ -332,7 +331,7 @@ export default function MobilePlayerView() {
|
||||
<OpenArtistRefInline
|
||||
refs={currentTrack.artists}
|
||||
fallbackName={currentTrack.artist}
|
||||
onGoArtist={id => navigate(`/artist/${id}`)}
|
||||
onGoArtist={id => { void navigatePlaybackLibrary(`/artist/${id}`); }}
|
||||
as="none"
|
||||
linkTag="span"
|
||||
linkClassName="mp-artist-link"
|
||||
@@ -341,12 +340,12 @@ export default function MobilePlayerView() {
|
||||
<span
|
||||
role={currentTrack.artistId ? 'link' : undefined}
|
||||
tabIndex={currentTrack.artistId ? 0 : undefined}
|
||||
onClick={() => currentTrack.artistId && navigate(`/artist/${currentTrack.artistId}`)}
|
||||
onClick={() => currentTrack.artistId && void navigatePlaybackLibrary(`/artist/${currentTrack.artistId}`)}
|
||||
onKeyDown={e => {
|
||||
if (!currentTrack.artistId) return;
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
navigate(`/artist/${currentTrack.artistId}`);
|
||||
void navigatePlaybackLibrary(`/artist/${currentTrack.artistId}`);
|
||||
}
|
||||
}}
|
||||
style={{ cursor: currentTrack.artistId ? 'pointer' : 'default' }}
|
||||
|
||||
Reference in New Issue
Block a user