Skip to content

Commit a59360a

Browse files
committed
feat: add keybinds settings modal, auto-delete expired timers, and bump version to v0.5.6
1 parent bacc1e5 commit a59360a

17 files changed

Lines changed: 678 additions & 216 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.
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` so completion notifications and auto-cleanup function globally even when the panel is closed.
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]]`) in addition to `/file` links, and added z-axis centering forces (`centerZ`, `folderZ`) for improved 3D layout stability.
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: 42 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,24 @@ function App() {
6570
type: 'info',
6671
})
6772
})
73+
74+
useTimerStore.getState().cleanExpiredTimers()
75+
76+
let unlistenTimer: (() => void) | undefined
77+
listen<string>('timer-complete', (event) => {
78+
const id = event.payload
79+
useTimerStore.getState().completeTimer(id)
80+
const t = useTimerStore.getState().timers.find((x) => x.id === id)
81+
useAppStore
82+
.getState()
83+
.addToast({ message: `⏱ Timer done: ${t?.label || ''}`, type: 'success' })
84+
}).then((fn) => {
85+
unlistenTimer = fn
86+
})
87+
6888
return () => {
6989
disposeUpdateReady()
90+
unlistenTimer?.()
7091
}
7192
}, [])
7293

@@ -231,7 +252,8 @@ function App() {
231252
left: 0,
232253
right: 0,
233254
bottom: 0,
234-
backgroundColor: bgType === 'color' ? bgColor : '#1a1a1a',
255+
backgroundColor: 'rgba(0, 0, 0, 0.75)',
256+
backdropFilter: 'blur(5px)',
235257
zIndex: 9999,
236258
overflow: 'auto',
237259
}}
@@ -240,6 +262,25 @@ function App() {
240262
</div>
241263
)}
242264

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

src/GraphView.tsx

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ interface GraphLink {
3232
target: string
3333
}
3434

35-
function buildFolderCentroids(folderNames: string[]): Map<string, { cx: number; cy: number }> {
36-
const centroids = new Map<string, { cx: number; cy: number }>()
35+
function buildFolderCentroids(
36+
folderNames: string[]
37+
): Map<string, { cx: number; cy: number; cz: number }> {
38+
const centroids = new Map<string, { cx: number; cy: number; cz: number }>()
3739
const n = folderNames.length
3840
if (n === 0) return centroids
3941
const radius = 60
@@ -42,6 +44,7 @@ function buildFolderCentroids(folderNames: string[]): Map<string, { cx: number;
4244
centroids.set(folder, {
4345
cx: radius * Math.cos(angle),
4446
cy: radius * Math.sin(angle),
47+
cz: (i % 2 === 0 ? 1 : -1) * (15 * (i % 3)),
4548
})
4649
})
4750
return centroids
@@ -141,15 +144,39 @@ export default function GraphView({
141144
const nodeIds = new Set(nodes.map((n) => n.id))
142145

143146
notes.forEach((note) => {
144-
const re = /\]\(\/file\s+([^)]+)\)/g
147+
const targets = new Set<string>()
148+
149+
// 1. Match ](/file <path>)
150+
const reFile = /\]\(\/file\s+([^)]+)\)/g
145151
let match
146-
while ((match = re.exec(note.content)) !== null) {
152+
while ((match = reFile.exec(note.content)) !== null) {
153+
let targetId = match[1].trim().replace(/\\/g, '/')
154+
if (!targetId.endsWith('.md')) targetId += '.md'
155+
targets.add(targetId)
156+
}
157+
158+
// 2. Match ](<path>.md)
159+
const reMd = /\]\(([^)]+\.md)\)/g
160+
while ((match = reMd.exec(note.content)) !== null) {
161+
let targetId = match[1].trim().replace(/\\/g, '/')
162+
if (targetId.startsWith('./')) targetId = targetId.slice(2)
163+
if (targetId.startsWith('/')) targetId = targetId.slice(1)
164+
targets.add(targetId)
165+
}
166+
167+
// 3. Match [[<title>]]
168+
const reWiki = /\[\[([^\]]+)\]\]/g
169+
while ((match = reWiki.exec(note.content)) !== null) {
147170
let targetId = match[1].trim().replace(/\\/g, '/')
148171
if (!targetId.endsWith('.md')) targetId += '.md'
149-
if (nodeIds.has(targetId)) {
172+
targets.add(targetId)
173+
}
174+
175+
targets.forEach((targetId) => {
176+
if (nodeIds.has(targetId) && targetId !== note.id) {
150177
links.push({ source: note.id, target: targetId })
151178
}
152-
}
179+
})
153180
})
154181

155182
return { nodes, links }

0 commit comments

Comments
 (0)