Skip to content

feat(desktop/pdf): fit-page, 90° rotation + hand/pan tool, ink-drag canvas preview (#321)#344

Merged
physercoe merged 3 commits into
physercoe:mainfrom
agentfleets:desktop/321-pdf-tail
Jul 20, 2026
Merged

feat(desktop/pdf): fit-page, 90° rotation + hand/pan tool, ink-drag canvas preview (#321)#344
physercoe merged 3 commits into
physercoe:mainfrom
agentfleets:desktop/321-pdf-tail

Conversation

@agentfleets

Copy link
Copy Markdown
Collaborator

Closes #321

Implements the last remaining tail of the PDF reader polish issue — the two items left open in the issue comments (fit-page mode + rotation + hand/pan tool; ink-drag preview re-rendering the whole page per pointermove).

What

Fit-page + rotation + hand/pan (PdfCanvas.tsx)

  • Fit-page button alongside the existing fit-width: computes the scale that fits the whole page (both axes) into the scroll viewport; the resulting scale persists via the existing PDF_SCALE_KEY mechanism.
  • 90°-step rotation toolbar button, persisted (termipod.pdf.rotation, same shared-across-PDFs pattern as zoom). User rotation stacks on the page's own (page.rotate + rotation) for canvas/text/link rendering; the pre-measured page footprints just swap axes at 90°/270° (no re-measure); render-task cancellation and live-DPR re-rasterization are unchanged. Annotation overlays, creation hit-mapping (note/area/ink/text-selection), area-screenshot capture, and annotation/dest jump offsets all map through rotation-aware pdfPtToView/viewToPdfPt helpers — rotation 0 degenerates to the old multiply + y-flip, so stored annotations are unaffected. Thumbnails rotate with the pages.
  • Hand/pan tool: drag anywhere in the scroll view to pan (grab/grabbing cursors, text selection disabled while armed); window listeners instead of setPointerCapture (WebView2), and the trailing click after a drag is swallowed so a pan released over a link doesn't open it.
  • New toolbar labels/tooltips localized en + zh (read.zoomFitPage, read.rotateCw, read.panTool); three new stroke icons (fit-page, rotate-cw, hand).

Ink-drag preview

  • The in-progress ink stroke now draws into a lightweight DPR-scaled canvas overlay (ref-only, incremental lineTo per move) instead of a draft state that re-rendered the whole page component on every pointermove. React state (the annotation store) is touched once, on pointer-up. The area-rect draft preview is unchanged.

Why

  • These were the only two open items left on the issue after the earlier shipped passes (match-granular search, load progress, zoom persistence, live-DPR, popover clamp, ArtifactViewer PdfCanvas, EPUB themes).

How verified

  • npm run build (sync:tokens + tsc --noEmit + vite build) — green.
  • scripts/lint-desktop-tokens.sh — clean (no new hex/primitive/phantom tokens; hand-tool CSS uses cursor/user-select only).
  • Rotation geometry (pdfPtToView/viewToPdfPt) round-trip-tested for 0/90/180/270 incl. corner expectations; rotation-0 output verified identical to the previous mapping.
  • No Rust changes; no package.json/lockfile changes.

agentfleet and others added 2 commits July 19, 2026 18:09
physercoe
physercoe previously approved these changes Jul 20, 2026

@physercoe physercoe left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

APPROVE. Rotation × annotation geometry verified correct against pdf.js viewport math for all four rotations (pdfPtToView/viewToPdfPt inverse pair; rotation-0 byte-identical so existing anchors unaffected). Ink preview is ref-only until pointer-up; hand/pan tracks via window listeners (WebView2 lesson). Rebased onto main and resolved the PdfCanvas drilled-t→local-useT() merge (kept #321 rot, dropped the t prop to match main). Cosmetic minor: ToC/internal-link jump lands page-top while rotated (goToAnnotation is correct).

# Conflicts:
#	desktop/src/ui/PdfCanvas.tsx

@physercoe physercoe left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Re-approve after rebasing onto main (incl #342). Resolved the #342×#344 overlap in PdfCanvas by taking the union — kept both #316 toolTitle + tool-shortcut effect and #321 rotation-aware annoAnchor, dropped the superseded annoTopY. Clean tsc+vite build and token lint.

@physercoe
physercoe merged commit b567a66 into physercoe:main Jul 20, 2026
5 checks passed
physercoe pushed a commit that referenced this pull request Jul 20, 2026
…ic-tail merges

Since v0.3.79:
- fix(terminal): tell xterm the pty is ConPTY on Windows so a repainting TUI's
  intermediate frames no longer pile up in the scrollback (2b26a16).
- 8 epic-tail PRs merged: #341 terminal connect-phase + SSH split-duplicate,
  #342 PDF struct-tree a11y + annotation shortcuts, #343 token burn-down /
  plural / responsive, #344 PDF fit-page / rotation / hand-pan / ink,
  #345 perf (page memo, debounce, chart cap, sync dirty-tracking),
  #346 modal migration + dirty-close guards, #347 vault TOTP / ed25519 /
  coded errors, #348 read reconcile / AuthorNav / table nav / frame check.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
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.

feat(desktop): PDF reader polish — per-match search, loading progress, zoom persistence, offscreen un-rendering

2 participants