Replace single toast with stacked toast queue
Multiple toasts can appear simultaneously, capped at 3. Oldest toast auto-evicts when cap is reached. Each toast auto-dismisses with a fade-up exit animation. - frontend/app.js: toast() now creates DOM elements in toastContainer - frontend/index.html: single #toast replaced with #toastContainer - frontend/styles.css: .toast-container flexbox row, .toast-exit animation
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user