feat: show iTunes enrichment status indicator in Spotify importer

This commit is contained in:
Honey committed 2026-05-14 18:01:34 +02:00
1 parent 11dec04fea
commit 55370ad760
3 files changed
+29

No files matched your search

+1
View File
@@ -376,6 +376,7 @@
</div> </div>
<div id="spotify-preview" style="display:none;margin-top:20px"> <div id="spotify-preview" style="display:none;margin-top:20px">
<div id="spotify-preview-inner"></div> <div id="spotify-preview-inner"></div>
<div id="spotify-enrich-status" style="display:none"></div>
<div id="spotify-tracks-section" style="display:none"> <div id="spotify-tracks-section" style="display:none">
<div class="section-header" style="margin-top:8px"> <div class="section-header" style="margin-top:8px">
<span class="section-title" id="spotify-tracks-title">Tracks</span> <span class="section-title" id="spotify-tracks-title">Tracks</span>
+25
View File
@@ -189,6 +189,26 @@ function _renderSpotifyPreview(data) {
} }
} }
function _setEnrichStatus(done, current, total) {
const el = document.getElementById('spotify-enrich-status');
if (!el) return;
if (done) {
el.className = 'done';
el.innerHTML = '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg> iTunes-Daten geladen';
el.style.display = 'flex';
el.style.opacity = '1';
setTimeout(() => {
el.style.opacity = '0';
setTimeout(() => { el.style.display = 'none'; el.className = ''; }, 400);
}, 2000);
} else {
el.className = '';
el.innerHTML = `<div class="enrich-spinner"></div> Lade iTunes-Daten… (${current}/${total})`;
el.style.display = 'flex';
el.style.opacity = '1';
}
}
async function _loadSpotifyTrackArtwork(tracks, listEl) { async function _loadSpotifyTrackArtwork(tracks, listEl) {
const artEls = listEl.querySelectorAll('.gtrack-art'); const artEls = listEl.querySelectorAll('.gtrack-art');
@@ -203,6 +223,8 @@ async function _loadSpotifyTrackArtwork(tracks, listEl) {
// Enrich each track with iTunes data — same call as global search // Enrich each track with iTunes data — same call as global search
const CONC = 4; const CONC = 4;
let enriched = 0;
_setEnrichStatus(false, 0, tracks.length);
for (let i = 0; i < tracks.length; i += CONC) { for (let i = 0; i < tracks.length; i += CONC) {
const batch = tracks.slice(i, i + CONC); const batch = tracks.slice(i, i + CONC);
await Promise.all(batch.map(async (t, bi) => { await Promise.all(batch.map(async (t, bi) => {
@@ -239,8 +261,11 @@ async function _loadSpotifyTrackArtwork(tracks, listEl) {
} }
} }
} catch { /* non-critical */ } } catch { /* non-critical */ }
enriched++;
_setEnrichStatus(false, enriched, tracks.length);
})); }));
} }
_setEnrichStatus(true);
} }
function _startRateLimitCountdown(inner, totalSecs) { function _startRateLimitCountdown(inner, totalSecs) {
+3
View File
@@ -723,6 +723,9 @@ nav{flex:1;overflow-y:auto;padding:4px 10px}
.list-search{width:100%;box-sizing:border-box;padding:8px 12px 8px 32px;background:var(--surface);border:1px solid var(--border2);border-radius:8px;color:var(--text1);font-size:13px;font-family:var(--font);outline:none;transition:border-color .15s} .list-search{width:100%;box-sizing:border-box;padding:8px 12px 8px 32px;background:var(--surface);border:1px solid var(--border2);border-radius:8px;color:var(--text1);font-size:13px;font-family:var(--font);outline:none;transition:border-color .15s}
.list-search:focus{border-color:var(--accent)} .list-search:focus{border-color:var(--accent)}
.list-search::placeholder{color:var(--text3)} .list-search::placeholder{color:var(--text3)}
#spotify-enrich-status{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--text2);padding:8px 12px;margin-bottom:8px;background:var(--surface);border:1px solid var(--border2);border-radius:8px;transition:opacity .4s}
#spotify-enrich-status.done{color:var(--accent)}
#spotify-enrich-status .enrich-spinner{width:12px;height:12px;border:2px solid var(--border2);border-top-color:var(--accent);border-radius:50%;animation:spin .7s linear infinite;flex-shrink:0}
.topsong-item{display:grid;grid-template-columns:28px 44px 1fr auto;align-items:center;gap:10px;padding:7px 10px;border-radius:8px;cursor:pointer;transition:background .15s} .topsong-item{display:grid;grid-template-columns:28px 44px 1fr auto;align-items:center;gap:10px;padding:7px 10px;border-radius:8px;cursor:pointer;transition:background .15s}
.topsong-item:hover{background:var(--surface)} .topsong-item:hover{background:var(--surface)}
.topsong-num{font-size:11px;color:var(--text3);font-family:var(--mono);text-align:center} .topsong-num{font-size:11px;color:var(--text3);font-family:var(--mono);text-align:center}