fix(library): mark the roll's own row while it is read, and count rows from the catalogue up

This commit is contained in:
2026-10-08 08:05:18 +07:00
parent ac0337147f
commit 3242b3aa48
2 changed files with 33 additions and 30 deletions
+19 -15
View File
@@ -786,28 +786,28 @@ export async function scanFolder(
progress.written ??= 0;
progress.at ??= '';
const found = new Set(progress.dirs.map((d) => d.id));
const counts: Record<string, number> = progress.counts;
// Count the frame the moment the scan gets to it, before it knows whether the
// frame is new: the rows say how far the reading has come, not what it kept.
const count = (rel: string) => {
const normRoot = normPath(folder.name);
// The rows are counted from what the catalogue already holds, and the reading
// only adds to them. A number that started at nothing would sit under the
// catalogue's own for as long as the reading took to pass it, and the screen
// shows the larger of the two — so an update, where the reading is mostly
// frames the catalogue has, is a number that stands still and then jumps. What
// the reading adds is the frames it found that the catalogue does not hold yet:
// the number climbs for news alone, and ends on the true total.
const counts: Record<string, number> = {};
const count = (rel: string, n = 1) => {
const relNorm = rel.replace(/\\/g, '/');
const cut = relNorm.lastIndexOf('/');
const normRoot = normPath(folder.name);
// A reading kept to one folder says nothing about the roll it sits in: the
// roll's own row counts every frame of the roll, and a number that counted
// one branch of it would count the roll down to that branch. Its own frames
// are outside the reading anyway — a bounded walk starts at `from`, so every
// frame it reaches is under it, and the roll's row keeps the catalogue's
// number until the reading is through and the catalogue is read back.
if (!bounded) counts[normRoot] = (counts[normRoot] ?? 0) + 1;
counts[normRoot] = (counts[normRoot] ?? 0) + n;
let path = '';
for (const part of (cut < 0 ? '' : relNorm.slice(0, cut)).split('/')) {
if (!part) continue;
path = path ? `${path}/${part}` : part;
const key = `${normRoot}/${path}`;
counts[key] = (counts[key] ?? 0) + 1;
counts[key] = (counts[key] ?? 0) + n;
}
};
for (const id of known.keys()) count(id.startsWith(`${normRoot}/`) ? id.slice(normRoot.length + 1) : id);
// 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
@@ -984,7 +984,12 @@ export async function scanFolder(
addedAt: seen?.addedAt ?? Date.now(),
};
batch.push(row);
if (!seen) added.push(row);
if (!seen) {
added.push(row);
// A frame the catalogue did not hold is news the rows have to show: it is
// the one thing an update adds to a number the catalogue already set.
count(rel);
}
progress.added++;
inHand = inHand.filter((r) => r !== rel);
if (batch.length >= BATCH) await flush();
@@ -1013,7 +1018,6 @@ export async function scanFolder(
const at = rel.lastIndexOf('/');
progress.at = at < 0 ? '' : rel.slice(0, at);
progress.done++;
count(rel);
const read = readOne(handle, rel);
const lane = read
.catch(() => undefined)