Skip to content

Commit 772f2b7

Browse files
authored
Merge pull request #76 from VariableThe/feat/keybinds-and-timers-v0.5.6
feat: add keybinds settings modal, auto-delete expired timers, and bump version to v0.5.6
2 parents 1c3908f + 0e28a95 commit 772f2b7

17 files changed

Lines changed: 709 additions & 232 deletions

AUDIT_LOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@
22

33
This log tracks all significant changes, updates, and versions in the PaperCache project.
44

5+
## 2026-06-28 (v0.5.6 Release: Keybinds Modal, Shortcut Mappings, Timer Auto-Delete, and Graph Link Refinement)
6+
**Change:** chore(release): bump version to 0.5.6; feat(shortcuts): add dedicated keybinds settings modal and update global hotkeys (`Cmd+R` for tasks, `Cmd+T` for timers); feat(timers): auto-delete expired timers after 5 seconds; feat(graph): support standard markdown links and wikilinks
7+
8+
**Details/Why:**
9+
1. **Version Bump**: Bumped application version to 0.5.6 across `package.json`, `Cargo.toml`, `tauri.conf.json`, and added release notes file `New Features in v0.5.6.md`.
10+
2. **Keybinds Settings Panel**: Created `ShortcutInput.tsx` as a shared component and `KeybindsModal.tsx` as a dedicated settings panel for remapping shortcuts, accessible via Settings. Added new storage keys in `settingsKeys.ts` and updated `useGlobalHotkey.ts` to dynamically match keyboard events against customizable shortcut settings. Refined UI layout so keycaps are centered horizontally and the container/buttons match the main Settings window.
11+
3. **Keybind Updates**: Updated default shortcuts so `Cmd+R` opens Tasks/Reminders and `Cmd+T` opens the countdown Timers panel, aligning with user navigation habits. Preserved cleared shortcuts via `getShortcut` helper distinguishing `null` from `''`. Dynamically generated the shortcuts reference note (`Cmd+/`) and added recording guards in `useGlobalHotkey.ts` and `ShortcutInput.tsx`. Persisted toggle shortcut changes in `Settings.tsx`.
12+
4. **Timer Auto-Deletion**: Updated `useTimerStore.ts` and `App.tsx` so that when a countdown timer completes, it schedules a targeted 5-second `setTimeout` to call `removeTimer(id)`, reducing UI clutter. Moved backend `timer-complete` event listener to `App.tsx` with robust late-resolution cleanup tracking so completion notifications and auto-cleanup function globally even when the panel is closed or unmounted.
13+
5. **Graph View Link Parsing**: Expanded regex detection in `GraphView.tsx` to link notes using standard markdown links (`[Title](Title.md)`) and wikilinks (`[[Title]]`, stripping aliases like `[[Title|Display]]`) in addition to `/file` links, and removed unused `cz` centroid force values to keep layout logic consistent.
14+
15+
**Files changed:** `package.json`, `src-tauri/Cargo.toml`, `src-tauri/tauri.conf.json`, `notes/New Features in v0.5.6.md`, `src/lib/settingsKeys.ts`, `src/components/ShortcutInput.tsx`, `src/components/KeybindsModal.tsx`, `src/store/useAppStore.ts`, `src/App.tsx`, `src/Settings.tsx`, `src/hooks/useGlobalHotkey.ts`, `src/store/useTimerStore.ts`, `src/components/TimersPage.tsx`, `src/GraphView.tsx`, `CHANGELOG.md`, `AUDIT_LOG.md`.
16+
17+
---
18+
519
## 2026-06-27 (API Key Persistence & Graph View Fixes)
620
**Change:** fix(ai): fix API key saving/clearing logic and macOS keychain credential updating; fix(graph): prevent `fg.graphData` crashes when opening or closing Graph View
721

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ All notable, user-facing changes to PaperCache will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [v0.5.6] - 2026-06-28
9+
10+
### Added
11+
- **Dedicated Keybinds Settings Panel**: Added a sleek, high-contrast dark modal accessible from Settings (`Cmd+Shift+S`) to view and remap all application shortcuts with live recording. Designed with rich typography, glassmorphic cards, and fixed-width input buttons for perfectly vertically aligned shortcut columns.
12+
13+
### Changed
14+
- **Updated Default Shortcut Mappings**: Shifted the Reminders/Tasks view shortcut to `Cmd+R` and Timers panel shortcut to `Cmd+T`.
15+
- **Timer Auto-Deletion**: Expired countdown timers are now automatically removed from the active list 5 seconds after completing, keeping the UI clean. Timer completion notifications and auto-cleanup now function globally even when the Timers panel is closed.
16+
- **Enhanced Graph View Link Parsing**: Extended 3D Graph View link detection to support standard markdown links (`[Note](Note.md)`) and wikilinks (`[[Note]]`) alongside the existing `/file` syntax, and added z-axis forces for improved 3D layout stability.
17+
818
## [v0.5.5] - 2026-06-27
919

