From d86b6344044f32fdbdca211653f2e73c7e407e29 Mon Sep 17 00:00:00 2001 From: 3dtours Date: Thu, 8 Oct 2026 20:08:19 +0700 Subject: [PATCH] fix: realtime folder photo counts during scan discovery and decode --- docker/frontend/src/engine/library.ts | 29 ++++++++++++++++++++++---- docker/frontend/src/engine/rollWalk.ts | 7 +++++-- docker/recipescam-images.tar.gz.sha256 | 2 +- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/docker/frontend/src/engine/library.ts b/docker/frontend/src/engine/library.ts index 9f90f02..138ea29 100644 --- a/docker/frontend/src/engine/library.ts +++ b/docker/frontend/src/engine/library.ts @@ -809,6 +809,17 @@ export async function scanFolder( } }; for (const id of known.keys()) count(id.startsWith(`${normRoot}/`) ? id.slice(normRoot.length + 1) : id); + const knownPaths = new Set( + [...known.keys()].map((id) => (id.startsWith(`${normRoot}/`) ? id.slice(normRoot.length + 1) : id)) + ); + const countedDiscovered = new Set(); + const countDiscovered = (rel: string) => { + const relClean = rel.replace(/\\/g, '/'); + if (knownPaths.has(relClean) || countedDiscovered.has(relClean)) return; + countedDiscovered.add(relClean); + count(relClean); + }; + for (const e of entries) countDiscovered(e.rel); // The frames the catalogue already holds of the folder being read, which is // what the reading is measured against: a roll of a hundred thousand that has // been read once before is a reading of a hundred thousand frames even while @@ -1036,10 +1047,20 @@ export async function scanFolder( // through. A jump would take it out of the subtree it was kept to, and // the reading it left behind is the reading that folder wanted. const asked = bounded ? () => null : (jump ?? (() => null)); - walked = await walkPass(tree, entries, names, isSupportedPhoto, asked, (dirRel) => { - progress.at = normPath(dirRel); - publish(true); - }); + walked = await walkPass( + tree, + entries, + names, + isSupportedPhoto, + asked, + (dirRel) => { + progress.at = normPath(dirRel); + publish(true); + }, + (file) => { + countDiscovered(file.rel); + } + ); // The names come in before the frames they hold: the column grows one pass // ahead of the strip, which is the whole point of reading layer by layer. for (const rel of names) { diff --git a/docker/frontend/src/engine/rollWalk.ts b/docker/frontend/src/engine/rollWalk.ts index 9fb7b92..df4804d 100644 --- a/docker/frontend/src/engine/rollWalk.ts +++ b/docker/frontend/src/engine/rollWalk.ts @@ -88,7 +88,8 @@ export async function walkPass( seen: string[], keep: (name: string) => boolean, jump: () => string | null, - onDir?: (rel: string) => void + onDir?: (rel: string) => void, + onFile?: (file: WalkFile) => void ): Promise { for (let i = 0; i < DIRS_PER_PASS && walk.pending.length; i++) { await jumpQueue(walk, jump()); @@ -107,7 +108,9 @@ export async function walkPass( walk.pending.push({ dir: entry as FileSystemDirectoryHandle, rel }); seen.push(rel); } else if (keep(entry.name)) { - out.push({ handle: entry as FileSystemFileHandle, rel: `${baseRel}${entry.name}` }); + const file: WalkFile = { handle: entry as FileSystemFileHandle, rel: `${baseRel}${entry.name}` }; + out.push(file); + onFile?.(file); } } } catch { diff --git a/docker/recipescam-images.tar.gz.sha256 b/docker/recipescam-images.tar.gz.sha256 index ddb342f..05b553e 100644 --- a/docker/recipescam-images.tar.gz.sha256 +++ b/docker/recipescam-images.tar.gz.sha256 @@ -1 +1 @@ -3e9a0f2173ec2dd5df1d1d6b3925ce16ac637e82746a316cc90cf35a82fb2c14 recipescam-images.tar.gz +d01beb3a629be66f3e70b82a325b26c92dd620e79a41de3ab73a578781f5bf45 recipescam-images.tar.gz