Add a Craft-like sidebar row context menu #39

Open
opened 2026-08-22 18:26:36 +00:00 by kayg · 0 comments
Owner

Ask

Add a Craft-like context menu to chat-sidebar session rows. The menu must expose at least Copy deep link and Pin, with pin state reflecting the pinned-session behavior tracked separately in the companion pinning issue.

Files and APIs

  • Sources/Hermternal/Views/SidebarView.swift: SessionRow and its row context menu.
  • Sources/Hermternal/Views/RootView.swift: ChatWindow, if clipboard or row-action routing is composed there.
  • Sources/Hermternal/HermternalApp.swift: existing onOpenURL handling for MessageDeepLink.
  • AppModel.openThenScroll(to:): the existing deep-link consumer. Reuse the URL scheme/path it already accepts; do not invent a second scheme.

Acceptance

  • Context-clicking a session row opens a native macOS context menu containing Copy deep link and Pin.
  • Copy deep link places a URL on the pasteboard that the existing HermternalApp.swift onOpenURL / MessageDeepLink path accepts and that reopens the copied chat (and message target when one is represented), without introducing another URL scheme.
  • Pin toggles the row's current pinned state and the sidebar placement updates as specified by the companion pinning issue; reopening the menu reflects the new state.
  • The menu acts on the row that was context-clicked and does not change the selected chat merely by opening the menu.
  • A verified secondary click does not move List(selection:) on macOS, so the no-selection-change requirement is achievable.
  • A per-row .contextMenu was chosen over contextMenu(forSelectionType:) because selection is single and a per-row menu provably acts on the clicked row.

This is the sidebar action surface related to the broader deep-link work in #4, not a duplicate of that issue's URL/navigation design.

## Ask Add a Craft-like context menu to chat-sidebar session rows. The menu must expose at least **Copy deep link** and **Pin**, with pin state reflecting the pinned-session behavior tracked separately in the companion pinning issue. ## Files and APIs - `Sources/Hermternal/Views/SidebarView.swift`: `SessionRow` and its row context menu. - `Sources/Hermternal/Views/RootView.swift`: `ChatWindow`, if clipboard or row-action routing is composed there. - `Sources/Hermternal/HermternalApp.swift`: existing `onOpenURL` handling for `MessageDeepLink`. - `AppModel.openThenScroll(to:)`: the existing deep-link consumer. Reuse the URL scheme/path it already accepts; do not invent a second scheme. ## Acceptance - Context-clicking a session row opens a native macOS context menu containing **Copy deep link** and **Pin**. - **Copy deep link** places a URL on the pasteboard that the existing `HermternalApp.swift` `onOpenURL` / `MessageDeepLink` path accepts and that reopens the copied chat (and message target when one is represented), without introducing another URL scheme. - **Pin** toggles the row's current pinned state and the sidebar placement updates as specified by the companion pinning issue; reopening the menu reflects the new state. - The menu acts on the row that was context-clicked and does not change the selected chat merely by opening the menu. - A verified secondary click does not move `List(selection:)` on macOS, so the no-selection-change requirement is achievable. - A per-row `.contextMenu` was chosen over `contextMenu(forSelectionType:)` because selection is single and a per-row menu provably acts on the clicked row. This is the sidebar action surface related to the broader deep-link work in [#4](https://git.kayg.org/kayg/hermternal-apple/issues/4), not a duplicate of that issue's URL/navigation design.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/hermternal-apple#39
No description provided.