Skip to content

feat(web): add keybinding to toggle thread read/unread - #12832

Closed
Mizaro wants to merge 2 commits into
pingdotgg:mainfrom
Mizaro:cursor/thread-toggle-unread-keybinding-35e3
Closed

Mizaro wants to merge 2 commits into
pingdotgg:mainfrom
Mizaro:cursor/thread-toggle-unread-keybinding-35e3

Conversation

@Mizaro

@Mizaro Mizaro commented Sep 21, 2026 •

Copy link
Copy Markdown

What Changed

Add a thread.toggleUnread keybinding so the open thread can be marked unread or read from the keyboard.

  • Default shortcut: mod+shift+u (⌘⇧U / Ctrl+Shift+U), with !terminalFocus so it does not steal terminal input
  • Dispatches from the chat view like pin and settle
  • Command palette action: Mark unread / Mark as read
  • Settings → Keybindings lists and searches Thread: Toggle Read/Unread

Toggling unread after opening a thread sticks until you leave or a later completion retriggers the visit stamp.

Why

Threads could already be marked unread from the context menu, but there was no shortcut. Pin and settle already have mod+shift bindings; this follows that pattern so read/unread is reachable from the chat view, Settings, and the command palette.

UI Changes

Settings lists the new binding as Thread: Toggle Read/Unread (Ctrl+Shift+U, when !terminalFocus):

Settings keybindings showing Thread: Toggle Read/Unread

Open thread starts read (relative time, no unread badge):

Thread sidebar in read state before shortcut

Ctrl+Shift+U marks it unread (green Done pill in the sidebar):

Thread sidebar showing unread Done badge after shortcut

Command palette exposes Mark unread with the same shortcut, and searching "unread" also finds the Settings row:

Command palette Mark unread with Ctrl+Shift+U

Command palette search for unread

End-to-end: Settings, then toggling the demo thread unread and read twice with ^⇧U, then palette search showing Mark unread:

https://github.com/Mizaro/t3code/releases/download/pr-12832-ui-evidence/toggle_thread_unread_shortcut.mp4

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Threads could be marked unread from the menu, but there was no shortcut. Add thread.toggleUnread (default mod+shift+u) so the open thread can be toggled from the keyboard, command palette, and Settings.

Made-with: Cursor Grok 4.6

Co-authored-by: Gilad Leifman <Mizaro@users.noreply.github.com>
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 21, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This adds a new production keyboard command and enables it by default through the shared keybinding defaults, with corresponding behavior in ChatView, the command palette, settings, and persisted UI state. The default shortcut changes user-facing product behavior and warrants human review.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

Understand this PR’s impact

Explore downstream dependencies and potential security impact with Blast Radius.

View blast radius →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration

Configuration used: Repository: pingdotgg/t3code/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: a7d1d13b-69bc-442c-991f-0f4171f738ba

📥 Commits

Reviewing files that changed from the base of the PR and between 2cde3fa and a5b29d4.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: pingdotgg/t3code/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: aeed9655-7217-4074-b990-dbdfbd4cd374

📥 Commits

Reviewing files that changed from the base of the PR and between 2efb817 and 2cde3fa.

📒 Files selected for processing (12)
  • apps/web/src/components/ChatView.tsx
  • apps/web/src/components/CommandPalette.tsx
  • apps/web/src/components/Sidebar.logic.ts
  • apps/web/src/components/settings/KeybindingsSettings.logic.test.ts
  • apps/web/src/components/settings/KeybindingsSettings.logic.ts
  • apps/web/src/components/settings/settingsSearch.test.ts
  • apps/web/src/keybindings.test.ts
  • apps/web/src/uiStateStore.test.ts
  • apps/web/src/uiStateStore.ts
  • packages/contracts/src/keybindings.test.ts
  • packages/contracts/src/keybindings.ts
  • packages/shared/src/keybindings.ts

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


📝 Walkthrough

Walkthrough

The change adds shared thread unread evaluation and toggling to the UI state store. It adds the thread.toggleUnread command with a Mod+Shift+U binding, integrates it into ChatView and CommandPalette, updates Sidebar indicators, and adds tests and settings labels.

Changes

Thread read toggle

Layer / File(s) Summary
Keybinding contract and default
packages/contracts/src/keybindings.ts, packages/shared/src/keybindings.ts, packages/contracts/src/keybindings.test.ts, apps/web/src/keybindings.test.ts
Adds thread.toggleUnread and binds it to Mod+Shift+U when the terminal is not focused. Tests cover decoding, resolution, focus conditions, and platform preservation.
Unread evaluation and state transition
apps/web/src/uiStateStore.ts, apps/web/src/uiStateStore.test.ts
Adds isThreadUnread and toggleThreadRead. The store action updates the thread visit timestamp using the latest completion timestamp.
Shortcut and command-palette integration
apps/web/src/components/ChatView.tsx, apps/web/src/components/CommandPalette.tsx, apps/web/src/components/Sidebar.logic.ts
Handles thread.toggleUnread in ChatView and CommandPalette. Adds a conditional Mark as read or Mark unread palette action. Sidebar unread checks use the shared helper.
Keybinding labels and search
apps/web/src/components/settings/KeybindingsSettings.logic.ts, apps/web/src/components/settings/KeybindingsSettings.logic.test.ts, apps/web/src/components/settings/settingsSearch.test.ts
Adds the Thread: Toggle Read/Unread label and verifies default-row display and settings search results.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ChatView
  participant CommandPalette
  participant UiStateStore
  participant Sidebar
  User->>ChatView: Press Mod+Shift+U
  ChatView->>UiStateStore: Toggle active thread read state
  User->>CommandPalette: Select read-state action
  CommandPalette->>UiStateStore: Toggle scoped thread read state
  UiStateStore-->>Sidebar: Updated visit timestamp
  Sidebar->>UiStateStore: Evaluate unread status
Loading

Suggested reviewers: bil0000

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 12 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 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.
Title check ✅ Passed The title clearly and concisely describes the main change: adding a web keybinding to toggle thread read/unread state.
Description check ✅ Passed The description includes What Changed, Why, UI Changes, and Checklist sections. It explains the shortcut, affected surfaces, behavior, and provides screenshots and a video for the interaction changes.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

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

@juliusmarminge

Copy link
Copy Markdown
Member

Thanks for working on this. We merged the orchestrator V2 rewrite in #2829, and we are closing this PR as part of that transition.

This PR adds read/unread keyboard and command-palette behavior throughout the old latestTurn.completedAt model. V2 changed the thread completion/read-status inputs, so the multi-entry-point implementation must move to latestRun.

Sorry for the extra work this creates. If the change is still needed on V2, please rebuild it on current main, verify it there, and open a new PR linking back here. We're closing the current implementation without assuming the underlying request is resolved.

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

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants