fix(web): 'Unknown Artist' download from artist page + rename itunes*→deezer* identifiers

Fix (the reported bug):
- Deezer's /artist/{id}/albums omits the artist object, so discography album cards had an
  empty artist name → the download modal fell back to the literal "Unknown Artist", which
  poisoned the yt-dlp search ("Unknown Artist <album>") and its artist/channel filter, failing
  with "Nicht eindeutig gefunden".
- deezerLookupArtistAlbums now backfills the known artist name (we're on that artist's page).
- openDlModal now defaults album cards to an ALBUM download (was always Track), so a one-click
  download no longer grabs an album as a single track named after the album.

Rename (requested cleanup, dependency-checked so nothing breaks):
- All frontend itunes* identifiers → deezer* (functions, the ItunesItem-shape field keys
  itunesData/itunesArtistId/itunesFanCount/itunesId, the itunes-album-detail route + DOM ids,
  the badge-itunes CSS class). The backend reads none of these fields, so the boundary is safe.
- Verified: build passes; route/DOM-id/CSS producer↔consumer all consistent; only the factual
  "Apple's iTunes /search 403" comments keep the historical name. SW ns-v62.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Opus 4.8 committed 2026-08-01 00:31:09 +02:00
1 parent bc87a04da5
commit 1e206e8df3
13 files changed
+118 -108

No files matched your search

+1 -1
View File
@@ -75,7 +75,7 @@ export function makeSongItem(s, idx, list, { noArtistLink = false, singlePlay =
return el;
}
// ─── GLOBAL TRACK ITEM (iTunes / Spotify results) ───
// ─── GLOBAL TRACK ITEM (Deezer / Spotify results) ───
export function makeGlobalTrackItem(t, idx, list) {
const el = document.createElement('div');
el.className = 'gtrack-item';
+8 -5
View File
@@ -1,13 +1,16 @@
import { S } from '../state.js';
import { esc, toast } from '../utils.js';
import { api, fetchRomajiIndex, romajiConvert, getRomajiOverrides, invalidateRomajiIndex, itunesLookupAlbum } from '../api.js';
import { api, fetchRomajiIndex, romajiConvert, getRomajiOverrides, invalidateRomajiIndex, deezerLookupAlbum } from '../api.js';
import { _addNotif } from './notify.js';
// ─── DOWNLOAD MODAL ───
export function openDlModal(track) {
if(!S.cfg.backendUrl) { toast('⚠ Kein Backend konfiguriert. Bitte in Einstellungen eintragen.'); return; }
S.downloadTarget = track; S.dlType = 'track';
document.querySelectorAll('.modal-opt').forEach(o => o.classList.toggle('selected', o.dataset.type==='track'));
// Album cards pass isAlbum → default the modal to an album download, not a single track named
// after the album (a one-click download of an album card used to grab it as one "track").
const _defType = track.isAlbum ? 'album' : 'track';
S.downloadTarget = track; S.dlType = _defType;
document.querySelectorAll('.modal-opt').forEach(o => o.classList.toggle('selected', o.dataset.type===_defType));
const info = document.getElementById('dl-modal-info');
const art = track.artworkUrl100 || track.artworkUrl60 || '';
info.innerHTML = `${art ? `<div class="modal-art"><img src="${art}"></div>` : '<div class="modal-art" style="display:flex;align-items:center;justify-content:center;font-size:28px">🎵</div>'}
@@ -35,7 +38,7 @@ export async function executeDownload() {
title: _title,
album: _album,
artworkUrl: S.downloadTarget.artworkUrl100 || S.downloadTarget.artworkUrl60 || '',
itunesId: S.downloadTarget.trackId || S.downloadTarget.collectionId || null,
deezerId: S.downloadTarget.trackId || S.downloadTarget.collectionId || null,
collectionId: S.downloadTarget.collectionId || null,
explicit: S.downloadTarget.trackExplicitness === 'explicit',
trackNum: S.downloadTarget.trackNumber || undefined,
@@ -51,7 +54,7 @@ export async function executeDownload() {
// request — the backend downloads that list directly (Apple's /search is 403, so no iTunes lookup).
if (S.dlType === 'album' && payload.collectionId) {
try {
const albumTracks = await itunesLookupAlbum(payload.collectionId);
const albumTracks = await deezerLookupAlbum(payload.collectionId);
if (albumTracks.length) payload.tracks = albumTracks;
} catch {}
}