Add download progress bar on card thumbnails

Replaces pulse-only state with a visible progress bar animation:
- Indeterminate bar slides across the bottom of card thumbnails during download
- markCardCacheState dynamically adds/removes the bar element
- renderCard includes the bar for newly rendered downloading cards
- Now-playing button already showed ' Saving…' state

Files:
- frontend/app.js: dl-progress in renderCard, markCardCacheState dynamic bar
- frontend/styles.css: .dl-progress, .dl-bar with dlSlide animation
This commit is contained in:
Jonathan Sykes
2026-06-14 14:23:52 +08:00
parent c676786144
commit 81aced9bc5
6 changed files with 37 additions and 3 deletions

View File

@@ -172,6 +172,16 @@ function markCardCacheState(id, state) {
document.querySelectorAll(`.card[data-id="${CSS.escape(id)}"]`).forEach((c) => {
c.classList.toggle('cached', state === 'cached');
c.classList.toggle('downloading', state === 'downloading');
const thumb = c.querySelector('.thumb');
if (state === 'downloading' && !thumb.querySelector('.dl-progress')) {
const bar = document.createElement('div');
bar.className = 'dl-progress';
bar.innerHTML = '<div class="dl-bar"></div>';
thumb.appendChild(bar);
} else if (state !== 'downloading') {
const bar = thumb.querySelector('.dl-progress');
if (bar) bar.remove();
}
});
}
@@ -802,13 +812,16 @@ async function renderSettings() {
function renderCard(v, index, list) {
const card = document.createElement('div');
card.className = 'card' + (cachedIds.has(v.id) ? ' cached' : '') + (downloading.has(v.id) ? ' downloading' : '');
const isCached = cachedIds.has(v.id);
const isDownloading = downloading.has(v.id);
card.className = 'card' + (isCached ? ' cached' : '') + (isDownloading ? ' downloading' : '');
card.dataset.id = v.id;
card.innerHTML = `
<div class="thumb">
<img loading="lazy" src="${v.thumbnail || ''}" alt="" />
${v.duration ? `<span class="dur">${fmtTime(v.duration)}</span>` : ''}
<span class="saved-badge" title="Saved offline">⬇</span>
<span class="saved-badge" title="${isDownloading ? 'Downloading…' : 'Saved offline'}">${isDownloading ? '' : '⬇'}</span>
${isDownloading ? '<div class="dl-progress"><div class="dl-bar"></div></div>' : ''}
</div>
<div class="card-info">
<div class="card-title"></div>