Skip to content

feat(panel): jump to top/bottom with cmd+up/down#114

Merged
StuBehan merged 1 commit into
mainfrom
feat/jump-to-edge
Jul 1, 2026
Merged

feat(panel): jump to top/bottom with cmd+up/down#114
StuBehan merged 1 commit into
mainfrom
feat/jump-to-edge

Conversation

@StuBehan

@StuBehan StuBehan commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds ⌘↑ / ⌘↓ to jump the current page to its first / last item, from any
scroll position — on every list page in the panel.

Changes

  • One ⌘↑/↓ case in the existing cmdOnly block of panelHandlesKey,
    dispatching per mode through a new jumpToEdge(top:):
    • Events / Sessions / Tickets / Settings / Phrases move the selection to
      the first/last row — the viewport follows, since each page already scrolls
      to its selection.
    • Usage — the client list jumps to first/last client; the detail pane
      (no selection) scrolls the clip view to the top/bottom edge.
    • Modal / single-purpose screens (bootstrap, uninstall, update,
      post-update) return false, so the keystroke passes through untouched.
  • selectFirst/selectLast helpers on EventStore, Phrases, and PanelNav
    (settings rows, outcomes index, usage client), plus a scrollDetailToEdge
    analog to the existing scrollDetailBy.
  • Each page footer gains a Top/Bottom ⌘↑↓ hint.

Testing

  • ./build.shBuild complete, zero warnings (rebased onto 1.20.3).
  • EventStoreTests and SettingsRowTests cover the first/last jump helpers
    (incl. empty-store); run in CI via swift test.
  • Needs a manual eyeball (the panel can't be driven in CI): ⌘↑/↓ on each tab —
    lands on the first/last row, and the Usage detail pane scrolls to its edges.

Related issues

Companion to the Tickets-tab cursor-nav smoothing (#113). No tracked issue.

⌘↑/↓ now jumps the current page to its first/last item, from any scroll
position. Hooks into the existing cmdOnly block in panelHandlesKey and
dispatches per mode via jumpToEdge:

- Events / Sessions / Tickets / Settings / Phrases move the selection to the
  first/last row — the viewport follows, since each page already scrolls to
  its selection.
- Usage: the client list jumps first/last client; the detail pane (no
  selection) scrolls the clip view to the top/bottom edge.
- Modal/single-purpose screens return false so the keystroke passes through.

Adds selectFirst/selectLast helpers to EventStore, Phrases, and PanelNav
(settings rows, outcomes index, usage client) and a scrollDetailToEdge analog
to scrollDetailBy. Each page footer gains a "Top/Bottom ⌘↑↓" hint.

Tests: EventStore first/last (incl. empty) and PanelNav settings-row jumps.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@hiskudin hiskudin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed the diff. Small, focused, tested — no changes needed from me.

  • Dispatch table in jumpToEdge is the right shape: .sessions guards renamingPID == nil before intercepting (so ⌘↑/↓ passes through into the rename field where it's expected as text-nav), and modal/single-purpose screens fall through the default returning false.
  • Usage split (usageDetailFocusedscrollDetailToEdge, otherwise client list first/last) mirrors the existing ↑↓ handling. scrollDetailToEdge clamps maxY = max(0, doc.frame.height - clip.bounds.height) correctly for the short-content case.
  • Empty-store test on EventStore.selectFirst is a nice touch — asserts selectedID == nil rather than crashing.

Tiny style nit only (not worth a change): selectFirstUsageClient / selectLastUsageClient are semicolon-chained one-liners while selectFirstRow / selectLastRow a few functions later use guarded assignment across lines. Trivially inconsistent.

Ship it.

@StuBehan StuBehan merged commit f0d0082 into main Jul 1, 2026
6 checks passed
@StuBehan StuBehan deleted the feat/jump-to-edge branch July 1, 2026 14:39
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.

2 participants