0b827ecfa3e6ecc31eddb0ef0a09d92fac0610a4
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2f34c36131 |
The room opens folded: the studio's panels and the catalogue's tree both start shut and come back the way they were left
Four asks, one shape: the LIGHT column had a chip that opened the same two
knobs DETAIL & EFFECTS already shows, the WB table was reading as one long
line per preset, the disclosure carets were too small to be the affordance
they are, and both folds — the studio's panels and the catalogue's folder tree
— opened fully every time. What the fold is for is the same in both places: a
column of a dozen controls is a wall to scroll past, and the control being
looked for is named by the head it sits under. So both open folded, and both
remember what was opened.
GRAIN's chip is gone from the LIGHT row. Its strip held a knob `grain` and the
"size" behind it, and both are rows of DETAIL & EFFECTS now — MONOCHROME GRAIN
and GRAIN SIZE — so the chip was a second way to one pair. The strip machinery
stays (`GroupKey 'grain'`, `groupDefs.grain`, `grainInch()`): it is reachable
from nothing today, and taking it out is a diff of its own. What went with the
chip is the `/INCH` readout, which only the strip drew.
The WB presets read as a name on one line and its kelvin under it: the label is
the chip's own label and the kelvin moved from the label into the value slot,
which the grid's rule stacks (`flex-direction: column`, `font-size: 11px`,
`white-space: nowrap`). Seven buttons, 147x39 each, name
box 14px — one line at 11px/1.25 — kelvin at 10px, `scrollWidth` equal to
`clientWidth` on every one of them. The kelvin rides a swatch, so it wears the
fill's own ink rather than the panel's dim grey (`.chip.tinted .val { color:
inherit }`): readableInk already picks #0b0e12 or #ffffff off that fill for
4.5:1, and dimming it a step costs contrast on a mid grey fill. Measured off
the running page: 4.88:1 (CLOUDY) to 5.00:1 (TUNGSTEN), name and kelvin alike.
The panels: `recipescam.develop.open` holds the slugs that are open, comma-
joined, and a slug no panel answers to is dropped on the way in, so a renamed
or removed panel leaves no hole. A visit that touches nothing writes nothing —
the column opens folded from an empty store — and a click on a head writes the
list as it stands. The caret is drawn a size up from the label it sits beside
(17px against an 11px head) and takes full opacity under the pointer, because
a line of uppercase does not read as a control on its own.
The tree: a row's click still opens it and folds it again, but the set it moves
in is inverted — what is *drawn open* rather than what is folded away — which
is what makes the state storable at all (a folded set is the whole tree minus
what is open, and the whole tree is not in that state to be stored). The
column opens with every folder shut, and the remembered set comes back over
it. A first visit under the new rule has no stored set and can still have a
folder remembered from before, so that one case seeds its ancestors: a screen
that opens on a node shrunk away behind a shut row is worse than a
remembered fold. COLLAPSE ALL folds the top-level row too now, which is what
makes it the way back to the column's rest — it was written when a top-level
row could not be folded, and the item is disabled when there is nothing open.
The caret is a leaf on a row with nothing under it, as it was.
`remember.ts` is the two functions both screens now share; Library had its own
copy of them.
The two checks that read these screens were wrong about the new fold and are
right about it now, not the other way round. `library-check` gains the rest
state (`the tree opens with the folders folded away — 1 rows`), walks the
tree a level per click, and reads the visit it left behind off a reload:
`lib-node-CheckRoll:true lib-node-CheckRoll/2026:true .../04:- .../Empty:-`,
with the screen marked on the subfolder. Two of its steps were stale
expectations rather than a fault: the fold-the-tree claim is one click over
four rows once the rows are opened for it, and the folder the screen reopens
on is the last row clicked, not the one clicked before it. `scan-nav-check`
asks the same tree for its deepest folder, so it opens the two rows above it
and folds them back — the reading it is watching does not move with rows.
Verified: `npx tsc --noEmit` clean, `npm run build` clean
(`dist/assets/index-T721P-Nv.js` 711.33 kB, `dist/assets/index-Co_dQD6t.css`
65.69 kB). `scripts/library-check.mjs` — "all checks passed", 55 steps, none
failing — including `the tree opens with the folders folded away — 1 rows,
aria-expanded=false`, `a row draws its own children, not the whole branch — 3
rows`, `and one click folds every row, leaving the frames where they were — 4
rows → 1, lib-node-CheckRoll:false, 2 tiles kept`, `the tree reopens with the
rows that were left open`, `the screen reopens on the folder it was left on —
lib-node-CheckRoll/2026`, `the screen reopens on the frame that was raised`,
and the column `198px, then 198px`. `scripts/scan-nav-check.mjs` — all steps
passed, its tree walk reading
`["lib-node-SlowRoll","lib-node-SlowRoll/2026","lib-node-SlowRoll/2026/04"]`.
In the running page: 5 panel heads and 0 panel bodies at rest with
`recipescam.develop.open` unset, caret `17px` `▸`; the WB table's seven rows
at 147x39 with name 14px one line, kelvin below at 10px, `nowrap`, no
overflow, ink 4.88–5.00:1; the LIGHT chip row `["auto","curve","fix",
"gradient-mask","mono","wb-temp:*","reset-all"]` — no `grp-grain` — with
MONOCHROME GRAIN and GRAIN SIZE still the two rows of DETAIL & EFFECTS; two
heads opened, `wb,effects` stored, and the same two open after a reload with
the other three shut. The deployed bundle was read too: `docker compose build
frontend && docker compose up -d frontend`, and `index-DpYWAhJ3.js` off
`127.0.0.1:8090` carries `recipescam.develop.open` and
`recipescam.library.open` and no `grp-grain`, with the same probe readings
taken against it.
Co-authored-by: PenguinHarness <noreply@penguin.local>
|
||
|
|
426488a788 |
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
|
||
|
|
1cb2618fd7 |
web: count a roll as it is read, and open a frame without losing the count
Two holes left by the last change. A frame is opened with `window.location.href` rather than a link, so the studio was still handed a fresh page and the scan with it — every route out of the catalogue now goes through `go()`, which pushes the address instead of reloading while a scan is in flight. And a row counted what was filed away rather than what had been read, so it sat at zero for the whole of a first scan: the catalogue's frames only reach IndexedDB in one batch at the end. `ScanProgress.counts` carries the frames the scan has reached, per row, off the scan's own bookkeeping, and the column reads it while the scan runs — the row under the reader's eye moves as the roll is read, and the toolbar's line stays the whole picture. A re-read counts from the start, which is what it is doing. The regression check grows the two: a frame opened mid-scan from the catalogue (of a roll it already holds) has to stay in the page, and the row has to count. |
||
|
|
79b0d0db86 |
web: keep reading a roll while the studio is up
The catalogue hands the visitor to the studio with a plain `<a href>`, and the app has no router: following it threw the page away, so a scan that was halfway through a roll died with it. A scan belongs to the tab, not to the screen that started it. The scan now lives outside the component (`scanSession`/`startScan`/`stopScan`, watched by whoever is up), so the catalogue can unmount and come back to a reading that never stopped; a screen that returns joins it and sees the toolbar line, the stop button and the rows filling in. The internal links are taken over for a history push *only while a scan is in flight* — everywhere else the browser navigates exactly as before, so the landing-to-studio flow is untouched. `scripts/scan-nav-check.mjs` is the regression: a roll read one frame at a time off a slow server, handed to the studio mid-scan, back to the catalogue, and the whole roll read to the end with the studio up, counting documents along the way. |