diff --git a/docker/frontend/src/Library.tsx b/docker/frontend/src/Library.tsx index 6859f7a..eeffd43 100644 --- a/docker/frontend/src/Library.tsx +++ b/docker/frontend/src/Library.tsx @@ -1091,7 +1091,9 @@ function Catalogue() { } const markOf = (folderName: string, rel: string, at: string): Mark => { const root = normPath(folderName); - const here = normPath(at || rel); + const cleanRel = (rel || '').replace(/\\/g, '/').replace(/^\/+/, '').replace(/\/$/, ''); + const cleanAt = (at || '').replace(/\\/g, '/').replace(/^\/+/, '').replace(/\/$/, ''); + const here = normPath(cleanAt || cleanRel); return { root, own: here ? `${root}/${here}` : root }; }; const liveMark = live ? markOf(live.folder, live.progress.from, live.progress.at) : null; @@ -1099,11 +1101,13 @@ function Catalogue() { // so it marks the folder it was asked of. const askedMarks = scanQueue().map((j) => markOf(j.folder, j.rel, '')); const wearsMark = (n: Node, m: Mark): boolean => { - const nKey = normPath(n.key); + const nKey = normPath(n.key).toLowerCase(); + const mRoot = normPath(m.root).toLowerCase(); + const mOwn = normPath(m.own).toLowerCase(); // Another roll's rows are neither the reading's nor the request's news. - if (nKey !== m.root && !nKey.startsWith(`${m.root}/`)) return false; + if (nKey !== mRoot && !nKey.startsWith(`${mRoot}/`)) return false; // The active scanning row itself, and every parent/ancestor row up to root. - return nKey === m.own || m.own.startsWith(`${nKey}/`); + return nKey === mOwn || mOwn.startsWith(`${nKey}/`); }; // A remembered subfolder that no longer holds a frame falls back to the folder diff --git a/docker/frontend/src/engine/library.ts b/docker/frontend/src/engine/library.ts index e5c39cd..b28e8f8 100644 --- a/docker/frontend/src/engine/library.ts +++ b/docker/frontend/src/engine/library.ts @@ -1034,7 +1034,10 @@ 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); + walked = await walkPass(tree, entries, names, isSupportedPhoto, asked, (dirRel) => { + progress.at = normPath(dirRel); + publish(true); + }); // 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 867be5d..9fb7b92 100644 --- a/docker/frontend/src/engine/rollWalk.ts +++ b/docker/frontend/src/engine/rollWalk.ts @@ -87,11 +87,13 @@ export async function walkPass( out: WalkFile[], seen: string[], keep: (name: string) => boolean, - jump: () => string | null + jump: () => string | null, + onDir?: (rel: string) => void ): Promise { for (let i = 0; i < DIRS_PER_PASS && walk.pending.length; i++) { await jumpQueue(walk, jump()); const here = walk.pending.shift()!; + onDir?.(here.rel); // A folder opened by a click is still in the queue its parent filled: it is // read once, in the place the click put it. if (walk.walked.has(here.rel)) continue; diff --git a/docker/recipescam-images.tar.gz.sha256 b/docker/recipescam-images.tar.gz.sha256 index b1ca16d..a343021 100644 --- a/docker/recipescam-images.tar.gz.sha256 +++ b/docker/recipescam-images.tar.gz.sha256 @@ -1 +1 @@ -6f46a29f988ade2397de4de014e53fec3aeb745e0798dbc7be86f03940a8e685 recipescam-images.tar.gz +431247d71c50662a2ee41d5d418c2966fc8a8496ea0a7f0909014916e0accd1a recipescam-images.tar.gz