mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 14:55:43 +00:00
fix(discord): resolve cover profile from the store, not getPlaybackServerId
Follow-up to the dual-address cover fix: a playback/active cover scope was
routed through getPlaybackServerId(), which returns a `string` that can be
empty or an index-key (not a profile id) for locally-cached tracks. The
`?? activeServerId` fallback never fired (empty string isn't nullish), so no
profile matched and the URL came back null — which the presence layer caches
per cover id, producing intermittent "cover shows, then doesn't".
A playback/active scope always means the active server (a cross-server track
gets an explicit `server` scope), so resolve the active profile directly.
(cherry picked from commit 8f93f30e6f)
This commit is contained in:
@@ -45,4 +45,25 @@ describe('coverArtUrlForDiscord', () => {
|
||||
|
||||
expect(url).toContain('music.example.com');
|
||||
});
|
||||
|
||||
it('resolves a playback scope to the active profile (public address)', async () => {
|
||||
// playback scope is the common case for locally-cached tracks; it must
|
||||
// resolve to the active server, not yield a null cover.
|
||||
const server = makeServer({
|
||||
url: 'http://192.168.1.50:4533',
|
||||
alternateUrl: 'https://music.example.com',
|
||||
});
|
||||
useAuthStore.setState({ servers: [server], activeServerId: server.id } as never);
|
||||
|
||||
const ref: CoverArtRef = {
|
||||
cacheKind: 'album',
|
||||
cacheEntityId: 'al-1',
|
||||
fetchCoverArtId: 'al-1',
|
||||
serverScope: { kind: 'playback' },
|
||||
};
|
||||
const url = await coverArtUrlForDiscord(ref);
|
||||
|
||||
expect(url).toContain('music.example.com');
|
||||
expect(url).not.toContain('192.168.1.50');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
import { buildCoverArtUrlForServer } from '../../api/subsonicStreamUrl';
|
||||
import { serverShareBaseUrl } from '../../utils/server/serverEndpoint';
|
||||
import { getPlaybackServerId } from '../../utils/playback/playbackServer';
|
||||
import { useAuthStore } from '../../store/authStore';
|
||||
import type { CoverArtRef, CoverServerScope } from '../types';
|
||||
|
||||
/** The saved profile id that a cover scope resolves to (active/playback/server). */
|
||||
function serverIdForScope(scope: CoverServerScope): string | null {
|
||||
if (scope.kind === 'server') return scope.serverId;
|
||||
if (scope.kind === 'playback') {
|
||||
return getPlaybackServerId() ?? useAuthStore.getState().activeServerId ?? null;
|
||||
}
|
||||
return useAuthStore.getState().activeServerId ?? null;
|
||||
}
|
||||
import type { CoverArtRef } from '../types';
|
||||
|
||||
/**
|
||||
* Discord large image — an https:// URL Discord's own servers can reach.
|
||||
@@ -21,13 +11,21 @@ function serverIdForScope(scope: CoverServerScope): string | null {
|
||||
* remotely, so a `http://192.168.x.x` address is unreachable and falls back to
|
||||
* the app icon. Discord is an external consumer just like a share link, so use
|
||||
* `serverShareBaseUrl` (public address preferred when both are set).
|
||||
*
|
||||
* Resolve the profile straight from the store: a `playback`/`active` scope
|
||||
* always means the active server (a cross-server track gets an explicit
|
||||
* `server` scope), so we never route through `getPlaybackServerId()`, whose
|
||||
* empty-string / index-key returns previously yielded a null cover URL on
|
||||
* locally-cached tracks.
|
||||
*/
|
||||
export async function coverArtUrlForDiscord(ref: CoverArtRef): Promise<string | null> {
|
||||
const { serverScope, fetchCoverArtId } = ref;
|
||||
const serverId = serverIdForScope(serverScope);
|
||||
const profile = serverId
|
||||
? useAuthStore.getState().servers.find(s => s.id === serverId)
|
||||
: undefined;
|
||||
const auth = useAuthStore.getState();
|
||||
|
||||
const profile =
|
||||
serverScope.kind === 'server'
|
||||
? auth.servers.find(s => s.id === serverScope.serverId)
|
||||
: auth.servers.find(s => s.id === auth.activeServerId);
|
||||
|
||||
if (profile) {
|
||||
return buildCoverArtUrlForServer(
|
||||
|
||||
Reference in New Issue
Block a user