diff --git a/android/app/src/main/kotlin/com/novasonic/app/ui/screen/ItunesArtistScreen.kt b/android/app/src/main/kotlin/com/novasonic/app/ui/screen/ItunesArtistScreen.kt index a7a9704..7bbc29e 100644 --- a/android/app/src/main/kotlin/com/novasonic/app/ui/screen/ItunesArtistScreen.kt +++ b/android/app/src/main/kotlin/com/novasonic/app/ui/screen/ItunesArtistScreen.kt @@ -68,6 +68,10 @@ fun categorizeAlbums(ndAlbums: List, iAlbums: List): ArtistAl } when { match == null -> notDl.add(ia) + // Deezer returns the same album as several variants (single/EP/album/regional); distinctBy + // above only catches identical ids, so also skip an owned album we've already classified — + // otherwise it shows 2-3x ("PIXELATED KISSES"). + match.id in usedNdIds -> Unit iCount > match.songCount -> { partial.add(Triple(match, ia, Pair(match.songCount, iCount))); usedNdIds.add(match.id) } diff --git a/public/sw.js b/public/sw.js index 9caa0ca..e8dde10 100644 --- a/public/sw.js +++ b/public/sw.js @@ -1,4 +1,4 @@ -const CACHE = 'ns-v57'; +const CACHE = 'ns-v58'; const PRECACHE = ['/', 'index.html', 'manifest.json', 'icon.svg']; const SKIP_PATHS = ['/rest/stream', '/rest/download', '/config.js']; // Auth token params stripped from cache keys so artwork survives across sessions/token refreshes. diff --git a/src/views/detail.js b/src/views/detail.js index 3e46658..483c089 100644 --- a/src/views/detail.js +++ b/src/views/detail.js @@ -293,7 +293,7 @@ async function _renderArtistAlbums(el, ndAlbums, iAlbums, artist) { el.innerHTML = '
'; // Match each Deezer album to a Navidrome album by normalized name. - const entries = iAlbums.map(ia => { + const allEntries = iAlbums.map(ia => { const iName = _normAlbum(ia.collectionName); const match = ndAlbums.find(a => { const n = _normAlbum(a.name); @@ -301,6 +301,16 @@ async function _renderArtistAlbums(el, ndAlbums, iAlbums, artist) { }); return { ia, match }; }); + // Deezer returns the same album several times (single/EP/album/regional/explicit variants), which + // rendered one owned album 3× ("PIXELATED KISSES"). Collapse to one entry per owned Navidrome album + // and one per not-owned title. + const entries = []; + const seenNd = new Set(), seenName = new Set(); + for (const e of allEntries) { + if (e.match) { if (seenNd.has(e.match.id)) continue; seenNd.add(e.match.id); } + else { const k = _normAlbum(e.ia.collectionName); if (seenName.has(k)) continue; seenName.add(k); } + entries.push(e); + } // Deezer's /artist/{id}/albums list omits nb_tracks, so the total is unknown here — which made every // owned album look "incomplete" (e.g. "Moonlight 1 / 0"). Resolve the real track count from the