refactor(ui): harden the board's recenter dependency and gate it on a real bump
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 49s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m0s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 49s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m0s
The recenter effect declared its dependency with a bare `void recenter`, which a production minifier could drop as a side-effect-free statement (the e2e runs only the unminified dev server, so it would not catch that). Read the nonce into a used variable and gate the pan on it actually changing (`recentered`), so the reactive dependency is robust to minification and the board pans only on an explicit hint recenter — never on an incidental re-run such as a viewport resize.
This commit is contained in:
@@ -69,12 +69,16 @@
|
||||
// toggle or an explicit recenter request (the hint) moves it. A recenter with no zoom change
|
||||
// pans straight to `focus`, since the board width is stable and the width-driven tween below
|
||||
// has nothing to ride (the case the owner hit: a hint taken while already zoomed in).
|
||||
// The previous zoom state, to tell a zoom toggle from a recenter request. The board always mounts
|
||||
// zoomed-out, so it starts false and is updated to the live zoom on each effect run.
|
||||
// prevZoom/prevRecenter let the effect tell a zoom toggle from a recenter request. The board
|
||||
// always mounts zoomed-out, so prevZoom starts false; both are updated on each effect run.
|
||||
let prevZoom = false;
|
||||
let prevRecenter = 0;
|
||||
$effect(() => {
|
||||
const on = zoomed;
|
||||
void recenter; // re-run on an explicit recenter request even when the zoom state is unchanged
|
||||
// An explicit "scroll to focus now" request (the hint). Read into a variable that is USED below,
|
||||
// so the reactive dependency survives minification (a bare `void recenter` could be dropped) and
|
||||
// an incidental re-run never pans on its own.
|
||||
const rc = recenter;
|
||||
const vp = viewport;
|
||||
if (!vp) return;
|
||||
const f = untrack(() => focus);
|
||||
@@ -91,11 +95,13 @@
|
||||
finalST = Math.max(0, Math.min((f.row + 0.5) * cell - clientH / 2, fullW - clientH));
|
||||
}
|
||||
const toggled = on !== prevZoom;
|
||||
const recentered = rc !== prevRecenter;
|
||||
prevZoom = on;
|
||||
prevRecenter = rc;
|
||||
if (!toggled) {
|
||||
// No zoom change: an explicit recenter (the hint) pans straight to the focused word; a stale
|
||||
// run with nothing focused leaves the scroll alone.
|
||||
if (on && f) {
|
||||
// No zoom change: pan straight to the focused word only on an explicit recenter request (the
|
||||
// hint), never on an incidental re-run such as a viewport resize.
|
||||
if (recentered && on && f) {
|
||||
vp.scrollLeft = finalSL;
|
||||
vp.scrollTop = finalST;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user