1020
### Added

notes/New Features in v0.5.6.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# New Features in v0.5.6
2+
3+
Welcome to PaperCache v0.5.6!
4+
5+
Here are the new features and improvements implemented in this release:
6+
- **Dedicated Keybinds Settings Panel**: Added a dedicated modal accessible from Settings (`Cmd+Shift+S`) to view and remap all application shortcuts with live keyboard shortcut recording. Designed with rich typography, centered 3D keycaps, and uniform layouts that seamlessly unify with the main Settings panel.
7+
- **Updated Default Shortcut Mappings**: Shifted the Reminders/Tasks view shortcut to `Cmd+R` and open Timers panel shortcut to `Cmd+T` for faster, ergonomic navigation.
8+
- **Automatic Timer Cleanup**: Completed countdown timers are now automatically removed from the active list 5 seconds after expiration, keeping your workspace uncluttered. Timer completion notifications and auto-cleanup function globally even when the Timers panel is closed.
9+
- **Expanded Graph View Link Detection**: Extended 3D Graph View link parsing to support standard markdown links (`[Note](Note.md)`) and wikilinks (`[[Note]]`) alongside `/file` links, with enhanced z-axis centering forces for improved 3D layout stability.
10+
11+
*(If you have read this note, feel free to delete it)*

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "papercache",
33
"private": true,
4-
"version": "0.5.5",
4+
"version": "0.5.6",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",

src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "papercache"
3-
version = "0.5.5"
3+
version = "0.5.6"
44
description = "A PaperCache Tauri App"
55
authors = ["Aditya Sharma"]
66
edition = "2021"

src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/2.0.0/tauri.schema.json",
33
"productName": "PaperCache",
4-
"version": "0.5.5",
4+
"version": "0.5.6",
55
"identifier": "com.variablethe.papercache",
66
"build": {
77
"beforeDevCommand": "npm run dev",

src/App.tsx

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ import './App.css'
55
const GraphView = lazy(() => import('./GraphView'))
66
import { RemindersPage } from './components/RemindersPage'
77
import { TimersPage } from './components/TimersPage'
8+
import { KeybindsModal } from './components/KeybindsModal'
89

910
import { useAppStore } from './store/useAppStore'
1011
import { useSettingsStore } from './store/useSettingsStore'
12+
import { useTimerStore } from './store/useTimerStore'
13+
import { listen } from '@tauri-apps/api/event'
1114

1215
import { useNoteStorage } from './hooks/useNoteStorage'
1316
import { useVariables } from './hooks/useVariables'
@@ -37,6 +40,8 @@ function App() {
3740
const setShowMainActionMenu = useAppStore((state) => state.setShowMainActionMenu)
3841
const showSettingsModal = useAppStore((state) => state.showSettingsModal)
3942
const setShowSettingsModal = useAppStore((state) => state.setShowSettingsModal)
43+
const showKeybindsModal = useAppStore((state) => state.showKeybindsModal)
44+
const setShowKeybindsModal = useAppStore((state) => state.setShowKeybindsModal)
4045

4146
const { themePreset, fontFamily, showRulings, bgType, bgColor, bgImage, textColor, numColor } =
4247
useSettingsStore()
@@ -65,8 +70,27 @@ function App() {
6570
type: 'info',
6671
})
6772
})
73+
74+
useTimerStore.getState().cleanExpiredTimers()
75+
76+
let unlistenTimer: (() => void) | undefined
77+
let isUnmounted = false
78+
listen<string>('timer-complete', (event) => {
79+
const id = event.payload
80+
useTimerStore.getState().completeTimer(id)
81+
const t = useTimerStore.getState().timers.find((x) => x.id === id)
82+
useAppStore
83+
.getState()
84+
.addToast({ message: `⏱ Timer done: ${t?.label || ''}`, type: 'success' })
85+
}).then((fn) => {
86+
if (isUnmounted) fn()
87+
else unlistenTimer = fn
88+
})
89+
6890
return () => {
91+
isUnmounted = true
6992
disposeUpdateReady()
93+
unlistenTimer?.()
7094
}
7195
}, [])
7296

