Skip to content

feat(inspector): pick the zoom level from a row of buttons - #694

Open
My-Denia wants to merge 1 commit into
getopenscreen:mainfrom
My-Denia:feat/670-zoom-level-buttons-clean
Open

My-Denia wants to merge 1 commit into
getopenscreen:mainfrom
My-Denia:feat/670-zoom-level-buttons-clean

Conversation

@My-Denia

@My-Denia My-Denia commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Replace the Zoom Level select in the floating zoom inspector with six always-visible level buttons. The six ZOOM_DEPTH_SCALES values stay on one row, the current level is aria-pressed, and the row is a labelled role="group".

Every button is a Tab stop. Click picks a level in one step. Enter and Space activate the focused button. Arrow keys step from the focused button and clamp at both ends. Those keys stay inside the control so the editor shell's seek/play shortcuts do not also handle them. Re-selecting the already requested level is a no-op.

Rapid clicks need ordered zoom-pane writes. Each level change is a whole-document save, so two saves built from the same render can land out of order. The zoom pane's one-field setters (level, 3D tilt, focus mode, hide cursor) share a small chain in useTimeline that reads the committed document inside the queued task. updateZoomDepth returns whether the save took effect, so a failed level can be retried. The control tracks each request by generation, so a late superseded settlement, a region switch, or an external undo cannot leave a stale requested level.

No zoom math, schema, renderer semantics, or unrelated timeline writers change.

Related issue

Fixes #670

Type of change

  • Bug fix
  • Feature
  • Enhancement
  • Documentation
  • Refactor / maintenance
  • Performance
  • Security

Release impact

  • Patch
  • Minor
  • Major / breaking change
  • No release note needed

Desktop impact

  • Windows
  • macOS
  • Linux
  • Installer / packaging
  • Not platform-specific

Renderer/timeline-store change only.

Screenshots / video

Before:

Zoom Level dropdown

After:

Zoom Level buttons

Six always-visible buttons on one row, current level pressed. Layout is covered by the v4-shell e2e case at the editor's 300px inspector width (one row, labels not clipped).

Testing

  • npx vitest --run src/components/ai-edition/v4/ZoomLevelControl.test.tsx src/lib/ai-edition/store/useTimeline.test.ts src/lib/ai-edition/store/documentWriteAudit.test.ts
    • ZoomLevelControl: six labelled buttons, aria-pressed, one-click commit, current-level no-op, arrows from the focused button, bounds, shell shortcut isolation, Enter/Space not cancelled, rapid in-flight steps, superseded and repeated-depth requests, region switch, undo after requests settle, retry after a failed save.
    • useTimeline: rapid level steps land in order with one undo step each; a 3D-tilt change keeps a pending level; a failed level save resolves false.
  • npx tsc --noEmit and npx tsc -p tsconfig.test.json --noEmit: clean. Biome on the changed files: clean.
  • npx playwright test tests/e2e/v4-shell.spec.ts against a local Vite server, including the six-button row, one-line/no-clipping layout, Space activation with focus retained, arrow navigation and the boundary.

Known limits

Only the zoom pane's one-field setters share the new chain. Other whole-document writers keep their existing behavior. Broader document serialization is out of this PR's scope.

Summary by CodeRabbit

  • New Features

    • Replaced the zoom-depth dropdown with six one-click zoom level buttons.
    • Added keyboard navigation with arrow keys and activation using Enter or Space.
    • The selected zoom level remains focused for faster editing.
  • Bug Fixes

    • Zoom changes now save reliably during rapid or overlapping edits.
    • Improved undo and redo behavior for zoom depth, rotation, focus mode, and cursor visibility changes.
    • Failed zoom saves no longer alter the document unexpectedly.

Replace the Zoom Level select with six always-visible buttons. Keyboard
stays local to the row: every level is a Tab stop, Enter/Space activate,
and arrows step from the focused button with both ends clamped.

Rapid clicks share a small zoom-pane write chain so 3 → 4 → 5 lands in
order. Each request has a generation, so late settlement, a region switch,
or a failed save can still retry.

Fixes getopenscreen#670.
Copilot AI lite review requested due to automatic review settings September 16, 2026 17:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 14264147-4b23-444f-b26f-c68f6d42869e

📥 Commits

Reviewing files that changed from the base of the PR and between 0834a66 and 36aedb5.

📒 Files selected for processing (6)
  • src/components/ai-edition/v4/FloatingInspector.tsx
  • src/components/ai-edition/v4/ZoomLevelControl.test.tsx
  • src/lib/ai-edition/store/documentWriteAudit.test.ts
  • src/lib/ai-edition/store/useTimeline.test.ts
  • src/lib/ai-edition/store/useTimeline.ts
  • tests/e2e/v4-shell.spec.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The zoom depth dropdown is replaced with six buttons. Zoom updates now use serialized document writes. The control adds keyboard navigation, request ordering, failure handling, and focus behavior. Tests cover component interactions, undo history, concurrent writes, and end-to-end behavior.

Changes

Zoom level feature

Layer / File(s) Summary
Serialized zoom writes
src/lib/ai-edition/store/useTimeline.ts, src/lib/ai-edition/store/documentWriteAudit.test.ts
Zoom depth, rotation, focus mode, and cursor visibility updates use a shared sequential writer. The audit table records the shared saveZoomPatch path.
Button control and inspector integration
src/components/ai-edition/v4/FloatingInspector.tsx
The inspector exports ZoomLevelControl, renders six labelled buttons, tracks asynchronous requests, handles keyboard navigation, and replaces the previous <select>.
Zoom interaction and persistence validation
src/components/ai-edition/v4/ZoomLevelControl.test.tsx, src/lib/ai-edition/store/useTimeline.test.ts, tests/e2e/v4-shell.spec.ts
Tests cover rendering, focus, keyboard events, concurrent requests, stale responses, failed saves, undo behavior, boundaries, and the end-to-end zoom level row.

Priority: ⬇️ Low

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature · Severity of issue fixed: Low

Sequence Diagram(s)

sequenceDiagram
  participant Editor
  participant ZoomLevelControl
  participant useTimeline
  participant saveDocument
  Editor->>ZoomLevelControl: click or press zoom level
  ZoomLevelControl->>useTimeline: request zoom depth
  useTimeline->>saveDocument: queue and save patched document
  saveDocument-->>useTimeline: return save result
  useTimeline-->>ZoomLevelControl: resolve request
  ZoomLevelControl-->>Editor: update pressed state and focus
Loading

Merge Risk: ⚪ Minimal · up to 36aed

The zoom controls and serialized persistence changes are mergeable with normal checks.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 14 functions across 6 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Issue #670 requires replacing the scale-level dropdown with a row of direct clickable controls. FloatingInspector.tsx adds ZoomLevelControl with six always-visible level buttons, a visible label, …
Out of Scope Changes check ✅ Passed The changes stay within the zoom-level control scope of issue #670. Keyboard handling and aria grouping support the new control. The queued zoom writes, generation tracking, undo tests, audit-table …
Title check ✅ Passed The title clearly and concisely describes the main change: replacing the zoom-level selector with a row of buttons in the inspector.
Description check ✅ Passed The description includes all required template sections and provides clear details about the UI change, issue reference, change type, release impact, platform impact, screenshots, testing, and known l…
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Use flat buttons instead of dropdown for scale level selection

2 participants