mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 06:25:41 +00:00
fix(search): hide search3 artists with zero albums (#697)
* fix(search): hide search3 artists with zero albums * docs: changelog and credits for search zero-album filter (PR #697)
This commit is contained in:
@@ -255,6 +255,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
|
### Search — hide duplicate artist hits with zero albums
|
||||||
|
|
||||||
|
**By [@cucadmuh](https://github.com/cucadmuh), thanks to zunoz for the report on the Psysonic Discord, PR [#697](https://github.com/Psychotoxical/psysonic/pull/697)**
|
||||||
|
|
||||||
|
* Subsonic **`search3`** sometimes returns extra **artist** rows that duplicate a real name but list **0 albums** (server-side indexing noise). **`search()`** now strips artists whose **`albumCount` is exactly `0`**. Rows with **no** `albumCount` field are kept so strict or legacy servers are unchanged.
|
||||||
|
* Applies everywhere **`search()`** is used: header live search, mobile overlay, search results page, advanced search free-text query, and hooks that call **`search()`** (e.g. similarity fallbacks).
|
||||||
|
|
||||||
### Offline downloads — the cancel button works again + the sidebar toast keeps its size
|
### Offline downloads — the cancel button works again + the sidebar toast keeps its size
|
||||||
|
|
||||||
**By [@Psychotoxical](https://github.com/Psychotoxical), PR [#694](https://github.com/Psychotoxical/psysonic/pull/694)**
|
**By [@Psychotoxical](https://github.com/Psychotoxical), PR [#694](https://github.com/Psychotoxical/psysonic/pull/694)**
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import { filterSearchArtistsWithNoAlbums } from './subsonicSearch';
|
||||||
|
import type { SubsonicArtist } from './subsonicTypes';
|
||||||
|
|
||||||
|
describe('filterSearchArtistsWithNoAlbums', () => {
|
||||||
|
it('removes artists with albumCount 0', () => {
|
||||||
|
const artists: SubsonicArtist[] = [
|
||||||
|
{ id: '1', name: 'Real', albumCount: 2 },
|
||||||
|
{ id: '2', name: 'Ghost', albumCount: 0 },
|
||||||
|
];
|
||||||
|
expect(filterSearchArtistsWithNoAlbums(artists)).toEqual([artists[0]]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('keeps artists when albumCount is omitted', () => {
|
||||||
|
const artists: SubsonicArtist[] = [{ id: '1', name: 'Unknown count' }];
|
||||||
|
expect(filterSearchArtistsWithNoAlbums(artists)).toEqual(artists);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -6,6 +6,15 @@ import type {
|
|||||||
SubsonicSong,
|
SubsonicSong,
|
||||||
} from './subsonicTypes';
|
} from './subsonicTypes';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search3 sometimes returns duplicate or junk artist rows with **zero** albums (e.g. Navidrome indexing).
|
||||||
|
* Drop only rows that explicitly report `albumCount === 0`; keep artists when the field is absent.
|
||||||
|
* Thanks to zunoz for the report on the Psysonic Discord.
|
||||||
|
*/
|
||||||
|
export function filterSearchArtistsWithNoAlbums(artists: SubsonicArtist[]): SubsonicArtist[] {
|
||||||
|
return artists.filter((a) => a.albumCount !== 0);
|
||||||
|
}
|
||||||
|
|
||||||
export async function search(query: string, options?: { albumCount?: number; artistCount?: number; songCount?: number }): Promise<SearchResults> {
|
export async function search(query: string, options?: { albumCount?: number; artistCount?: number; songCount?: number }): Promise<SearchResults> {
|
||||||
if (!query.trim()) return { artists: [], albums: [], songs: [] };
|
if (!query.trim()) return { artists: [], albums: [], songs: [] };
|
||||||
const data = await api<{
|
const data = await api<{
|
||||||
@@ -22,7 +31,11 @@ export async function search(query: string, options?: { albumCount?: number; art
|
|||||||
...libraryFilterParams(),
|
...libraryFilterParams(),
|
||||||
});
|
});
|
||||||
const r = data.searchResult3 ?? {};
|
const r = data.searchResult3 ?? {};
|
||||||
return { artists: r.artist ?? [], albums: r.album ?? [], songs: r.song ?? [] };
|
return {
|
||||||
|
artists: filterSearchArtistsWithNoAlbums(r.artist ?? []),
|
||||||
|
albums: r.album ?? [],
|
||||||
|
songs: r.song ?? [],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ export const CONTRIBUTORS = [
|
|||||||
'Analysis queue control: prune stale http-backfill / cpu-seed jobs when tracks leave the playback queue, cap loudness backfill warmup to current + next 5 tracks, plus debug counters for diagnostics (PR #480)',
|
'Analysis queue control: prune stale http-backfill / cpu-seed jobs when tracks leave the playback queue, cap loudness backfill warmup to current + next 5 tracks, plus debug counters for diagnostics (PR #480)',
|
||||||
'CachedImage / useCachedUrl: blob URL only for matching cacheKey, layout load reset on key change; fixes broken player cover flash on track switch (#606) (PR #695)',
|
'CachedImage / useCachedUrl: blob URL only for matching cacheKey, layout load reset on key change; fixes broken player cover flash on track switch (#606) (PR #695)',
|
||||||
'OpenSubsonic albumArtists in album header; track artists in player bar, mobile, mini + songToTrack (#552) (PR #696)',
|
'OpenSubsonic albumArtists in album header; track artists in player bar, mobile, mini + songToTrack (#552) (PR #696)',
|
||||||
|
'Search: filter search3 artist rows with zero albums (report: zunoz on Psysonic Discord) (PR #697)',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user