From d48d51bdc3a330f2c7871eb2638c0c22e3234a7d Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Thu, 22 Jan 2026 09:36:12 -0700 Subject: [PATCH] feat: Display 'All uploads complete' banner on finish Co-authored-by: aider (gemini/gemini-2.5-pro) --- frontend/app.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/frontend/app.js b/frontend/app.js index cbaf6ba..6e6e94a 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -34,6 +34,7 @@ try { } catch {} let items = []; let socket; +let allCompleteBannerShown = false; // Status precedence: never regress (e.g., uploading -> done shouldn't go back to uploading) const STATUS_ORDER = { queued: 0, checking: 1, uploading: 2, duplicate: 3, done: 3, error: 4 }; @@ -92,6 +93,7 @@ function addItem(file, relativePath){ const resolvedPath = (relativePath !== undefined) ? relativePath : (file.webkitRelativePath || ''); const it = { id, file, name: file.name, size: file.size, status: 'queued', progress: 0, relativePath: resolvedPath }; items.unshift(it); + allCompleteBannerShown = false; render(); } @@ -155,6 +157,15 @@ function render(){ document.getElementById('countDone').textContent=c.done; document.getElementById('countDup').textContent=c.dup; document.getElementById('countErr').textContent=c.err; + + if (!allCompleteBannerShown && items.length > 0) { + const isComplete = items.every(it => FINAL_STATES.has(it.status)); + const hasSuccess = items.some(it => it.status === 'done' || it.status === 'duplicate'); + if (isComplete && hasSuccess) { + showBanner("All uploads complete.", "ok"); + allCompleteBannerShown = true; + } + } } // --- WebSocket progress ---