From c80c8729a81957c6b2d8c9a177c62bac646d66af Mon Sep 17 00:00:00 2001 From: 3dtours Date: Wed, 7 Oct 2026 23:10:21 +0700 Subject: [PATCH] fix(library): mark only the folder a reading stands in, and keep a one-folder reading out of the roll's count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The column's ring was drawn from the open node's roll: a row of another roll had no path under it, so the empty prefix matched every row of the roll being read and the whole column lit up. The roll's own row was marked too, at every moment of a reading of it, and a reading kept to one folder counted its frames onto the roll's row as well — a roll counted down to one branch of itself. A queued request was drawn from the reading's roll instead of its own, so a request on a second roll showed nothing at all. --- docker/frontend/src/Library.tsx | 36 +++++++++++++++++++++------ docker/frontend/src/engine/library.ts | 8 +++++- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/docker/frontend/src/Library.tsx b/docker/frontend/src/Library.tsx index ea16806..c587118 100644 --- a/docker/frontend/src/Library.tsx +++ b/docker/frontend/src/Library.tsx @@ -1656,14 +1656,34 @@ function Catalogue() { // left bare, and the toolbar's line is what carries them. const isScanFolderMatch = !!(live && folder && normPath(live.folder) === normPath(folder.name)); const scanAt = live?.progress.at ? normPath(live.progress.at) : ''; - const nodeRel = (relOf(n.key) ?? '').replace(/\/$/, ''); - const scanning = isScanFolderMatch && ( - n.depth === 0 ? true : (scanAt === nodeRel || scanAt.startsWith(nodeRel ? `${nodeRel}/` : '')) - ); - const waiting = !scanning && isScanFolderMatch && scanQueue().some((j) => { - const qRel = (j.rel ?? '').replace(/\/$/, ''); - return qRel === nodeRel || qRel.startsWith(nodeRel ? `${nodeRel}/` : ''); - }); + // The row's own path under its own roll, spelled the way the + // walk spells one. Not `relOf`, which answers for the open + // node's roll alone: a reading of another roll draws its ring + // on that roll's rows too, and those rows still have to say + // where it stands. + const normFolder = folder ? normPath(folder.name) : ''; + const nodeRel = + n.depth === 0 || !normFolder || !n.key.startsWith(`${normFolder}/`) + ? '' + : n.key.slice(normFolder.length + 1); + const scanning = + isScanFolderMatch && + n.depth > 0 && + nodeRel !== '' && + (scanAt === nodeRel || scanAt.startsWith(`${nodeRel}/`)); + // What is waiting its turn is waiting on the row it was asked + // of, and on every row above it: a request under a folded + // branch still says the roll has work queued. The roll's own + // row says nothing, for the reason it says nothing of the + // reading — and a request belongs to the roll it was asked + // of, so another roll's queue is not this row's news. + const waiting = + !scanning && + n.depth > 0 && + nodeRel !== '' && + scanQueue().some( + (j) => j.folder === folder?.name && (j.rel === `${nodeRel}/` || j.rel.startsWith(`${nodeRel}/`)) + ); const under = parents.has(n.key); return (