Originally created by: kristofferR
Implements the shortcut set from [#18] and [#30] (Ref [#18], Ref [#30]).
| Action | Key |
|---|---|
| Previous / next conversation | Cmd/Ctrl+[ / ], and Ctrl+Tab / Ctrl+Shift+Tab |
| New conversation | Cmd/Ctrl+Shift+N (File menu; Cmd/Ctrl+N stays New Window) |
| Search conversations | Cmd/Ctrl+K |
| Search in conversation | Cmd/Ctrl+F |
| Focus message input | Cmd/Ctrl+L |
| Emoji / GIF / attach files | Cmd/Ctrl+E / G / T |
The browser-style Cmd/Ctrl+[/] history bindings are removed per [#18] and the keys reused for conversation navigation.
Cmd+N: stays New Window (maintainer call, matching [#18]'s recommendation). New Conversation is a File-menu item on Cmd/Ctrl+Shift+N, and Hide Names & Avatars (the previous Shift+N holder) moved to Cmd/Ctrl+Shift+H. A page-side ⌘N binding alone was never an option — the native File menu claims the key before the page sees it.inject/messenger.js, per [#30]'s mechanism table: plain DOM ops where possible (composer focus, chat-list search focus, the /messages/new/ compose link), clicking Messenger's own buttons otherwise — no React-fiber reaching.Cmd/Ctrl+F is the two-step case: the Search control only exists inside the conversation-info sidebar (aria-label is just "Search", no complementary landmark). If it's not present the handler opens the sidebar via the existing __carrierToggleInfo and clicks Search once React renders it (50 ms poll, 2 s cap).mcp-bridge.js gains a sanitized __carrier_mcp_shortcut_probe__ (roles/labels/rects of shortcut targets; chat rows and articles excluded, digits masked) and a CSP-safe __carrier_mcp_call__:<name> invoker restricted to the __carrierShortcuts registry. Release builds compile none of this.Every selector was verified against the live Messenger DOM in an mcp debug build, and each helper was invoked end-to-end: next/prev switch threads (URL confirmed), ⌘F opens the sidebar → Search input focused (screenshot-verified), ⌘K/⌘L focus their inputs, emoji/GIF pickers open and toggle closed, New Conversation SPA-navigates to the compose view with the To: field active. attachFiles was validated by label match only (clicking it opens a native file dialog).
Gates: cargo fmt / clippy -D warnings / cargo test --lib (44 passed) / node --check on both injected files.
https://claude.ai/code/session_01BuZke2qu27Gw363mGTm7gn
Added keyboard shortcuts to move between conversations, open a new conversation, and quickly access chat tools like search, composer focus, emoji/GIF pickers, and file attachment.
Bug Fixes
Corrected the shortcut for hiding names and avatars to avoid conflicts.
Documentation
Originally posted by: kristofferR
@coderabbitai review
Originally posted by: coderabbitai[bot]
✅ Action performed
Review finished. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.Originally posted by: coderabbitai[bot]
📝 Walkthrough
## Walkthrough This PR adds conversation navigation shortcuts (Ctrl+Tab/Ctrl+Shift+Tab, Cmd/Ctrl+[/]) and Messenger action shortcuts (search, composer focus, emoji/GIF pickers, attach, new conversation) via a new window.__carrierShortcuts registry, wires a native "New Conversation" menu item, changes the Hide Names & Avatars accelerator to Shift+H, adds an MCP bridge probe/invocation path, and updates docs. ### Changes **Messenger shortcuts and menu integration** |Layer / File(s)|Summary| |---|---| |**Conversation navigation and shortcut helpers**`src-tauri/inject/messenger.js`|Adds stepConversation navigation and focus/search/composer/picker/attach/new-conversation helpers, exposed via window.__carrierShortcuts.| |**Shortcut keymap wiring and hotkey comment fix**
`src-tauri/inject/messenger.js`|Replaces history-based [/] navigation with stepConversation, adds Ctrl+Tab/Ctrl+Shift+Tab cycling and new action bindings, and fixes the Hide Names & Avatars comment.| |**Native menu: New Conversation item and accelerator change**
`src-tauri/src/lib.rs`|Adds a "New Conversation" menu item (CmdOrCtrl+Shift+N), changes Hide Names & Avatars accelerator to CmdOrCtrl+Shift+H, and handles the new_conversation event to invoke the JS shortcut hook.| |**MCP bridge probe and helper invocation**
`src-tauri/inject/mcp-bridge.js`|Adds shortcutProbe() and execute-js handling for shortcut probe and whitelisted __carrierShortcuts calls, bypassing arbitrary Function evaluation for those cases.| |**Documentation and settings UI updates**
`README.md`, `dist/settings.html`|Updates keyboard shortcuts list and settings hint text to reflect new navigation shortcuts and the Shift+H accelerator.| **Estimated code review effort:** 3 (Moderate) | ~30 minutes ### Sequence Diagram(s) :::mermaid sequenceDiagram participant User participant NativeMenu as Native Menu (lib.rs) participant Webview participant Messenger as messenger.js participant DOM as Messenger DOM User->>NativeMenu: Trigger "New Conversation" (Shift+N) NativeMenu->>Webview: eval JS Webview->>Messenger: window.__carrierShortcuts.newConversation() Messenger->>DOM: Navigate via SPA route or fallback DOM-->>Messenger: New conversation opened User->>Messenger: Ctrl+Tab / Cmd+] Messenger->>Messenger: stepConversation(direction) Messenger->>DOM: Locate current thread + visible chat rows DOM-->>Messenger: Next/prev thread element Messenger->>DOM: Click/navigate to target conversation :::mermaid sequenceDiagram participant MCPClient participant Bridge as mcp-bridge.js participant Window as window.__carrierShortcuts participant DOM as Messenger DOM MCPClient->>Bridge: execute-js "__carrier_mcp_call__:focusComposer" Bridge->>Window: lookup helper by name Window->>DOM: focusComposer() DOM-->>Window: composer focused Window-->>Bridge: {called, returned} Bridge-->>MCPClient: result MCPClient->>Bridge: execute-js "__carrier_mcp_shortcut_probe__" Bridge->>DOM: scan controls, masks data DOM-->>Bridge: sanitized control descriptors Bridge-->>MCPClient: shortcutProbe() result **Possibly related issues** - [kristofferR/Carrier#18](https://github.com/kristofferR/Carrier/issues/18): Implements the described removal of history-based navigation in favor of next/prev conversation and related Messenger shortcuts. - [kristofferR/Carrier#30](https://github.com/kristofferR/Carrier/issues/30): Implements the described Messenger keyboard-shortcut additions including new conversation, search, emoji/GIF, and attach actions. **Possibly related PRs** - [[kristofferR/Carrier#2](https://github.com/kristofferR/Carrier/issues/2)](https://github.com/kristofferR/Carrier/pull/2): Both PRs modify conversation navigation/shortcut handling in `src-tauri/inject/messenger.js`. - [[kristofferR/Carrier#11](https://github.com/kristofferR/Carrier/issues/11)](https://github.com/kristofferR/Carrier/pull/11): Both PRs extend the `execute-js` responder in `src-tauri/inject/mcp-bridge.js` with new probe/call handling.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
| Check name | Status | Explanation | | :------------------------: | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | | Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. | | Title check | ✅ Passed | The title is clear and matches the main change set: adding Caprine-style keyboard shortcuts for conversation navigation, search, and composer actions. | | Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. | | Linked Issues check | ✅ Passed | Check skipped because no linked issues were found for this pull request. | | Out of Scope Changes check | ✅ Passed | Check skipped because no linked issues were found for this pull request. |✨ Finishing Touches
📝 Generate docstrings
- [ ] Create stacked PR - [ ] Commit on current branch🧪 Generate unit tests (beta)
- [ ] Create PR with unit tests - [ ] Commit unit tests in branch `feature/caprine-shortcuts`Comment
@coderabbitai helpto get the list of available commands.Originally posted by: kristofferR
@coderabbitai review
Originally posted by: coderabbitai[bot]
✅ Action performed
Review finished. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.Originally posted by: kristofferR
@coderabbitai review
Originally posted by: coderabbitai[bot]
✅ Action performed
Review finished. > Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.Ticket changed by: kristofferR