diff --git a/src/ui.js b/src/ui.js index ba80fbd..ce6a5d6 100644 --- a/src/ui.js +++ b/src/ui.js @@ -355,16 +355,19 @@ async function _createNdPlaylist(tracks, name) { const norm = s => s?.toLowerCase().trim() || ''; for (const t of tracks) { if (!t.trackName) continue; + const missingLabel = t.artistName ? `${t.artistName} – ${t.trackName}` : t.trackName; try { - const r = await api('search3', `&query=${encodeURIComponent(t.trackName)}&songCount=5&albumCount=0&artistCount=0`); + // Search with artist+title first for precision, fall back to title-only with more results + const artistQuery = t.artistName ? `${t.artistName} ${t.trackName}` : t.trackName; + const r = await api('search3', `&query=${encodeURIComponent(artistQuery)}&songCount=10&albumCount=0&artistCount=0`); const songs = r.searchResult3?.song || []; const match = songs.find(s => norm(s.title) === norm(t.trackName) && norm(s.artist).split(' ')[0] === norm(t.artistName).split(' ')[0] ) || songs.find(s => norm(s.title) === norm(t.trackName)); if (match) songIds.push(match.id); - else missing.push(t.trackName); - } catch { missing.push(t.trackName); } + else missing.push(missingLabel); + } catch { missing.push(missingLabel); } } if (!songIds.length) { toast('⚠ Keine Tracks in Navidrome gefunden — zuerst Library scannen, dann Playlist manuell anlegen'); @@ -521,10 +524,22 @@ function updateJob(id, status, msg, progress) { } function renderJobs() { const panel = document.getElementById('jobs-panel'); - panel.innerHTML = ''; - Object.entries(S.jobs).forEach(([id,j]) => { - const c = document.createElement('div'); c.className = 'job-card'; - const isDone=j.status==='done', isErr=j.status==='error'; + const activeIds = new Set(Object.keys(S.jobs)); + + // Remove cards whose jobs are gone + panel.querySelectorAll('[data-job-id]').forEach(el => { + if (!activeIds.has(el.dataset.jobId)) el.remove(); + }); + + Object.entries(S.jobs).forEach(([id, j]) => { + let c = panel.querySelector(`[data-job-id="${id}"]`); + if (!c) { + c = document.createElement('div'); + c.className = 'job-card'; + c.dataset.jobId = id; + panel.appendChild(c); + } + const isDone = j.status === 'done', isErr = j.status === 'error'; const statusText = isErr ? 'Fehler' : isDone ? '✓ Fertig! Bibliothek wird gescannt…' : j.msg || 'Wird heruntergeladen…'; c.innerHTML = `
${esc(j.title)}
@@ -532,7 +547,6 @@ function renderJobs() {
${statusText}
`; - panel.appendChild(c); }); } async function pollJob(jobId) {