feat(artist): pin a local artist to a specific Deezer artist (same-name fix, shared)
Fixes same-name collisions where NovaSonic guessed the wrong Deezer artist (e.g. 'Nana' → a random DJ): fans, top songs, missing albums and the hero image were all off. A '⚙ Falscher Künstler?' button on the artist page opens a picker (same-name Deezer candidates with image + fan count); the chosen mapping is stored SERVER-SIDE (shared across users, like the romaji overrides) in /data/deezer-artist-overrides.json. Once pinned, the artist page short-circuits the name search to the pinned Deezer id (drives albums/top-songs/fans) and overrides the hero image with the pinned artist's Deezer picture (NovaSonic-side, so it works even for tag-merged same-name artists — Navidrome can't disambiguate them without an MBID). New endpoints GET/POST/DELETE /api/artist-overrides; api.js load/get/set/remove; loaded at startup. SW cache -> ns-v74. Needs on-device runtime test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
b788fedec3
commit
02960cf886
6 files changed
+204
-7
No files matched your search
+4
-1
@@ -1,9 +1,10 @@
|
||||
import { S } from './state.js';
|
||||
import { toast } from './utils.js';
|
||||
import { api, fetchRomajiIndex, loadRomajiOverrides } from './api.js';
|
||||
import { api, fetchRomajiIndex, loadRomajiOverrides, loadArtistOverrides } from './api.js';
|
||||
import { injectPWA } from './pwa.js';
|
||||
import { initPlayLog } from './player/scrobbleLog.js';
|
||||
import { openStats, closeStats } from './ui/stats.js';
|
||||
import { closeArtistPin, clearArtistPin } from './ui/artistPin.js';
|
||||
import { loadSavedTheme } from './themes.js';
|
||||
import { initScrollRows } from './ui/components.js';
|
||||
import {
|
||||
@@ -111,6 +112,7 @@ async function startApp() {
|
||||
}
|
||||
initNotifBell();
|
||||
initPlayLog(); // flush any queued plays to the scrobble service (offline-safe)
|
||||
loadArtistOverrides().catch(() => {}); // pinned same-name artist → Deezer mappings (shared)
|
||||
// Wait for overrides before restoring player bar so disp* functions have the cache ready
|
||||
loadRomajiOverrides().catch(() => {}).then(() => { _restoreLastPlayed(); });
|
||||
if(localStorage.getItem('ns_radio')==='1') { S.radioMode=true; _applyRadioBtn(); }
|
||||
@@ -334,6 +336,7 @@ Object.assign(window, {
|
||||
openSettings, closeSettings, saveSettings, confirmDisconnect, checkBackend,
|
||||
openSidebar, closeSidebar, switchNavMode, showCtxMenu,
|
||||
openStats, closeStats,
|
||||
closeArtistPin, clearArtistPin,
|
||||
// Views
|
||||
loadAlbums, loadStarred, loadRandom, filterStarred, filterPlaylist,
|
||||
plReorderEnter, plReorderSave, plReorderCancel, toggleAllGenres,
|
||||
|
||||
Reference in new issue
Block a user