studio: say the roll is still being read while the catalogue is off screen

The reading of a folder belongs to the tab, not to the catalogue screen: it was
made to survive the hand-over to the studio in 753eea0, and it does. What was
missing was any sign of it up there — a visitor who hands a half-read roll to the
studio saw a page that said nothing about the frames still landing, and had no
way to tell a reading in flight from one that had quietly died. The one thing
that did say so, the toolbar line, lived on the screen they had just left.

The header now carries it, immediately left of the way back into the catalogue,
where the two belong together: the ring the catalogue already uses for a roll in
hand, and the count the toolbar states, "4/12", whose title is the same
"Scanning 4/12 — 0 new…" line in the visitor's language. It reads the session
through scanSession() and watches it with watchScan() exactly as the catalogue
does, so a pass that moves the progress moves the header too — the session object
outlives them both, only its progress is replaced each pass. No new state is
introduced, no new copy: the markup borrows .lib-spin and the lib.scanning key
the catalogue already had.

Verified: tsc --noEmit and vite build clean; scripts/scan-nav-check.mjs grew one
step at the first hand-over, "the studio header shows the reading the tab is
doing", which waits for [data-key="studio-scan-count"] mid-scan and matches it
against \d+/\d+ — it passes with 4/12, the same reading the toolbar shows at that
moment; the other 18 steps of that check, the 52 steps of library-check.mjs and
roll-walk-check.mjs all still pass.

ponytail: the header states progress, it does not offer to stop the scan; the
catalogue's own STOP stays the one place that ends a reading. Add a control here
when someone asks to stop a roll from the studio.

Co-authored-by: PenguinHarness <noreply@penguin.local>
This commit is contained in:
2026-09-29 10:55:07 +07:00
parent 53cb1c97e9
commit 426488a788
3 changed files with 36 additions and 1 deletions
@@ -209,6 +209,13 @@ await page.click('[data-key="lib-studio"]');
await page.waitForSelector('[data-key="nav-library"]', { timeout: 15_000 });
step('the handover stays in the page, it does not reload it', await noReload(), `${await docs()} document load(s)`);
step('and it lands in the studio', new URL(page.url()).pathname === '/app', page.url());
// The reading belongs to the tab, so the header of the screen that did not start
// it says it is still going, beside the way back into the catalogue.
const badge = await page
.waitForSelector('[data-key="studio-scan-count"]', { timeout: 15_000 })
.then((el) => el.textContent())
.catch(() => null);
step('the studio header shows the reading the tab is doing', /^\d+\/\d+$/.test(badge ?? ''), String(badge));
// Back to the catalogue mid-scan: the screen that started the scan is gone and
// back, and the roll is still being read — the reading belongs to the tab.