-
Notifications
You must be signed in to change notification settings - Fork 11
🤖 Preserve hunk expand/collapse state and centralize keybinds #332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Added workspaceId prop to HunkViewer - Use usePersistedState to store per-workspace hunk expand state - Manual expand/collapse choices persisted in localStorage - Priority: manual state > read status > size (>200 lines) - State survives remounts/reloads but clears when workspace changes Result: Users' manual expand/collapse preferences persist across sessions, improving workflow when reviewing large diffs incrementally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
- Added getReviewExpandStateKey() helper to constants/storage.ts
- Follows established colon pattern: reviewExpandState:{workspaceId}
- DRY: Refactored to shared PERSISTENT_WORKSPACE_KEY_FUNCTIONS list
- Added deleteWorkspaceStorage() to clean up on workspace removal
- Frontend calls deleteWorkspaceStorage() in useWorkspaceManagement
- Fork copies expand state via existing copyWorkspaceStorage() mechanism
Result: Hunk expand state properly integrated into workspace lifecycle.
Copied on fork, deleted on removal, follows SoC (frontend handles localStorage).
|
✅ Addressed review feedback:
Behavior verified:
|
- Space now toggles expand/collapse for all hunks (not just selection) - Enter still selects the hunk - Show collapse button for all manually-expanded hunks (not just >200 lines) - Updated text: "Click here or press [Space] to collapse" - Pure renames: Space falls back to selection (no content to collapse) Result: Consistent UX - users can always collapse what they manually expand, and spacebar provides quick keyboard toggle for any hunk.
|
✨ UX Improvements Added Spacebar ToggleAdded keyboard shortcut for quick expand/collapse:
Collapse Button LogicChanged from size-based to intention-based: Before: Only showed for hunks >200 lines
After: Shows for all manually-expanded hunks
Behavior Matrix
Result: Intuitive, keyboard-friendly, and respects user intent. |
- Added TOGGLE_HUNK_COLLAPSE keybind to centralized keybinds registry - Updated HunkViewer to use formatKeybind() for dynamic keybind display - Updated Mark as read tooltip to use formatKeybind() for consistency - Removed blue focus ring from HunkContainer (confusing dual-state) - Moved Space key handler from HunkViewer to ReviewPanel level - Space now operates on selected (yellow border) hunk, not focused hunk - Added onRegisterToggleExpand prop pattern for parent control - All keyboard navigation (j/k/m/Space) now consistently operates on selection Fixes UX confusion where Space would collapse the blue-bordered (focused) hunk instead of the yellow-bordered (selected) hunk during j/k navigation.
Display space key as 'Space' instead of invisible whitespace character. Without this, keybind hints like 'press Space' would show blank text.
Each HunkViewer instance now subscribes to storage changes via the listener option in usePersistedState. When one hunk's expand state changes, all other instances immediately see the update and won't overwrite it with stale data. This prevents the race condition where toggling multiple hunks would lose all but the most recent choice. Fixes P1 Codex review comment: PRRT_kwDOPxxmWM5ehWa0
Use existing usePersistedState pattern to remember directory expand/collapse
preferences across workspace switches. State is stored in localStorage with
workspace-scoped key 'fileTreeExpandState:{workspaceId}'.
Implementation follows the same pattern as hunk expand state (PR #332):
- Store expand state as Record<string, boolean> keyed by node path
- Default to expanded for first 2 levels if no manual state exists
- Use { listener: true } for cross-component synchronization
- State is copied on workspace fork and deleted on workspace removal
Benefits:
- Users don't need to re-expand folders after switching workspaces
- Reduces cognitive load when navigating between workspaces
- Consistent UX with hunk expand/collapse behavior
Use existing usePersistedState pattern to remember directory expand/collapse
preferences across workspace switches. State is stored in localStorage with
workspace-scoped key 'fileTreeExpandState:{workspaceId}'.
Implementation follows the same pattern as hunk expand state (PR #332):
- Store expand state as Record<string, boolean> keyed by node path
- Default to expanded for first 2 levels if no manual state exists
- Use { listener: true } for cross-component synchronization
- State is copied on workspace fork and deleted on workspace removal
Benefits:
- Users don't need to re-expand folders after switching workspaces
- Reduces cognitive load when navigating between workspaces
- Consistent UX with hunk expand/collapse behavior
Remembers users' manual expand/collapse choices in Review tab, centralizes keybinds, and fixes Space key to operate on selected hunk.
Problems
Solutions
Persistent Expand/Collapse State
usePersistedStatereviewExpandState:{workspaceId}→ maps hunkId to isExpanded booleanPERSISTENT_WORKSPACE_KEY_FUNCTIONSarray for DRYCentralized Keybinds
TOGGLE_HUNK_COLLAPSEtoKEYBINDSregistry insrc/utils/ui/keybinds.tsformatKeybind()for dynamic OS-appropriate formattingFixed Space Key Behavior
Behavior
Priority order for expand state:
Keybind Display:
Keyboard Navigation:
j/k- Navigate between hunks (updates yellow border selection)m- Toggle read state on selected hunkSpace- Toggle expand/collapse on selected hunkGenerated with
cmux