feat: add keybinds settings modal, auto-delete expired timers, and bump version to v0.5.6#76
Conversation
…mp version to v0.5.6
|
Warning Review limit reached
More reviews will be available in 34 minutes and 8 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughPaperCache v0.5.6 adds a dedicated ChangesKeybinds Settings Modal & Configurable Hotkeys
Timer Auto-Deletion and Event Handling Consolidation
3D Graph Link Parsing and Z-Axis Centroids
Version Bump to 0.5.6
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/hooks/useGlobalHotkey.ts (1)
92-180: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winBypass all global hotkeys while recording a shortcut.
ShortcutInputdepends on its ownonKeyDown, but this window capture handler runs first. WhileisRecordingShortcutis true, pressing an existing shortcut likeCmd+Pcan trigger the app action and prevent the new binding from being captured.Proposed fix
const handleGlobalKeyDown = async (e: KeyboardEvent) => { const state = useAppStore.getState() const defaultMod = isHyprland ? 'Alt' : 'CommandOrControl' + + if (state.isRecordingShortcut) { + return + } if (e.key === 'Escape') { const isRenaming = useAppStore.getState().isRenaming const actionMenuIndex = useAppStore.getState().actionMenuIndex - const isRecordingShortcut = useAppStore.getState().isRecordingShortcut - - if (isRecordingShortcut) return // Do not close app while recording shortcut // Dismiss overlays in priority order — highest-level first🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/hooks/useGlobalHotkey.ts` around lines 92 - 180, The global hotkey handler in useGlobalHotkey should not run while ShortcutInput is recording a new binding. Add an early guard in the window keydown capture logic, using the existing isRecordingShortcut state, so matchShortcut checks and app actions are skipped during recording. Keep the change localized to useGlobalHotkey and its shortcut handler block so ShortcutInput can receive keys without Cmd+P/Cmd+T/etc. triggering.
🧹 Nitpick comments (2)
src/GraphView.tsx (2)
35-51: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
czcentroid is computed but never used; the Z-axis layout has no effect.The centroid map now carries
cz, but the force setup only registersfolderX/folderY(Lines 206–225) — there is nofolderZforce consumingcz. Additionally,ForceGraph3Dis configured withnumDimensions={2}(Line 476), so the simulation is constrained to a plane and any Z positioning would be ignored anyway. As written, the "Z-Axis Centroids" change is dead code.Either wire up a
folderZforce and switch tonumDimensions={3}, or dropczto avoid misleading dead state.♻️ Option A — wire up the Z force (3D)
+ fg.d3Force( + 'folderZ', + d3 + .forceZ<GraphNode>((node) => { + const c = centroids.get(node.folder) + return c ? c.cz : 0 + }) + .strength((node) => (node.folder && !draggedNodesRef.current.has(node.id) ? 0.008 : 0)) + )And set
numDimensions={3}onForceGraph3D.♻️ Option B — drop the unused field
-): Map<string, { cx: number; cy: number; cz: number }> { - const centroids = new Map<string, { cx: number; cy: number; cz: number }>() +): Map<string, { cx: number; cy: number }> { + const centroids = new Map<string, { cx: number; cy: number }>()cy: radius * Math.sin(angle), - cz: (i % 2 === 0 ? 1 : -1) * (15 * (i % 3)), })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/GraphView.tsx` around lines 35 - 51, The `cz` value in `buildFolderCentroids` is currently unused because the graph only applies `folderX` and `folderY` forces and `ForceGraph3D` is still set to `numDimensions={2}`. Update the `GraphView` setup to either add a `folderZ` force that consumes the centroid `cz` values and switch `ForceGraph3D` to 3 dimensions, or remove `cz` from `buildFolderCentroids` and related centroid data to keep the layout logic consistent.
158-165: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueOptional: wikilink aliases and redundant matches.
The new parsing is correct and the
nodeIds+ self-link guards safely discard junk, so this is non-blocking. Two minor notes:
reMd(/\]\(([^)]+\.md)\)/g) also matches the](/file …)syntax already handled byreFile, and external URLs ending in.md. These produce targets that get filtered out, so behavior is fine — just redundant work.- Wikilink aliases like
[[Note|Display]]aren't handled;targetIdbecomesNote|Display.mdand won't resolve. If aliases are expected, split on|before appending.md.♻️ Optional alias handling
while ((match = reWiki.exec(note.content)) !== null) { - let targetId = match[1].trim().replace(/\\/g, '/') + let targetId = match[1].split('|')[0].trim().replace(/\\/g, '/') if (!targetId.endsWith('.md')) targetId += '.md' targets.add(targetId) }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/GraphView.tsx` around lines 158 - 165, The GraphView note target parsing in the markdown-link branch is still missing wikilink alias handling: when processing `note.content`, `targetId` should strip any `|display text` portion from `[[Note|Display]]` before normalizing and appending `.md`, so the resolved ID matches the actual node. Update the parsing logic alongside the existing `reMd`/`targets.add` flow in `GraphView` to preserve current guards while correctly resolving aliased wikilinks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/App.tsx`:
- Around line 76-90: The timer listener setup in App.tsx is missing cleanup for
the case where listen() resolves after the effect has already unmounted, so the
unlisten callback can be lost and the listener remain registered. Update the
effect around listen<string>('timer-complete', ...) to track the pending promise
and ensure the resolved unlisten function is invoked during cleanup even if it
arrives late; use the existing unlistenTimer/cleanup logic in the same effect to
cover both immediate and delayed resolution.
In `@src/components/KeybindsModal.tsx`:
- Around line 15-49: The shortcut state initializers in KeybindsModal are using
getItem(...) || fallback, which turns a saved empty string back into the default
shortcut. Update these reads to preserve cleared bindings by distinguishing null
from '', and apply the same pattern consistently across the shortcut state setup
in KeybindsModal and the related hotkey hydration path so empty values remain
persisted.
In `@src/components/ShortcutInput.tsx`:
- Around line 19-25: The ShortcutInput recording lifecycle only pauses/resumes
shortcuts during local state changes, so if the component unmounts while
recording is still true the paused global shortcut state can leak. Update the
ShortcutInput useEffect to return a cleanup that resumes shortcuts on unmount,
and also clear the recording flag/state that is set when starting shortcut
capture so the modal Escape guard does not remain stuck in recording mode. Use
the existing pauseShortcuts, resumeShortcuts, and setIsRecordingShortcut flow to
locate the fix.
In `@src/hooks/useGlobalHotkey.ts`:
- Around line 194-195: The reference note in useGlobalHotkey is hardcoding the
Tasks/Reminders and Timers Panel shortcuts, which breaks when the user remaps
them. Update the note generation to read from the configured shortcut values
used by useGlobalHotkey rather than embedding Cmd+R and Cmd+T directly. Make
sure the same source of truth that drives the hotkey bindings is also used when
composing the reference text so it stays accurate after remapping.
In `@src/Settings.tsx`:
- Around line 264-270: The edited Toggle App Visibility shortcut is not being
persisted, so it can revert after restart. Update the Settings save flow in
Settings.tsx, specifically the saveSettings logic that already handles shortcut
registration updates, to also write shortcutToggle into
SETTINGS_KEYS.SHORTCUT_TOGGLE before saving. Make sure the same source of truth
used by ShortcutInput for shortcutToggle is included alongside the existing
shortcut fields so the backend and stored settings stay in sync.
---
Outside diff comments:
In `@src/hooks/useGlobalHotkey.ts`:
- Around line 92-180: The global hotkey handler in useGlobalHotkey should not
run while ShortcutInput is recording a new binding. Add an early guard in the
window keydown capture logic, using the existing isRecordingShortcut state, so
matchShortcut checks and app actions are skipped during recording. Keep the
change localized to useGlobalHotkey and its shortcut handler block so
ShortcutInput can receive keys without Cmd+P/Cmd+T/etc. triggering.
---
Nitpick comments:
In `@src/GraphView.tsx`:
- Around line 35-51: The `cz` value in `buildFolderCentroids` is currently
unused because the graph only applies `folderX` and `folderY` forces and
`ForceGraph3D` is still set to `numDimensions={2}`. Update the `GraphView` setup
to either add a `folderZ` force that consumes the centroid `cz` values and
switch `ForceGraph3D` to 3 dimensions, or remove `cz` from
`buildFolderCentroids` and related centroid data to keep the layout logic
consistent.
- Around line 158-165: The GraphView note target parsing in the markdown-link
branch is still missing wikilink alias handling: when processing `note.content`,
`targetId` should strip any `|display text` portion from `[[Note|Display]]`
before normalizing and appending `.md`, so the resolved ID matches the actual
node. Update the parsing logic alongside the existing `reMd`/`targets.add` flow
in `GraphView` to preserve current guards while correctly resolving aliased
wikilinks.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 4069dcc3-1a4b-430f-965e-8d09e6a125aa
📒 Files selected for processing (17)
AUDIT_LOG.mdCHANGELOG.mdnotes/New Features in v0.5.6.mdpackage.jsonsrc-tauri/Cargo.tomlsrc-tauri/tauri.conf.jsonsrc/App.tsxsrc/GraphView.tsxsrc/Settings.tsxsrc/components/KeybindsModal.tsxsrc/components/ShortcutInput.tsxsrc/components/TimersPage.tsxsrc/hooks/useGlobalHotkey.tssrc/lib/settingsKeys.tssrc/setupTests.tssrc/store/useAppStore.tssrc/store/useTimerStore.ts
💤 Files with no reviewable changes (1)
- src/components/TimersPage.tsx
Description
This release bumps the application version to v0.5.6 and introduces key workflow and UX enhancements:
Cmd+Shift+S) to view and remap all application shortcuts with live recording. Designed with centered 3D keycaps and layout structure unified with the main Settings window.Cmd+Rand Timers panel toCmd+T.[Note](Note.md)) and wikilinks ([[Note]]).Pre-PR Verification
npm run lint— Passed (0 errors, 0 warnings).npx vitest run— Passed (35 tests passed across 8 suites).Performance Reporting (Vite Build Output)
Summary by CodeRabbit
New Features
Bug Fixes
Chores