fix: duplicate rows in artist "Top Songs" when a track exists twice in the library

Navidrome can hold the same track twice (downloaded as a single AND as an album track), so
getTopSongs returned two identical rows ("PIXELATED KISSES" x2). Collapse the top-songs list
by title+album for display (keeps the highest play count) on web + Android. SW ns-v59.

Note: this is a display fix — the underlying duplicate files remain a library-cleanup matter.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Opus 4.8 committed 2026-07-31 17:48:02 +02:00
1 parent fbee695aad
commit b3cf01dd3b
3 files changed
+12 -3

No files matched your search

+8 -1
View File
@@ -219,7 +219,14 @@ export async function loadArtistDetail(artist) {
// ── Top Songs ──
const ndAlbums = _ndArtist?.album || [];
const topSongs = topRes.status === 'fulfilled' ? (topRes.value?.topSongs?.song || []) : [];
// Navidrome can hold the same track twice (e.g. downloaded as a single AND as an album track),
// so getTopSongs returns duplicate rows ("PIXELATED KISSES" x2). Collapse by title+album for display.
const _rawTop = topRes.status === 'fulfilled' ? (topRes.value?.topSongs?.song || []) : [];
const _seenTop = new Set();
const topSongs = _rawTop.filter(s => {
const k = `${s.title}|${s.album}`.toLowerCase().replace(/[^a-z0-9|]/g, '');
return _seenTop.has(k) ? false : (_seenTop.add(k), true);
});
const iTracks = iTracksRes.status === 'fulfilled' ? (iTracksRes.value || []).filter(t => t.wrapperType === 'track') : [];
const iAlbums = iAlbumsRes.status === 'fulfilled' ? (iAlbumsRes.value || []) : [];