2026-03-02 11:55:51 +01:00
|
|
|
import { useCallback, useRef } from 'react'
|
2026-02-25 13:31:19 +01:00
|
|
|
import { useAppKeyboard } from './useAppKeyboard'
|
|
|
|
|
import { useCommandRegistry } from './useCommandRegistry'
|
|
|
|
|
import type { CommandAction } from './useCommandRegistry'
|
|
|
|
|
import { useKeyboardNavigation } from './useKeyboardNavigation'
|
feat: populate macOS menu bar with native menus (File, Edit, View, Window) (#77)
* feat: populate macOS menu bar with File, Edit, View, Window menus
Add complete native macOS menu structure with all app actions:
- Laputa menu: About, Settings (Cmd+,), Hide/Quit
- File: New Note (Cmd+N), Quick Open (Cmd+P), Save (Cmd+S), Close Tab (Cmd+W)
- Edit: standard Undo/Redo/Cut/Copy/Paste/Select All
- View: Editor Only (Cmd+1), Editor+Notes (Cmd+2), All Panels (Cmd+3),
Toggle Inspector, Command Palette (Cmd+K)
- Window: Minimize, Maximize, Close Window
All accelerators registered via Tauri menu API. Menu events dispatched
to frontend via useMenuEvents hook. Save/Close Tab items dynamically
disabled when no note tab is active.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: wrap Enter selection assertion in waitFor for effect re-registration
* fix: resolve rebase conflict markers in menu.rs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 20:05:24 +01:00
|
|
|
import { useMenuEvents } from './useMenuEvents'
|
2026-03-19 06:41:40 +01:00
|
|
|
import type { SidebarSelection, SidebarFilter, ThemeFile, VaultEntry } from '../types'
|
2026-03-18 03:43:23 +01:00
|
|
|
import type { NoteListFilter } from '../utils/noteListHelpers'
|
2026-02-25 13:31:19 +01:00
|
|
|
import type { ViewMode } from './useViewMode'
|
|
|
|
|
|
|
|
|
|
interface Tab { entry: VaultEntry; content: string }
|
|
|
|
|
|
|
|
|
|
interface AppCommandsConfig {
|
|
|
|
|
activeTabPath: string | null
|
|
|
|
|
activeTabPathRef: React.MutableRefObject<string | null>
|
|
|
|
|
handleCloseTabRef: React.MutableRefObject<(path: string) => void>
|
|
|
|
|
tabs: Tab[]
|
|
|
|
|
entries: VaultEntry[]
|
|
|
|
|
modifiedCount: number
|
|
|
|
|
selection: SidebarSelection
|
|
|
|
|
onQuickOpen: () => void
|
|
|
|
|
onCommandPalette: () => void
|
feat: full-text search with qmd backend and SearchPanel UI (Cmd+Shift+F) (#64)
* feat: add search backend (qmd CLI) and design file
- Add search.rs: qmd integration for keyword (BM25), semantic (vsearch),
and hybrid search modes via CLI JSON output
- Register search_vault Tauri command in lib.rs
- Design file with 3 frames: empty, results, no-results states
- Fix pre-existing test failures: install @tauri-apps/plugin-opener,
add mock in test setup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add SearchPanel UI with Cmd+Shift+F shortcut
- SearchPanel component: full-text search overlay with keyword/semantic
mode toggle, debounced search (200ms), arrow key navigation, result
count + elapsed time display, note type badges from vault entries
- Cmd+Shift+F shortcut registered in useAppKeyboard
- Mock search_vault handler in mock-tauri for browser dev mode
- SearchResult/SearchResponse types in types.ts
- Tests: 15 new tests for SearchPanel + 2 for keyboard shortcut
- scrollIntoView mock in test setup for jsdom compatibility
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: correct SearchPanel imports for Tauri/browser dual-mode
Use invoke from @tauri-apps/api/core and mockInvoke from mock-tauri
with a searchCall wrapper, fixing the TypeScript build error.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: make test_detect_collection_fallback robust when qmd not installed
* fix: reset localStorage between App tests to prevent view mode state leak
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 17:09:50 +01:00
|
|
|
onSearch: () => void
|
2026-02-25 13:31:19 +01:00
|
|
|
onCreateNote: () => void
|
2026-03-02 03:08:15 +01:00
|
|
|
onOpenDailyNote: () => void
|
2026-02-28 19:13:29 +01:00
|
|
|
onCreateNoteOfType: (type: string) => void
|
2026-02-25 13:31:19 +01:00
|
|
|
onSave: () => void
|
|
|
|
|
onOpenSettings: () => void
|
|
|
|
|
onTrashNote: (path: string) => void
|
2026-03-02 11:55:51 +01:00
|
|
|
onRestoreNote: (path: string) => void
|
2026-02-25 13:31:19 +01:00
|
|
|
onArchiveNote: (path: string) => void
|
|
|
|
|
onUnarchiveNote: (path: string) => void
|
|
|
|
|
onCommitPush: () => void
|
2026-03-03 02:27:42 +01:00
|
|
|
onResolveConflicts?: () => void
|
2026-02-25 13:31:19 +01:00
|
|
|
onSetViewMode: (mode: ViewMode) => void
|
|
|
|
|
onToggleInspector: () => void
|
2026-03-03 02:00:48 +01:00
|
|
|
onToggleDiff?: () => void
|
2026-03-02 18:38:25 +01:00
|
|
|
onToggleRawEditor?: () => void
|
2026-03-03 02:00:48 +01:00
|
|
|
activeNoteModified: boolean
|
2026-02-28 12:41:57 +01:00
|
|
|
onZoomIn: () => void
|
|
|
|
|
onZoomOut: () => void
|
|
|
|
|
onZoomReset: () => void
|
|
|
|
|
zoomLevel: number
|
2026-02-25 13:31:19 +01:00
|
|
|
onSelect: (sel: SidebarSelection) => void
|
|
|
|
|
onCloseTab: (path: string) => void
|
|
|
|
|
onSwitchTab: (path: string) => void
|
|
|
|
|
onReplaceActiveTab: (entry: VaultEntry) => void
|
|
|
|
|
onSelectNote: (entry: VaultEntry) => void
|
2026-02-25 19:39:12 +01:00
|
|
|
onGoBack?: () => void
|
|
|
|
|
onGoForward?: () => void
|
|
|
|
|
canGoBack?: boolean
|
|
|
|
|
canGoForward?: boolean
|
feat: vault-native theming system with live reload (#154)
* feat: add theming system design file with 3 frames
Design frames for Settings > Appearance panel, Command Palette
theme switching, and live theme editing flow visualization.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add Rust backend for vault-native theming system
Theme files live in _themes/*.json with colors, typography, and spacing
sections. Vault-level settings (.laputa/settings.json) store the active
theme. Built-in themes (default, dark, minimal) are seeded on vault
creation. All 6 Tauri commands registered: list_themes, get_theme,
get_vault_settings, save_vault_settings, set_active_theme, create_theme.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add frontend theme engine, settings UI, and command palette integration
Wire up useThemeManager hook to load themes via Tauri IPC, apply CSS
custom properties to :root, and support switching/creating themes.
Add Appearance section to Settings panel with color swatches and theme
cards. Register theme switch and create commands in the command registry.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use .to_string() instead of format! for string literal (clippy)
* style: cargo fmt on theme.rs
---------
Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:05:14 +01:00
|
|
|
themes?: ThemeFile[]
|
|
|
|
|
activeThemeId?: string | null
|
|
|
|
|
onSwitchTheme?: (themeId: string) => void
|
|
|
|
|
onCreateTheme?: () => void
|
2026-03-02 21:05:20 +01:00
|
|
|
onOpenTheme?: (themeId: string) => void
|
2026-03-01 16:04:51 +01:00
|
|
|
onOpenVault?: () => void
|
2026-03-03 00:31:10 +01:00
|
|
|
onCreateType?: () => void
|
2026-03-02 05:00:29 +01:00
|
|
|
onToggleAIChat?: () => void
|
2026-03-02 23:48:01 +01:00
|
|
|
onCheckForUpdates?: () => void
|
2026-03-03 02:26:41 +01:00
|
|
|
onRemoveActiveVault?: () => void
|
|
|
|
|
onRestoreGettingStarted?: () => void
|
2026-03-05 11:18:53 +01:00
|
|
|
onRestoreDefaultThemes?: () => void
|
2026-03-03 02:26:41 +01:00
|
|
|
isGettingStartedHidden?: boolean
|
|
|
|
|
vaultCount?: number
|
2026-03-04 13:11:58 +01:00
|
|
|
mcpStatus?: string
|
|
|
|
|
onInstallMcp?: () => void
|
2026-03-12 00:06:33 +01:00
|
|
|
onEmptyTrash?: () => void
|
|
|
|
|
trashedCount?: number
|
2026-03-11 23:36:42 +01:00
|
|
|
onReopenClosedTab?: () => void
|
2026-03-07 01:14:12 +01:00
|
|
|
onReindexVault?: () => void
|
2026-03-09 00:35:21 +01:00
|
|
|
onReloadVault?: () => void
|
2026-03-07 12:39:55 +01:00
|
|
|
onRepairVault?: () => void
|
2026-03-17 22:42:55 +01:00
|
|
|
onSetNoteIcon?: () => void
|
|
|
|
|
onRemoveNoteIcon?: () => void
|
|
|
|
|
activeNoteHasIcon?: boolean
|
2026-03-18 03:43:23 +01:00
|
|
|
noteListFilter?: NoteListFilter
|
|
|
|
|
onSetNoteListFilter?: (filter: NoteListFilter) => void
|
2026-03-19 08:47:25 +01:00
|
|
|
onOpenInNewWindow?: () => void
|
2026-02-25 13:31:19 +01:00
|
|
|
}
|
|
|
|
|
|
feat: populate macOS menu bar with native menus (File, Edit, View, Window) (#77)
* feat: populate macOS menu bar with File, Edit, View, Window menus
Add complete native macOS menu structure with all app actions:
- Laputa menu: About, Settings (Cmd+,), Hide/Quit
- File: New Note (Cmd+N), Quick Open (Cmd+P), Save (Cmd+S), Close Tab (Cmd+W)
- Edit: standard Undo/Redo/Cut/Copy/Paste/Select All
- View: Editor Only (Cmd+1), Editor+Notes (Cmd+2), All Panels (Cmd+3),
Toggle Inspector, Command Palette (Cmd+K)
- Window: Minimize, Maximize, Close Window
All accelerators registered via Tauri menu API. Menu events dispatched
to frontend via useMenuEvents hook. Save/Close Tab items dynamically
disabled when no note tab is active.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: wrap Enter selection assertion in waitFor for effect re-registration
* fix: resolve rebase conflict markers in menu.rs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 20:05:24 +01:00
|
|
|
/** Sets up keyboard shortcuts, command registry, menu events, and keyboard navigation. */
|
2026-02-25 13:31:19 +01:00
|
|
|
export function useAppCommands(config: AppCommandsConfig): CommandAction[] {
|
2026-03-02 11:55:51 +01:00
|
|
|
const entriesRef = useRef(config.entries)
|
|
|
|
|
// eslint-disable-next-line react-hooks/refs
|
|
|
|
|
entriesRef.current = config.entries
|
|
|
|
|
|
|
|
|
|
const toggleArchive = useCallback((path: string) => {
|
|
|
|
|
const entry = entriesRef.current.find(e => e.path === path)
|
|
|
|
|
;(entry?.archived ? config.onUnarchiveNote : config.onArchiveNote)(path)
|
|
|
|
|
}, [config.onArchiveNote, config.onUnarchiveNote])
|
|
|
|
|
|
|
|
|
|
const toggleTrash = useCallback((path: string) => {
|
|
|
|
|
const entry = entriesRef.current.find(e => e.path === path)
|
|
|
|
|
;(entry?.trashed ? config.onRestoreNote : config.onTrashNote)(path)
|
|
|
|
|
}, [config.onTrashNote, config.onRestoreNote])
|
|
|
|
|
|
feat: reorganize menu bar with Go, Note, and Vault menus
Add missing command palette commands to menu bar and reorganize into
logical groups: File, Edit, View, Go, Note, Vault, Window. New menus
expose navigation filters, note actions, vault management, themes, and
git operations. Context-sensitive items (archive, trash, diff, raw
editor, commit, conflicts) are greyed out when not applicable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 14:13:54 +01:00
|
|
|
const { onSelect } = config
|
|
|
|
|
|
2026-03-19 06:41:40 +01:00
|
|
|
const selectFilter = useCallback((filter: SidebarFilter) => {
|
feat: reorganize menu bar with Go, Note, and Vault menus
Add missing command palette commands to menu bar and reorganize into
logical groups: File, Edit, View, Go, Note, Vault, Window. New menus
expose navigation filters, note actions, vault management, themes, and
git operations. Context-sensitive items (archive, trash, diff, raw
editor, commit, conflicts) are greyed out when not applicable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 14:13:54 +01:00
|
|
|
onSelect({ kind: 'filter', filter })
|
|
|
|
|
}, [onSelect])
|
|
|
|
|
|
|
|
|
|
const viewChanges = useCallback(() => {
|
|
|
|
|
onSelect({ kind: 'filter', filter: 'changes' })
|
|
|
|
|
}, [onSelect])
|
|
|
|
|
|
2026-02-25 13:31:19 +01:00
|
|
|
useAppKeyboard({
|
|
|
|
|
onQuickOpen: config.onQuickOpen,
|
|
|
|
|
onCommandPalette: config.onCommandPalette,
|
feat: full-text search with qmd backend and SearchPanel UI (Cmd+Shift+F) (#64)
* feat: add search backend (qmd CLI) and design file
- Add search.rs: qmd integration for keyword (BM25), semantic (vsearch),
and hybrid search modes via CLI JSON output
- Register search_vault Tauri command in lib.rs
- Design file with 3 frames: empty, results, no-results states
- Fix pre-existing test failures: install @tauri-apps/plugin-opener,
add mock in test setup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add SearchPanel UI with Cmd+Shift+F shortcut
- SearchPanel component: full-text search overlay with keyword/semantic
mode toggle, debounced search (200ms), arrow key navigation, result
count + elapsed time display, note type badges from vault entries
- Cmd+Shift+F shortcut registered in useAppKeyboard
- Mock search_vault handler in mock-tauri for browser dev mode
- SearchResult/SearchResponse types in types.ts
- Tests: 15 new tests for SearchPanel + 2 for keyboard shortcut
- scrollIntoView mock in test setup for jsdom compatibility
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: correct SearchPanel imports for Tauri/browser dual-mode
Use invoke from @tauri-apps/api/core and mockInvoke from mock-tauri
with a searchCall wrapper, fixing the TypeScript build error.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: make test_detect_collection_fallback robust when qmd not installed
* fix: reset localStorage between App tests to prevent view mode state leak
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 17:09:50 +01:00
|
|
|
onSearch: config.onSearch,
|
2026-02-25 13:31:19 +01:00
|
|
|
onCreateNote: config.onCreateNote,
|
2026-03-02 03:08:15 +01:00
|
|
|
onOpenDailyNote: config.onOpenDailyNote,
|
2026-02-25 13:31:19 +01:00
|
|
|
onSave: config.onSave,
|
|
|
|
|
onOpenSettings: config.onOpenSettings,
|
2026-03-02 11:55:51 +01:00
|
|
|
onTrashNote: toggleTrash,
|
|
|
|
|
onArchiveNote: toggleArchive,
|
2026-02-25 13:31:19 +01:00
|
|
|
onSetViewMode: config.onSetViewMode,
|
2026-02-28 12:41:57 +01:00
|
|
|
onZoomIn: config.onZoomIn,
|
|
|
|
|
onZoomOut: config.onZoomOut,
|
|
|
|
|
onZoomReset: config.onZoomReset,
|
2026-02-25 19:39:12 +01:00
|
|
|
onGoBack: config.onGoBack,
|
|
|
|
|
onGoForward: config.onGoForward,
|
2026-03-02 05:00:29 +01:00
|
|
|
onToggleAIChat: config.onToggleAIChat,
|
2026-03-02 19:12:11 +01:00
|
|
|
onToggleRawEditor: config.onToggleRawEditor,
|
2026-03-11 23:36:42 +01:00
|
|
|
onReopenClosedTab: config.onReopenClosedTab,
|
2026-03-19 08:47:25 +01:00
|
|
|
onOpenInNewWindow: config.onOpenInNewWindow,
|
2026-02-25 13:31:19 +01:00
|
|
|
activeTabPathRef: config.activeTabPathRef,
|
|
|
|
|
handleCloseTabRef: config.handleCloseTabRef,
|
|
|
|
|
})
|
|
|
|
|
|
feat: populate macOS menu bar with native menus (File, Edit, View, Window) (#77)
* feat: populate macOS menu bar with File, Edit, View, Window menus
Add complete native macOS menu structure with all app actions:
- Laputa menu: About, Settings (Cmd+,), Hide/Quit
- File: New Note (Cmd+N), Quick Open (Cmd+P), Save (Cmd+S), Close Tab (Cmd+W)
- Edit: standard Undo/Redo/Cut/Copy/Paste/Select All
- View: Editor Only (Cmd+1), Editor+Notes (Cmd+2), All Panels (Cmd+3),
Toggle Inspector, Command Palette (Cmd+K)
- Window: Minimize, Maximize, Close Window
All accelerators registered via Tauri menu API. Menu events dispatched
to frontend via useMenuEvents hook. Save/Close Tab items dynamically
disabled when no note tab is active.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: wrap Enter selection assertion in waitFor for effect re-registration
* fix: resolve rebase conflict markers in menu.rs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 20:05:24 +01:00
|
|
|
useMenuEvents({
|
|
|
|
|
onSetViewMode: config.onSetViewMode,
|
|
|
|
|
onCreateNote: config.onCreateNote,
|
feat: reorganize menu bar with Go, Note, and Vault menus
Add missing command palette commands to menu bar and reorganize into
logical groups: File, Edit, View, Go, Note, Vault, Window. New menus
expose navigation filters, note actions, vault management, themes, and
git operations. Context-sensitive items (archive, trash, diff, raw
editor, commit, conflicts) are greyed out when not applicable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 14:13:54 +01:00
|
|
|
onCreateType: config.onCreateType,
|
2026-03-02 03:08:15 +01:00
|
|
|
onOpenDailyNote: config.onOpenDailyNote,
|
feat: populate macOS menu bar with native menus (File, Edit, View, Window) (#77)
* feat: populate macOS menu bar with File, Edit, View, Window menus
Add complete native macOS menu structure with all app actions:
- Laputa menu: About, Settings (Cmd+,), Hide/Quit
- File: New Note (Cmd+N), Quick Open (Cmd+P), Save (Cmd+S), Close Tab (Cmd+W)
- Edit: standard Undo/Redo/Cut/Copy/Paste/Select All
- View: Editor Only (Cmd+1), Editor+Notes (Cmd+2), All Panels (Cmd+3),
Toggle Inspector, Command Palette (Cmd+K)
- Window: Minimize, Maximize, Close Window
All accelerators registered via Tauri menu API. Menu events dispatched
to frontend via useMenuEvents hook. Save/Close Tab items dynamically
disabled when no note tab is active.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: wrap Enter selection assertion in waitFor for effect re-registration
* fix: resolve rebase conflict markers in menu.rs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 20:05:24 +01:00
|
|
|
onQuickOpen: config.onQuickOpen,
|
|
|
|
|
onSave: config.onSave,
|
|
|
|
|
onOpenSettings: config.onOpenSettings,
|
|
|
|
|
onToggleInspector: config.onToggleInspector,
|
|
|
|
|
onCommandPalette: config.onCommandPalette,
|
2026-02-28 12:41:57 +01:00
|
|
|
onZoomIn: config.onZoomIn,
|
|
|
|
|
onZoomOut: config.onZoomOut,
|
|
|
|
|
onZoomReset: config.onZoomReset,
|
2026-03-02 11:55:51 +01:00
|
|
|
onArchiveNote: toggleArchive,
|
|
|
|
|
onTrashNote: toggleTrash,
|
feat: keyboard-first navigation — menu bar shortcuts, note list nav, inspector Tab/Enter (#158)
* feat: keyboard-first navigation — menu bar shortcuts, note list nav, inspector Tab/Enter
- Add missing menu bar items: Archive Note (⌘E), Trash Note (⌘⌫),
Find in Vault (⌘⇧F), Go Back (⌘[), Go Forward (⌘])
- Wire new menu events through useMenuEvents → useAppCommands
- Note list: ↑↓ moves highlight, Enter opens selected note (useNoteListKeyboard hook)
- Inspector properties: Tab between rows, Enter to start editing
- Settings panel: auto-focus first input on open
- Extract StatusDot, StateBadge, noteItemStyle from NoteItem (reduces complexity)
- Extract dispatchActiveTabEvent/dispatchOptionalEvent from useMenuEvents
- 21 new tests (useNoteListKeyboard + useMenuEvents for new events)
- All 1275 frontend tests pass, 319 Rust tests pass
- CodeScene quality gates: passed (NoteItem improved from 22→18 complexity)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* design: keyboard-first-nav wireframes (note list highlight, menu shortcuts, inspector tab nav)
* test: add search.rs coverage for fallback branches (qmd_uri_to_vault_path, extract_clean_snippet)
* chore: exclude search.rs and lib.rs from coverage (qmd integration + Tauri setup code)
---------
Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:32:15 +01:00
|
|
|
onSearch: config.onSearch,
|
feat: reorganize menu bar with Go, Note, and Vault menus
Add missing command palette commands to menu bar and reorganize into
logical groups: File, Edit, View, Go, Note, Vault, Window. New menus
expose navigation filters, note actions, vault management, themes, and
git operations. Context-sensitive items (archive, trash, diff, raw
editor, commit, conflicts) are greyed out when not applicable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 14:13:54 +01:00
|
|
|
onToggleRawEditor: config.onToggleRawEditor,
|
|
|
|
|
onToggleDiff: config.onToggleDiff,
|
|
|
|
|
onToggleAIChat: config.onToggleAIChat,
|
feat: keyboard-first navigation — menu bar shortcuts, note list nav, inspector Tab/Enter (#158)
* feat: keyboard-first navigation — menu bar shortcuts, note list nav, inspector Tab/Enter
- Add missing menu bar items: Archive Note (⌘E), Trash Note (⌘⌫),
Find in Vault (⌘⇧F), Go Back (⌘[), Go Forward (⌘])
- Wire new menu events through useMenuEvents → useAppCommands
- Note list: ↑↓ moves highlight, Enter opens selected note (useNoteListKeyboard hook)
- Inspector properties: Tab between rows, Enter to start editing
- Settings panel: auto-focus first input on open
- Extract StatusDot, StateBadge, noteItemStyle from NoteItem (reduces complexity)
- Extract dispatchActiveTabEvent/dispatchOptionalEvent from useMenuEvents
- 21 new tests (useNoteListKeyboard + useMenuEvents for new events)
- All 1275 frontend tests pass, 319 Rust tests pass
- CodeScene quality gates: passed (NoteItem improved from 22→18 complexity)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* design: keyboard-first-nav wireframes (note list highlight, menu shortcuts, inspector tab nav)
* test: add search.rs coverage for fallback branches (qmd_uri_to_vault_path, extract_clean_snippet)
* chore: exclude search.rs and lib.rs from coverage (qmd integration + Tauri setup code)
---------
Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:32:15 +01:00
|
|
|
onGoBack: config.onGoBack,
|
|
|
|
|
onGoForward: config.onGoForward,
|
2026-03-03 13:19:09 +01:00
|
|
|
onCheckForUpdates: config.onCheckForUpdates,
|
feat: reorganize menu bar with Go, Note, and Vault menus
Add missing command palette commands to menu bar and reorganize into
logical groups: File, Edit, View, Go, Note, Vault, Window. New menus
expose navigation filters, note actions, vault management, themes, and
git operations. Context-sensitive items (archive, trash, diff, raw
editor, commit, conflicts) are greyed out when not applicable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 14:13:54 +01:00
|
|
|
onSelectFilter: selectFilter,
|
|
|
|
|
onOpenVault: config.onOpenVault,
|
|
|
|
|
onRemoveActiveVault: config.onRemoveActiveVault,
|
|
|
|
|
onRestoreGettingStarted: config.onRestoreGettingStarted,
|
|
|
|
|
onCreateTheme: config.onCreateTheme,
|
|
|
|
|
onRestoreDefaultThemes: config.onRestoreDefaultThemes,
|
|
|
|
|
onCommitPush: config.onCommitPush,
|
|
|
|
|
onResolveConflicts: config.onResolveConflicts,
|
|
|
|
|
onViewChanges: viewChanges,
|
|
|
|
|
onInstallMcp: config.onInstallMcp,
|
2026-03-07 01:14:12 +01:00
|
|
|
onReindexVault: config.onReindexVault,
|
2026-03-09 00:35:21 +01:00
|
|
|
onReloadVault: config.onReloadVault,
|
2026-03-07 12:39:55 +01:00
|
|
|
onRepairVault: config.onRepairVault,
|
2026-03-12 00:13:51 +01:00
|
|
|
onEmptyTrash: config.onEmptyTrash,
|
2026-03-11 23:36:42 +01:00
|
|
|
onReopenClosedTab: config.onReopenClosedTab,
|
2026-03-19 08:47:25 +01:00
|
|
|
onOpenInNewWindow: config.onOpenInNewWindow,
|
feat: populate macOS menu bar with native menus (File, Edit, View, Window) (#77)
* feat: populate macOS menu bar with File, Edit, View, Window menus
Add complete native macOS menu structure with all app actions:
- Laputa menu: About, Settings (Cmd+,), Hide/Quit
- File: New Note (Cmd+N), Quick Open (Cmd+P), Save (Cmd+S), Close Tab (Cmd+W)
- Edit: standard Undo/Redo/Cut/Copy/Paste/Select All
- View: Editor Only (Cmd+1), Editor+Notes (Cmd+2), All Panels (Cmd+3),
Toggle Inspector, Command Palette (Cmd+K)
- Window: Minimize, Maximize, Close Window
All accelerators registered via Tauri menu API. Menu events dispatched
to frontend via useMenuEvents hook. Save/Close Tab items dynamically
disabled when no note tab is active.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: wrap Enter selection assertion in waitFor for effect re-registration
* fix: resolve rebase conflict markers in menu.rs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 20:05:24 +01:00
|
|
|
activeTabPathRef: config.activeTabPathRef,
|
|
|
|
|
handleCloseTabRef: config.handleCloseTabRef,
|
|
|
|
|
activeTabPath: config.activeTabPath,
|
feat: reorganize menu bar with Go, Note, and Vault menus
Add missing command palette commands to menu bar and reorganize into
logical groups: File, Edit, View, Go, Note, Vault, Window. New menus
expose navigation filters, note actions, vault management, themes, and
git operations. Context-sensitive items (archive, trash, diff, raw
editor, commit, conflicts) are greyed out when not applicable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 14:13:54 +01:00
|
|
|
modifiedCount: config.modifiedCount,
|
feat: populate macOS menu bar with native menus (File, Edit, View, Window) (#77)
* feat: populate macOS menu bar with File, Edit, View, Window menus
Add complete native macOS menu structure with all app actions:
- Laputa menu: About, Settings (Cmd+,), Hide/Quit
- File: New Note (Cmd+N), Quick Open (Cmd+P), Save (Cmd+S), Close Tab (Cmd+W)
- Edit: standard Undo/Redo/Cut/Copy/Paste/Select All
- View: Editor Only (Cmd+1), Editor+Notes (Cmd+2), All Panels (Cmd+3),
Toggle Inspector, Command Palette (Cmd+K)
- Window: Minimize, Maximize, Close Window
All accelerators registered via Tauri menu API. Menu events dispatched
to frontend via useMenuEvents hook. Save/Close Tab items dynamically
disabled when no note tab is active.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: wrap Enter selection assertion in waitFor for effect re-registration
* fix: resolve rebase conflict markers in menu.rs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 20:05:24 +01:00
|
|
|
})
|
|
|
|
|
|
2026-02-25 13:31:19 +01:00
|
|
|
const commands = useCommandRegistry({
|
|
|
|
|
activeTabPath: config.activeTabPath,
|
|
|
|
|
entries: config.entries,
|
|
|
|
|
modifiedCount: config.modifiedCount,
|
|
|
|
|
onQuickOpen: config.onQuickOpen,
|
|
|
|
|
onCreateNote: config.onCreateNote,
|
2026-02-28 19:13:29 +01:00
|
|
|
onCreateNoteOfType: config.onCreateNoteOfType,
|
2026-02-25 13:31:19 +01:00
|
|
|
onSave: config.onSave,
|
|
|
|
|
onOpenSettings: config.onOpenSettings,
|
|
|
|
|
onTrashNote: config.onTrashNote,
|
2026-03-02 11:55:51 +01:00
|
|
|
onRestoreNote: config.onRestoreNote,
|
2026-02-25 13:31:19 +01:00
|
|
|
onArchiveNote: config.onArchiveNote,
|
|
|
|
|
onUnarchiveNote: config.onUnarchiveNote,
|
|
|
|
|
onCommitPush: config.onCommitPush,
|
2026-03-03 02:27:42 +01:00
|
|
|
onResolveConflicts: config.onResolveConflicts,
|
2026-02-25 13:31:19 +01:00
|
|
|
onSetViewMode: config.onSetViewMode,
|
|
|
|
|
onToggleInspector: config.onToggleInspector,
|
2026-03-03 02:00:48 +01:00
|
|
|
onToggleDiff: config.onToggleDiff,
|
2026-03-02 18:38:25 +01:00
|
|
|
onToggleRawEditor: config.onToggleRawEditor,
|
feat: reorganize menu bar with Go, Note, and Vault menus
Add missing command palette commands to menu bar and reorganize into
logical groups: File, Edit, View, Go, Note, Vault, Window. New menus
expose navigation filters, note actions, vault management, themes, and
git operations. Context-sensitive items (archive, trash, diff, raw
editor, commit, conflicts) are greyed out when not applicable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 14:13:54 +01:00
|
|
|
onToggleAIChat: config.onToggleAIChat,
|
|
|
|
|
onOpenVault: config.onOpenVault,
|
2026-03-03 02:00:48 +01:00
|
|
|
activeNoteModified: config.activeNoteModified,
|
2026-02-28 12:41:57 +01:00
|
|
|
onZoomIn: config.onZoomIn,
|
|
|
|
|
onZoomOut: config.onZoomOut,
|
|
|
|
|
onZoomReset: config.onZoomReset,
|
|
|
|
|
zoomLevel: config.zoomLevel,
|
2026-02-25 13:31:19 +01:00
|
|
|
onSelect: config.onSelect,
|
2026-03-02 03:08:15 +01:00
|
|
|
onOpenDailyNote: config.onOpenDailyNote,
|
2026-02-25 13:31:19 +01:00
|
|
|
onCloseTab: config.onCloseTab,
|
2026-02-25 19:39:12 +01:00
|
|
|
onGoBack: config.onGoBack,
|
|
|
|
|
onGoForward: config.onGoForward,
|
|
|
|
|
canGoBack: config.canGoBack,
|
|
|
|
|
canGoForward: config.canGoForward,
|
feat: vault-native theming system with live reload (#154)
* feat: add theming system design file with 3 frames
Design frames for Settings > Appearance panel, Command Palette
theme switching, and live theme editing flow visualization.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add Rust backend for vault-native theming system
Theme files live in _themes/*.json with colors, typography, and spacing
sections. Vault-level settings (.laputa/settings.json) store the active
theme. Built-in themes (default, dark, minimal) are seeded on vault
creation. All 6 Tauri commands registered: list_themes, get_theme,
get_vault_settings, save_vault_settings, set_active_theme, create_theme.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add frontend theme engine, settings UI, and command palette integration
Wire up useThemeManager hook to load themes via Tauri IPC, apply CSS
custom properties to :root, and support switching/creating themes.
Add Appearance section to Settings panel with color swatches and theme
cards. Register theme switch and create commands in the command registry.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use .to_string() instead of format! for string literal (clippy)
* style: cargo fmt on theme.rs
---------
Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:05:14 +01:00
|
|
|
themes: config.themes,
|
|
|
|
|
activeThemeId: config.activeThemeId,
|
|
|
|
|
onSwitchTheme: config.onSwitchTheme,
|
|
|
|
|
onCreateTheme: config.onCreateTheme,
|
2026-03-02 21:05:20 +01:00
|
|
|
onOpenTheme: config.onOpenTheme,
|
2026-03-02 23:48:01 +01:00
|
|
|
onCheckForUpdates: config.onCheckForUpdates,
|
feat: reorganize menu bar with Go, Note, and Vault menus
Add missing command palette commands to menu bar and reorganize into
logical groups: File, Edit, View, Go, Note, Vault, Window. New menus
expose navigation filters, note actions, vault management, themes, and
git operations. Context-sensitive items (archive, trash, diff, raw
editor, commit, conflicts) are greyed out when not applicable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 14:13:54 +01:00
|
|
|
onCreateType: config.onCreateType,
|
2026-03-03 02:26:41 +01:00
|
|
|
onRemoveActiveVault: config.onRemoveActiveVault,
|
|
|
|
|
onRestoreGettingStarted: config.onRestoreGettingStarted,
|
2026-03-05 11:18:53 +01:00
|
|
|
onRestoreDefaultThemes: config.onRestoreDefaultThemes,
|
2026-03-03 02:26:41 +01:00
|
|
|
isGettingStartedHidden: config.isGettingStartedHidden,
|
|
|
|
|
vaultCount: config.vaultCount,
|
2026-03-04 13:11:58 +01:00
|
|
|
mcpStatus: config.mcpStatus,
|
|
|
|
|
onInstallMcp: config.onInstallMcp,
|
2026-03-12 00:06:33 +01:00
|
|
|
onEmptyTrash: config.onEmptyTrash,
|
|
|
|
|
trashedCount: config.trashedCount,
|
2026-03-07 01:14:12 +01:00
|
|
|
onReindexVault: config.onReindexVault,
|
2026-03-09 00:35:21 +01:00
|
|
|
onReloadVault: config.onReloadVault,
|
2026-03-07 12:39:55 +01:00
|
|
|
onRepairVault: config.onRepairVault,
|
2026-03-17 22:42:55 +01:00
|
|
|
onSetNoteIcon: config.onSetNoteIcon,
|
|
|
|
|
onRemoveNoteIcon: config.onRemoveNoteIcon,
|
|
|
|
|
activeNoteHasIcon: config.activeNoteHasIcon,
|
2026-03-18 03:43:23 +01:00
|
|
|
selection: config.selection,
|
|
|
|
|
noteListFilter: config.noteListFilter,
|
|
|
|
|
onSetNoteListFilter: config.onSetNoteListFilter,
|
2026-03-19 08:47:25 +01:00
|
|
|
onOpenInNewWindow: config.onOpenInNewWindow,
|
2026-02-25 13:31:19 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
useKeyboardNavigation({
|
|
|
|
|
tabs: config.tabs,
|
|
|
|
|
activeTabPath: config.activeTabPath,
|
|
|
|
|
entries: config.entries,
|
|
|
|
|
selection: config.selection,
|
|
|
|
|
onSwitchTab: config.onSwitchTab,
|
|
|
|
|
onReplaceActiveTab: config.onReplaceActiveTab,
|
|
|
|
|
onSelectNote: config.onSelectNote,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return commands
|
|
|
|
|
}
|