mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 07:15:47 +00:00
fix(home): scope Because you listened rail to sidebar library (#964)
* fix(home): scope Because you listened rail to sidebar library Similar-artist album picks used getArtist without library filtering; session cache also ignored musicLibraryFilterVersion. Filter picks to the scoped album set and key cache/reserve by filter version. * docs(changelog): credit zunoz on Psysonic Discord for PR #964 * test: satisfy SubsonicAlbum required fields in new unit tests Fix tsc --noEmit CI: songCount and duration are required on SubsonicAlbum.
This commit is contained in:
@@ -150,6 +150,29 @@ export async function filterSongsToActiveLibrary(songs: SubsonicSong[]): Promise
|
||||
return filterSongsToServerLibrary(songs, activeServerId);
|
||||
}
|
||||
|
||||
/** Client-side album scope filter — same album-id set as {@link filterSongsToServerLibrary}. */
|
||||
export function filterAlbumsByScopedAlbumIds(
|
||||
albums: SubsonicAlbum[],
|
||||
allowed: Set<string> | null,
|
||||
): SubsonicAlbum[] {
|
||||
if (!allowed || allowed.size === 0) return albums;
|
||||
return albums.filter(a => allowed.has(a.id));
|
||||
}
|
||||
|
||||
export async function filterAlbumsToServerLibrary(
|
||||
albums: SubsonicAlbum[],
|
||||
serverId: string,
|
||||
): Promise<SubsonicAlbum[]> {
|
||||
const allowed = await albumIdsInLibraryScope(serverId);
|
||||
return filterAlbumsByScopedAlbumIds(albums, allowed);
|
||||
}
|
||||
|
||||
export async function filterAlbumsToActiveLibrary(albums: SubsonicAlbum[]): Promise<SubsonicAlbum[]> {
|
||||
const { activeServerId } = useAuthStore.getState();
|
||||
if (!activeServerId) return albums;
|
||||
return filterAlbumsToServerLibrary(albums, activeServerId);
|
||||
}
|
||||
|
||||
/** When scoped to one library, ask the server for more similar tracks — many will be filtered out client-side. */
|
||||
export function similarSongsRequestCount(desired: number): number {
|
||||
const { activeServerId, musicLibraryFilterByServer } = useAuthStore.getState();
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import type { SubsonicAlbum } from './subsonicTypes';
|
||||
import { filterAlbumsByScopedAlbumIds } from './subsonicLibrary';
|
||||
|
||||
const album = (id: string): SubsonicAlbum => ({
|
||||
id,
|
||||
name: id,
|
||||
artist: 'a',
|
||||
artistId: '1',
|
||||
songCount: 1,
|
||||
duration: 1,
|
||||
});
|
||||
|
||||
describe('filterAlbumsByScopedAlbumIds', () => {
|
||||
it('returns all albums when scope is unset', () => {
|
||||
const albums = [album('a'), album('b')];
|
||||
expect(filterAlbumsByScopedAlbumIds(albums, null)).toEqual(albums);
|
||||
});
|
||||
|
||||
it('keeps only albums in the scoped id set', () => {
|
||||
const albums = [album('a'), album('b'), album('c')];
|
||||
expect(filterAlbumsByScopedAlbumIds(albums, new Set(['a', 'c']))).toEqual([album('a'), album('c')]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user