fix(library): stop calling a .tif a RAW, and stop the wall's render loop

Three things, all from one look at a folder of TIFF scans.

A `.tif` is no longer a RAW. Nothing here develops one, and `tif`/`tiff` sat in
`RAW_EXT` for no decoder's sake: opening a TIFF asked for PRO and its tile wore
a RAW badge, for a file the engine has nothing to hand back. Both extensions
are dropped, and a TIFF keeps its own route instead — the tile reads the file's
own pixels (`useThumbUrls`, via `tiffDevelop`) and so does the studio — so a
`.tif` still opens and still draws, it just is not a RAW any more.

The wall's render loop. `painted` was a fresh `.slice()` on every render, so
`useThumbUrls` saw a new list each time round and its effect ran again, and
again: about twenty thousand renders a second while the page sat idle, and the
file reads frozen at the first screenful, so a tile scrolled to never came up
(7 of 24 cards drawn). `painted` is memoised on `listed, wall.from, wall.to`
now — no date formats in eight idle seconds, 28 of 28 cards after a scroll.

Scrolling between the two modes. SINGLE → ALL THUMBS lands the wall on the
frame the strip was showing, centred in the window; ALL THUMBS → SINGLE swipes
the strip to the frame nearest the wall's middle, centred in the row. Each way
the frame the other mode was standing on is the one you come back to.
This commit is contained in:
2026-10-09 16:12:18 +07:00
parent 6e11da7e9a
commit 88d97432bd
4 changed files with 169 additions and 39 deletions
+2 -2
View File
@@ -14,7 +14,7 @@
// smart collections) that hand-rolled cursors would make ugly.
import type { Recipe } from '../../shared/types';
import { readCapturedAt } from './imageOps';
import { isRawName } from './rawDevelop';
import { isRawName, isTiffName } from './rawDevelop';
import { isHeicName } from './heicDevelop';
import { openAt, walkPass, type Walk, type WalkFile } from './rollWalk';
@@ -1242,7 +1242,7 @@ export async function scanFolder(
// RAW whose date sits deeper is read once more before the clock on the file
// has to do. The tile is the wall's business — one is made when one is drawn
// and not before — see `makeTile`.
const rawish = isRawName(file.name) || /\.(tiff?)$/i.test(file.name) || isHeicName(file.name);
const rawish = isRawName(file.name) || isTiffName(file.name) || isHeicName(file.name);
const bytes = new Uint8Array(await file.slice(0, Math.min(file.size, HEAD_BYTES)).arrayBuffer());
let taken = await readCapturedAt(bytes);
if (taken === null && rawish && file.size > HEAD_BYTES) {