diff --git a/BACKLOG.md b/BACKLOG.md index 5c58653..09d68f7 100644 --- a/BACKLOG.md +++ b/BACKLOG.md @@ -20,7 +20,7 @@ bottom as they come up. - [x] Keyboard-shortcut help overlay (press `?`), listing space / arrows / f / m. - [x] Download/preload progress indicator on cards (percent or a bar, not just a pulse). - [x] Remember and restore the last playback position per video. -- [ ] Toast queue (stack multiple toasts instead of replacing). +- [x] Toast queue (stack multiple toasts instead of replacing). ## Features - [ ] Drag-to-reorder videos within a playlist. diff --git a/frontend/app.js b/frontend/app.js index 1baa0e6..7e042c1 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -109,12 +109,29 @@ function fmtTime(sec) { const mm = h ? String(m).padStart(2, '0') : String(m); return (h ? h + ':' : '') + mm + ':' + String(s).padStart(2, '0'); } -function toast(msg) { - const t = $('toast'); +function toast(msg, { duration = 2200 } = {}) { + const t = document.createElement('div'); + t.className = 'toast'; t.textContent = msg; - t.classList.remove('hidden'); - clearTimeout(toast._t); - toast._t = setTimeout(() => t.classList.add('hidden'), 2200); + const container = $('toastContainer'); + container.appendChild(t); + // Trigger layout for animation + t.style.animation = 'none'; + t.offsetHeight; // force reflow + t.style.animation = ''; + + // Auto-remove after duration + setTimeout(() => { + t.classList.add('toast-exit'); + setTimeout(() => t.remove(), 280); + }, duration); + + // Cap at 3 toasts — remove oldest + while (container.children.length > 3) { + const first = container.firstChild; + first.classList.add('toast-exit'); + setTimeout(() => first.remove(), 280); + } } function uid() { return Date.now().toString(36) + Math.random().toString(36).slice(2, 7); } function fmtBytes(n) { diff --git a/frontend/index.html b/frontend/index.html index 20a8b5a..d047b80 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -162,7 +162,7 @@ - +