From a89d97a1f3070639f71d73bef5d569446e3ba44b Mon Sep 17 00:00:00 2001 From: awsr <43862868+awsr@users.noreply.github.com> Date: Tue, 27 Jan 2026 13:23:33 -0800 Subject: [PATCH 01/14] Simplify message clearing --- javascript/gallery.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/javascript/gallery.js b/javascript/gallery.js index 54131386f..adec39527 100644 --- a/javascript/gallery.js +++ b/javascript/gallery.js @@ -998,7 +998,6 @@ async function thumbCacheCleanup(folder, imgCount, controller, force = false) { return; } const cb_clearMsg = showCleaningMsg(cleanupCount); - const tRun = Date.now(); // Doesn't need high resolution await idbFolderCleanup(staticGalleryHashes, folder, controller.signal) .then((delcount) => { const t1 = performance.now(); @@ -1012,10 +1011,7 @@ async function thumbCacheCleanup(folder, imgCount, controller, force = false) { } }) .finally(async () => { - // Ensure at least enough time to see that it's a message and not the UI breaking/flickering - await new Promise((resolve) => { - setTimeout(resolve, Math.min(1000, Math.max(1000 - (Date.now() - tRun), 0))); // Total display time of at least 1 second - }); + await new Promise((resolve) => { setTimeout(resolve, 1000); }); // Delay removal by 1 second to ensure at least minimum visibility cb_clearMsg(); }); }, From 22240b93b5330e1c59e655043be2b4fbe05aad41 Mon Sep 17 00:00:00 2001 From: awsr <43862868+awsr@users.noreply.github.com> Date: Tue, 27 Jan 2026 13:26:14 -0800 Subject: [PATCH 02/14] Abort handling helper in SimpleFunctionQueue --- javascript/gallery.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/javascript/gallery.js b/javascript/gallery.js index adec39527..0f431e18c 100644 --- a/javascript/gallery.js +++ b/javascript/gallery.js @@ -267,6 +267,14 @@ class SimpleFunctionQueue { this.#queue = []; } + static abortHandler(identifier, result) { + if (typeof result === 'string' || (result instanceof DOMException && result.name === 'AbortError')) { + log(identifier, result?.message || result); + } else { + error(identifier, result.message); + } + } + /** * @param {{ * signal: AbortSignal, @@ -1004,11 +1012,7 @@ async function thumbCacheCleanup(folder, imgCount, controller, force = false) { log(`Thumbnail DB cleanup: folder=${folder} kept=${staticGalleryHashes.size} deleted=${delcount} time=${Math.floor(t1 - t0)}ms`); }) .catch((reason) => { - if (typeof reason === 'string' || (reason instanceof DOMException && reason.name === 'AbortError')) { - log('Thumbnail DB cleanup:', reason?.message || reason); - } else { - error('Thumbnail DB cleanup:', reason.message); - } + SimpleFunctionQueue.abortHandler('Thumbnail DB cleanup:', reason); }) .finally(async () => { await new Promise((resolve) => { setTimeout(resolve, 1000); }); // Delay removal by 1 second to ensure at least minimum visibility From b0cd31a0cbd6e758983ed145411af895f2613157 Mon Sep 17 00:00:00 2001 From: awsr <43862868+awsr@users.noreply.github.com> Date: Tue, 27 Jan 2026 13:29:48 -0800 Subject: [PATCH 03/14] Formatting and names --- javascript/gallery.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/javascript/gallery.js b/javascript/gallery.js index 0f431e18c..121129c60 100644 --- a/javascript/gallery.js +++ b/javascript/gallery.js @@ -1022,7 +1022,7 @@ async function thumbCacheCleanup(folder, imgCount, controller, force = false) { }); } -function clearGalleryFolderCache(evt) { +function folderCleanupRunner(evt) { evt.preventDefault(); evt.stopPropagation(); if (!currentGalleryFolder) return; @@ -1045,9 +1045,9 @@ function addCacheClearLabel() { // Don't use async div.style.marginBlock = '0.75rem'; const span = document.createElement('span'); - span.style.cssText = 'font-weight:bold; text-decoration:underline; cursor:pointer; color:var(--color-blue); user-select: none;'; + span.style.cssText = 'font-weight: bold; text-decoration: underline; cursor: pointer; color: var(--color-blue); user-select: none;'; span.innerText = ''; + updateStatusWithSort('Thumbnail cache cleared'); + log('Thumbnail DB cleanup: Cache cleared'); + }) + .catch((e) => { + SimpleFunctionQueue.abortLogger('Thumbnail DB cleanup:', e); + }); + }, + }); + } +} + function folderCleanupRunner(evt) { evt.preventDefault(); evt.stopPropagation(); @@ -1212,6 +1236,16 @@ async function setOverlayAnimation() { document.head.append(busyAnimation); } +async function galleryClearInit() { + let galleryClearInitTimeout = 0; + const tryCleanupInit = setInterval(() => { + if (addCacheClearLabel() || galleryClearInitTimeout++ === 60) { + clearInterval(tryCleanupInit); + monitorOption('browser_cache', clearCacheIfDisabled); + } + }, 1000); +} + async function blockQueueUntilReady() { // Add block to maintenanceQueue until cache is ready maintenanceQueue.enqueue({ @@ -1243,6 +1277,7 @@ async function initGallery() { // triggered on gradio change to monitor when ui updateGalleryStyles(); injectGalleryStatusCSS(); setOverlayAnimation(); + galleryClearInit(); const progress = gradioApp().getElementById('tab-gallery-progress'); if (progress) { galleryProgressBar.attachTo(progress); @@ -1261,15 +1296,6 @@ async function initGallery() { // triggered on gradio change to monitor when ui monitorGalleries(); } -// Additional settings handling - -let galleryClearInitTimeout = 0; -const tryCleanupInit = setInterval(() => { - if (addCacheClearLabel() || ++galleryClearInitTimeout === 60) { - clearInterval(tryCleanupInit); - } -}, 1000); - // register on startup customElements.define('gallery-folder', GalleryFolder); diff --git a/javascript/indexdb.js b/javascript/indexdb.js index 1998597d8..1115137a4 100644 --- a/javascript/indexdb.js +++ b/javascript/indexdb.js @@ -208,6 +208,16 @@ async function idbFolderCleanup(keepSet, folder, signal) { }); } +async function idbClearAll(signal) { + if (!db) return null; + return new Promise((resolve, reject) => { + const transaction = db.transaction(['thumbs'], 'readwrite'); + const props = { transaction, signal, resolve, reject }; + configureTransactionAbort(props, null); + transaction.objectStore('thumbs').clear(); + }); +} + window.idbAdd = add; window.idbDel = del; window.idbGet = get; From 2925577ec2a80504790f2a9fc220d3e9734ae622 Mon Sep 17 00:00:00 2001 From: awsr <43862868+awsr@users.noreply.github.com> Date: Wed, 28 Jan 2026 20:43:00 -0800 Subject: [PATCH 11/14] Ensure message clear function always runs --- javascript/gallery.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/javascript/gallery.js b/javascript/gallery.js index 0054d69e8..0c5991d16 100644 --- a/javascript/gallery.js +++ b/javascript/gallery.js @@ -1037,7 +1037,6 @@ function clearCacheIfDisabled(browser_cache) { const cb_clearMsg = showCleaningMsg(0, true); await idbClearAll(controller.signal) .then(() => { - cb_clearMsg(); currentGalleryFolder = null; el.clearCacheFolder.innerText = ''; + updateStatusWithSort('Thumbnail cache cleared'); }) .catch((reason) => { SimpleFunctionQueue.abortLogger('Thumbnail DB cleanup:', reason); @@ -1034,18 +1037,20 @@ function clearCacheIfDisabled(browser_cache) { maintenanceQueue.enqueue({ signal: controller.signal, callback: async () => { + const t0 = performance.now(); const cb_clearMsg = showCleaningMsg(0, true); await idbClearAll(controller.signal) .then(() => { + log(`Thumbnail DB cleanup: Cache cleared. time=${Math.floor(performance.now() - t0)}ms`); currentGalleryFolder = null; el.clearCacheFolder.innerText = '