fix: v1.5.1 — UX bug-fix pass (20 verified defects from a six-dimension frontend review) - #29
Merged
Merged
Conversation
Six parallel review dimensions (input pipeline, select, text, camera/render, UI chrome/keyboard, undo/persistence); every finding traced end-to-end before fixing. Headliners: - window resize / DPR change blanked or blurred the board (canvas bitmap wipe with no dirty-mark; DPR now tracked via re-armed matchMedia) — setupCanvas gains an onResize contract - pointer router gains single-owner pointerId gating (stray second touch corrupted strokes; stray pointerup committed gestures early) - wheel deltaMode normalized (Firefox line-mode pan/zoom crawled) - line/arrow selection handles reduced to the two true endpoints via shared enabledHandles() (six bogus handles teleported endpoints) - text measurement cache invalidation folded into resizeToFit (edited texts rendered pre-edit glyphs until undo/reload); rotated texts get a rotated editor overlay; Cmd+B/I on selected text refits its box - editable-target guards centralized in editable.ts with two tiers (typing 'e'/Space in inputs hijacked eraser/pan; focused sliders killed every shortcut) - destructive toasts focus Cancel and disarm on Esc/panel dismiss (stray Enter could factory-reset; orphaned armed toast confirmed silently) - in-progress text edits flush on pagehide/beforeunload; persistence failures surface a once-per-session toast; laser taps draw a fading dot; pen/eraser ghost cursor cleared via new Tool.onPointerLeave; Shift+tap keeps selections; '?' gains a repeat guard; Escape respects IME composition +9 unit tests (283 total); e2e smoke suite passes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CI's high-severity audit gate (bun audit) failed on the vite server.fs.deny Windows bypass advisory. Lockfile-only bump within the existing ^8.0.13 range; the bun.lock change also rotates the e2e job's Playwright browser-cache key, replacing the stale June cache that was missing chromium_headless_shell-1223. Verified locally: audit clean, typecheck, 283 unit tests, 6/6 e2e against the vite 8.1.5 production build. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nstalls `bun update vite` injected a spurious root vite dependency entry into bun.lock that validated against a warm local cache but failed `bun install --frozen-lockfile` on every cold CI install (lint/test, e2e, Docker). Regenerated via a cold `bun install` in a fresh clone; vite stays at 8.1.5, audit stays clean, frozen install verified cold. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`bunx playwright install` at the repo root doesn't resolve the e2e workspace's bin (it lives in apps/e2e/node_modules/.bin, not hoisted), so bunx silently downloaded the LATEST playwright and installed that version's browser builds — while the pinned 1.60.0 test runner looks for chromium_headless_shell-1223. The drift was masked while latest ≈ 1.60 and the browser cache was warm; the June cache expired (7-day eviction) and latest moved on, so every fresh install produced mismatched browsers. New `install-browsers` package script runs the workspace-pinned playwright deterministically. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A six-dimension parallel frontend review (input pipeline, select tool, text tool, camera/render, UI chrome/keyboard, undo/persistence) surfaced twenty verified UX defects; every finding was traced end-to-end in code before fixing. Full details in the CHANGELOG entry this PR closes as v1.5.1.
Headliners
setupCanvasnow owns anonResizerepaint contract, and DPR changes (monitor drags that fire noresize) are tracked via a re-armedmatchMedialistener.pointerupfrom an unrelated pointer prematurely committed the gesture.enabledHandles()used by renderer + hit-test.resizeToFit, the shared refit chokepoint.editable.ts, two tiers) — typinge/Space into inputs hijacked eraser/pan; focused sliders killed every shortcut including Esc.Tool.onPointerLeavehook, Shift+tap keeps selections, rotated-text editor overlay, Cmd+B refit,?repeat guard, IME-safe Escape.Architectural chokepoints introduced
editable.tsguards ·setupCanvas(parent, onResize?)·Tool.onPointerLeave?(ctx)·enabledHandles(view)· invalidate-inside-resizeToFit— each fix that came from "two hand-maintained copies drifted" got a single source of truth so the class can't recur.Test plan
bun run typecheck— clean across all workspacesbun test— 283/283 (+9 new: eraser-hold guard, pointer single-owner gating, laser tap fade)bun run test:e2e— 6/6 Playwright smoke tests against the production buildbun run lint/ production build — cleanCloses CHANGELOG
[Unreleased]→ v1.5.1; tag to follow after merge.🤖 Generated with Claude Code