mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
fix(library): All Albums compilation filter matches VA album artist (#1026)
* fix(library): All Albums compilation filter matches VA album artist Local index SQL and track-grouped browse missed compilations tagged via Various Artists on album_artist; genre-only browse also ignored combined filters. Extend predicates on both sides and route genre+filter to advanced search. * docs(changelog): All Albums compilation filter fix (PR #1026)
This commit is contained in:
@@ -30,19 +30,42 @@ export async function runLocalAlbumBrowse(
|
||||
|
||||
if (query.genres.length > 0) {
|
||||
if (query.genres.length === 1) {
|
||||
// Genre-only fast path; combined filters (year / lossless / compilation) need advanced search.
|
||||
if (shared.length === 0) {
|
||||
try {
|
||||
const resp = await libraryListAlbumsByGenre({
|
||||
serverId,
|
||||
genre: query.genres[0],
|
||||
libraryScope: scope,
|
||||
sort: albumSortClauses(query.sort),
|
||||
limit: pageSize,
|
||||
offset,
|
||||
});
|
||||
if (resp.source !== 'local') return null;
|
||||
let albums = resp.albums.map(albumToAlbum);
|
||||
if (useServerStarredIds) albums = markServerStarredAlbums(albums);
|
||||
return { albums, hasMore: resp.hasMore };
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
try {
|
||||
const resp = await libraryListAlbumsByGenre({
|
||||
const resp = await libraryAdvancedSearch({
|
||||
serverId,
|
||||
genre: query.genres[0],
|
||||
libraryScope: scope,
|
||||
entityTypes: ['album'],
|
||||
filters: [{ field: 'genre', op: 'eq', value: query.genres[0] }, ...shared],
|
||||
starredOnly,
|
||||
restrictAlbumIds: useServerStarredIds ? restrictAlbumIds : undefined,
|
||||
sort: albumSortClauses(query.sort),
|
||||
limit: pageSize,
|
||||
offset,
|
||||
skipTotals: true,
|
||||
});
|
||||
if (resp.source !== 'local') return null;
|
||||
let albums = resp.albums.map(albumToAlbum);
|
||||
if (useServerStarredIds) albums = markServerStarredAlbums(albums);
|
||||
return { albums, hasMore: resp.hasMore };
|
||||
return { albums, hasMore: albums.length === pageSize };
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
import { filterAlbumsByCompilation } from './albumBrowseFilters';
|
||||
|
||||
const album = (
|
||||
overrides: Partial<SubsonicAlbum> & { compilation?: boolean } = {},
|
||||
overrides: Partial<SubsonicAlbum> & { compilation?: boolean; albumArtist?: string } = {},
|
||||
): SubsonicAlbum => ({
|
||||
id: '1',
|
||||
name: 'A',
|
||||
@@ -25,6 +25,7 @@ describe('albumIsCompilation', () => {
|
||||
expect(albumIsCompilation(album({ compilation: true }))).toBe(true);
|
||||
expect(albumIsCompilation(album({ releaseTypes: ['Live', 'Compilation'] }))).toBe(true);
|
||||
expect(albumIsCompilation(album({ artist: 'Various Artists' }))).toBe(true);
|
||||
expect(albumIsCompilation(album({ albumArtist: 'Various Artists' }))).toBe(true);
|
||||
expect(albumIsCompilation(album())).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,12 +10,15 @@ const VARIOUS_ARTISTS = /\bvarious artists\b/i;
|
||||
/** OpenSubsonic / Navidrome: `compilation`, `isCompilation`, `releaseTypes`, or VA artist. */
|
||||
export function albumIsCompilation(a: SubsonicAlbum): boolean {
|
||||
if (a.isCompilation === true) return true;
|
||||
const loose = a as SubsonicAlbum & { compilation?: boolean };
|
||||
const loose = a as SubsonicAlbum & { compilation?: boolean; albumArtist?: string };
|
||||
if (loose.compilation === true) return true;
|
||||
if (a.releaseTypes?.some(t => /^compilation$/i.test(t.trim()))) return true;
|
||||
const artist = (a.artist ?? '').trim();
|
||||
const displayArtist = (a.displayArtist ?? '').trim();
|
||||
return VARIOUS_ARTISTS.test(artist) || VARIOUS_ARTISTS.test(displayArtist);
|
||||
const albumArtist = (loose.albumArtist ?? '').trim();
|
||||
return VARIOUS_ARTISTS.test(artist)
|
||||
|| VARIOUS_ARTISTS.test(displayArtist)
|
||||
|| VARIOUS_ARTISTS.test(albumArtist);
|
||||
}
|
||||
|
||||
/** Stop paginating when the catalog tail is reached or the scan budget is spent. */
|
||||
|
||||
Reference in New Issue
Block a user