The lazy editor (Exp A) unmounts on exit, so the editor's own deferred
focus-return (useReactiveTextInput) targeted a detached node and focus was
lost to <body>, breaking table keyboard navigation after submit/escape.
Return focus to the parent cell deterministically in a layout effect once the
display element is back in the DOM (rather than a setTimeout that races the
next keypress), mirroring the time/duration cells.
Update the e2e tests to the lazy interaction model (click the cell to open the
on-demand editor, assert it unmounts on exit) — matching the existing timer
cell test. Verified end-to-end: 202-cuesheet (3/3) and 206-url-preset (5/5).
The metrics scaffold has served its purpose: it proved the lazy text-cell
editor change (Exp A) and ruled out the colour-precompute and lazy-autosize
candidates. Removing it entirely:
- restores AutoTextarea/Tooltip/useReactiveTextInput/EventRow/CuesheetTable
to their original (uninstrumented) form
- deletes common/devtools/cuesheet-metrics
Keeps the validated Exp A optimization (lazy editor mounting). Verified:
typecheck, lint, 181 unit tests, and production build all pass; no scaffold
references remain in the bundle.
Render a lightweight, focusable TextLikeInput for cue/title/note/custom cells
and only mount the real input/textarea editor (with reactive-input hooks and
autosize) on click/focus, mirroring the existing time/duration cells.
Measured baseline vs Exp A at CPU 4x (median of 3, ~1140 row mounts):
- longFrames 201 -> 127 (-37%), maxFrameMs 517 -> 417 (-19%)
- longtask total 58.9s -> 30.7s (-48%), EventRow.mount avg 179 -> 146ms (-18%)
- cell.autosize and cell.reactiveInputInit eliminated from the scroll path
- per-row re-renders 4648 -> 3048 (-34%): stable display height, no virtuoso churn
(the opposite of the reverted lazy-autosize Exp B, which doubled re-renders)
Editing verified end-to-end: click mounts+focuses the editor, edits persist,
editor unmounts back to the display on commit. TextLikeInput now fills its cell
so the whole cell is clickable to edit.
- Scaffold: snapshot()/getResults() so the benchmark returns structured
metrics for automated before/after capture (PERF-METRICS).
- Candidate Exp B: defer AutoTextarea autosize() off the mount path to
focus-time, removing the per-row forced reflows during scroll. Under
evaluation against the metrics.
Adds a dev-only, self-contained instrumentation module under
common/devtools/cuesheet-metrics to measure the first-render (mount) cost
of virtualised cuesheet rows, so scroll-performance changes can be backed
by before/after numbers.
- Console-only API on window.__cuesheetPerf (deterministic scroll benchmark
+ manual start/stop), gated by isDev && ?perf=1, runtime-inert in prod.
- Whole-row mount probe plus per-subsystem attribution: colour calc,
getVisibleCells, AutoTextarea autosize, Tooltip portal mount,
useReactiveTextInput hotkey-handler init; FPS/long-frame timing.
- All edits to existing files tagged // PERF-METRICS for a one-pass teardown.
Temporary: to be deleted once the optimizations are proven.
* refactor: allow secondary rundowns
* ui: move dropdown
* feat: follow loaded
* ui: background edit warning
ui: fix disable radio button
* feat(ui): add loaded sufix in the rundown list
* feat(ui): add direct link to background edit from rundown manager
* fix: better fallback
* fix: default to is isCurrentRundown for nav bar colour
* chore: rename navigate to cuesheet
---------
Co-authored-by: alex-arc <ac@omnivox.dk>
Adds timer-legacy.html — a zero-dependency static page that connects
to the Ontime WebSocket and displays the live countdown for browsers
that cannot parse the Vite-built React bundle (Safari < 14, Chrome < 85).
Also adds a synchronous pre-React guard in index.html that redirects
/timer visitors to the legacy page when Promise.any is unavailable,
matching the Vite build target floor of Safari 14 / Chrome 85.
https://claude.ai/code/session_013MfdwdjdDUnr3akpGSGXa4
* feat: update auto cue numbering
* feat: renumber from ui
* refactor: patchEntries is not used
* chore: format
* fix: correct cue at top of group
* fix: handle precision
* refactor dialog
* bump limit for performance time test
* extract type
* add class name to lable
* fix rebase
* refator: extract renumering logic
* chore: comments for getIntegerAndFraction function
* chore: add the for renumber mutation
* fix: fraction match precision
* refactor: small cleanup
* refactor: use more narrow validator
---------
Co-authored-by: alex-Arc <omnivox@LAPTOP-RC5SNBVV.localdomain>
* refactor: remove unneeded async
* chore: add express Router type to all routes
* refactor: don't use index in react key
* refactor: correctly get error message in excel route
* refactor: avoid exporting muteable values
* refactor: replace traslation hook refetch time with stale time
* refactor: make it the service responsebillety to send refetch keys for asset changes