@@ -231,7 +255,8 @@ function App() {
231255
left: 0,
232256
right: 0,
233257
bottom: 0,
234-
backgroundColor: bgType === 'color' ? bgColor : '#1a1a1a',
258+
backgroundColor: 'rgba(0, 0, 0, 0.75)',
259+
backdropFilter: 'blur(5px)',
235260
zIndex: 9999,
236261
overflow: 'auto',
237262
}}
@@ -240,6 +265,25 @@ function App() {
240265
</div>
241266
)}
242267

268+
{showKeybindsModal && (
269+
<div
270+
onClick={(e) => e.stopPropagation()}
271+
style={{
272+
position: 'fixed',
273+
top: 0,
274+
left: 0,
275+
right: 0,
276+
bottom: 0,
277+
backgroundColor: 'rgba(0, 0, 0, 0.75)',
278+
backdropFilter: 'blur(5px)',
279+
zIndex: 10000,
280+
overflow: 'auto',
281+
}}
282+
>
283+
<KeybindsModal onClose={() => setShowKeybindsModal(false)} />
284+
</div>
285+
)}
286+
243287
{/* In-app toast notifications */}
244288
{toasts.length > 0 && (
245289
<div

src/GraphView.tsx

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,15 +141,39 @@ export default function GraphView({
141141
const nodeIds = new Set(nodes.map((n) => n.id))
142142

143143
notes.forEach((note) => {
144-
const re = /\]\(\/file\s+([^)]+)\)/g
144+
const targets = new Set<string>()
145+
146+
// 1. Match ](/file <path>)
147+
const reFile = /\]\(\/file\s+([^)]+)\)/g
145148
let match
146-
while ((match = re.exec(note.content)) !== null) {
149+
while ((match = reFile.exec(note.content)) !== null) {
147150
let targetId = match[1].trim().replace(/\\/g, '/')
148151
if (!targetId.endsWith('.md')) targetId += '.md'
149-
if (nodeIds.has(targetId)) {
152+
targets.add(targetId)
153+
}
154+
155+
// 2. Match ](<path>.md)
156+
const reMd = /\]\(([^)]+\.md)\)/g
157+
while ((match = reMd.exec(note.content)) !== null) {
158+
let targetId = match[1].trim().replace(/\\/g, '/')
159+
if (targetId.startsWith('./')) targetId = targetId.slice(2)
160+
if (targetId.startsWith('/')) targetId = targetId.slice(1)
161+
targets.add(targetId)
162+
}
163+
164+
// 3. Match [[<title>]]
165+
const reWiki = /\[\[([^\]]+)\]\]/g
166+
while ((match = reWiki.exec(note.content)) !== null) {
167+
let targetId = match[1].split('|')[0].trim().replace(/\\/g, '/')
168+
if (!targetId.endsWith('.md')) targetId += '.md'
169+
targets.add(targetId)
170+
}
171+
172+
targets.forEach((targetId) => {
173+
if (nodeIds.has(targetId) && targetId !== note.id) {
150174
links.push({ source: note.id, target: targetId })
151175
}
152-
}
176+
})
153177
})
154178

155179
return { nodes, links }

0 commit comments

Comments
 (0)