feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
import { useState, useEffect, useRef, useCallback } from "react";
|
2026-03-07 08:40:16 -08:00
|
|
|
import { useNavigate } from "react-router-dom";
|
|
|
|
|
import { useVault } from "../App";
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
import { searchVault, listTemplates, createFromTemplate, exportNoteHtml, type SearchResult, type TemplateInfo } from "../lib/commands";
|
2026-03-07 08:40:16 -08:00
|
|
|
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
interface CommandItem {
|
2026-03-07 08:40:16 -08:00
|
|
|
id: string;
|
|
|
|
|
icon: string;
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
label: string;
|
|
|
|
|
hint?: string;
|
2026-03-07 08:40:16 -08:00
|
|
|
action: () => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function CommandPalette({ open, onClose }: { open: boolean; onClose: () => void }) {
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
const { vaultPath, notes, navigateToNote, currentNote } = useVault();
|
|
|
|
|
const navigate = useNavigate();
|
2026-03-07 08:40:16 -08:00
|
|
|
const [query, setQuery] = useState("");
|
|
|
|
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
const [searchResults, setSearchResults] = useState<SearchResult[]>([]);
|
|
|
|
|
const [templates, setTemplates] = useState<TemplateInfo[]>([]);
|
2026-03-07 08:40:16 -08:00
|
|
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
|
|
|
const listRef = useRef<HTMLDivElement>(null);
|
|
|
|
|
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
// Load templates when opened
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (open && vaultPath) {
|
|
|
|
|
listTemplates(vaultPath).then(setTemplates).catch(() => setTemplates([]));
|
|
|
|
|
}
|
|
|
|
|
}, [open, vaultPath]);
|
|
|
|
|
|
|
|
|
|
// Focus input when opened
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (open) {
|
|
|
|
|
setQuery("");
|
|
|
|
|
setSelectedIndex(0);
|
|
|
|
|
setSearchResults([]);
|
|
|
|
|
setTimeout(() => inputRef.current?.focus(), 50);
|
|
|
|
|
}
|
|
|
|
|
}, [open]);
|
|
|
|
|
|
|
|
|
|
// Debounced search
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!query.trim() || query.length < 2) {
|
|
|
|
|
setSearchResults([]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const timer = setTimeout(async () => {
|
|
|
|
|
try {
|
|
|
|
|
const results = await searchVault(vaultPath, query);
|
|
|
|
|
setSearchResults(results.slice(0, 10));
|
|
|
|
|
} catch {
|
|
|
|
|
setSearchResults([]);
|
|
|
|
|
}
|
|
|
|
|
}, 200);
|
|
|
|
|
|
|
|
|
|
return () => clearTimeout(timer);
|
|
|
|
|
}, [query, vaultPath]);
|
2026-03-07 08:40:16 -08:00
|
|
|
|
|
|
|
|
// Build command list
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
const commands: CommandItem[] = [];
|
|
|
|
|
|
|
|
|
|
if (!query.trim()) {
|
|
|
|
|
commands.push(
|
|
|
|
|
{ id: "daily", icon: "📅", label: "Open Daily Note", hint: "⌘D", action: () => { navigate("/daily"); onClose(); } },
|
|
|
|
|
{ id: "graph", icon: "🔮", label: "Graph View", hint: "⌘G", action: () => { navigate("/graph"); onClose(); } },
|
|
|
|
|
{ id: "new", icon: "✏️", label: "New Note", hint: "⌘N", action: () => { const name = prompt("Note name:"); if (name?.trim()) { navigateToNote(name.trim()); onClose(); } } },
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Template commands
|
|
|
|
|
if (templates.length > 0) {
|
|
|
|
|
for (const t of templates) {
|
|
|
|
|
commands.push({
|
|
|
|
|
id: `template-${t.path}`,
|
|
|
|
|
icon: "📋",
|
|
|
|
|
label: `New from template: ${t.name}`,
|
|
|
|
|
hint: "_templates",
|
|
|
|
|
action: async () => {
|
|
|
|
|
const name = prompt(`Note name (from "${t.name}" template):`);
|
|
|
|
|
if (name?.trim()) {
|
|
|
|
|
try {
|
|
|
|
|
const path = await createFromTemplate(vaultPath, t.path, name.trim());
|
|
|
|
|
navigate(`/note/${encodeURIComponent(path)}`);
|
|
|
|
|
onClose();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error("Template creation failed:", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// v0.4 commands
|
|
|
|
|
commands.push(
|
|
|
|
|
{ id: "calendar", icon: "📆", label: "Calendar View", action: () => { navigate("/calendar"); onClose(); } },
|
|
|
|
|
{ id: "theme", icon: "🎨", label: "Change Theme", hint: "⌘T", action: () => { onClose(); } },
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (currentNote) {
|
|
|
|
|
commands.push({
|
|
|
|
|
id: "export-html",
|
|
|
|
|
icon: "📤",
|
|
|
|
|
label: "Export as HTML",
|
|
|
|
|
action: async () => {
|
|
|
|
|
try {
|
|
|
|
|
const html = await exportNoteHtml(vaultPath, currentNote);
|
|
|
|
|
const blob = new Blob([html], { type: "text/html" });
|
|
|
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
|
const a = document.createElement("a");
|
|
|
|
|
a.href = url;
|
|
|
|
|
a.download = currentNote.replace(/\.md$/, ".html");
|
|
|
|
|
a.click();
|
|
|
|
|
URL.revokeObjectURL(url);
|
|
|
|
|
onClose();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error("Export failed:", e);
|
|
|
|
|
}
|
|
|
|
|
},
|
2026-03-07 08:40:16 -08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
// v0.5 commands
|
|
|
|
|
commands.push(
|
|
|
|
|
{ id: "kanban", icon: "📋", label: "Kanban Board", action: () => { navigate("/kanban"); onClose(); } },
|
|
|
|
|
{ id: "focus", icon: "🧘", label: "Focus Mode", hint: "⌘⇧F", action: () => { onClose(); } },
|
|
|
|
|
{ id: "search-replace", icon: "🔍", label: "Search & Replace", hint: "⌘H", action: () => { onClose(); } },
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (currentNote) {
|
|
|
|
|
commands.push({
|
|
|
|
|
id: "export-pdf",
|
|
|
|
|
icon: "📄",
|
|
|
|
|
label: "Export as PDF",
|
feat: v0.3 + v0.4 — frontmatter, templates, outline panel, vault cache
v0.3: Core file reading & markdown infrastructure
- Rust: read_note_with_meta, list_templates, save_attachment commands
- TypeScript: frontmatter.ts (parse/serialize YAML, extract headings)
- OutlinePanel with click-to-scroll headings + tabbed right panel
- CommandPalette: New from Template with {{title}}/{{date}} replacement
- Editor: image drag-and-drop to attachments/
- 130 lines of CSS for outline panel and right panel tabs
v0.4: File reading & caching
- Rust: VaultCache (cache.rs) with mtime-based invalidation
- Rewrote read_note, read_note_with_meta, build_graph, search_vault to use cache
- init_vault_cache (eager scan on startup), get_cache_stats commands
- Frontend LRU noteCache (capacity 20, stale-while-revalidate)
- notify crate added for filesystem watching foundation
2026-03-07 09:54:08 -08:00
|
|
|
action: () => {
|
|
|
|
|
onClose();
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
setTimeout(() => window.print(), 200);
|
feat: v0.3 + v0.4 — frontmatter, templates, outline panel, vault cache
v0.3: Core file reading & markdown infrastructure
- Rust: read_note_with_meta, list_templates, save_attachment commands
- TypeScript: frontmatter.ts (parse/serialize YAML, extract headings)
- OutlinePanel with click-to-scroll headings + tabbed right panel
- CommandPalette: New from Template with {{title}}/{{date}} replacement
- Editor: image drag-and-drop to attachments/
- 130 lines of CSS for outline panel and right panel tabs
v0.4: File reading & caching
- Rust: VaultCache (cache.rs) with mtime-based invalidation
- Rewrote read_note, read_note_with_meta, build_graph, search_vault to use cache
- init_vault_cache (eager scan on startup), get_cache_stats commands
- Frontend LRU noteCache (capacity 20, stale-while-revalidate)
- notify crate added for filesystem watching foundation
2026-03-07 09:54:08 -08:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
// v0.6 commands
|
|
|
|
|
commands.push(
|
|
|
|
|
{ id: "flashcards", icon: "🎴", label: "Flashcards", action: () => { navigate("/flashcards"); onClose(); } },
|
|
|
|
|
{ id: "custom-css", icon: "🎨", label: "Custom CSS", action: () => { onClose(); } },
|
|
|
|
|
{
|
|
|
|
|
id: "save-workspace", icon: "💾", label: "Save Workspace", action: () => {
|
|
|
|
|
const name = prompt("Workspace name:");
|
|
|
|
|
if (name?.trim()) { onClose(); }
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
);
|
2026-03-07 08:40:16 -08:00
|
|
|
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
// v0.7 commands
|
|
|
|
|
commands.push(
|
|
|
|
|
{ id: "database", icon: "📊", label: "Database View", action: () => { navigate("/database"); onClose(); } },
|
|
|
|
|
{
|
|
|
|
|
id: "whiteboard", icon: "🎨", label: "New Whiteboard", action: () => {
|
|
|
|
|
const name = prompt("Canvas name:");
|
|
|
|
|
if (name?.trim()) { navigate(`/whiteboard/${encodeURIComponent(name.trim())}`); onClose(); }
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{ id: "git-sync", icon: "🔀", label: "Git Sync", action: () => { onClose(); } },
|
|
|
|
|
);
|
2026-03-07 08:40:16 -08:00
|
|
|
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
// v0.8 commands
|
|
|
|
|
commands.push(
|
|
|
|
|
{ id: "timeline", icon: "📅", label: "Timeline", action: () => { navigate("/timeline"); onClose(); } },
|
|
|
|
|
{
|
|
|
|
|
id: "random-note", icon: "🎲", label: "Random Note", action: async () => {
|
|
|
|
|
try {
|
|
|
|
|
const { randomNote } = await import("../lib/commands");
|
|
|
|
|
const name = await randomNote(vaultPath);
|
|
|
|
|
navigate(`/note/${encodeURIComponent(name)}`);
|
|
|
|
|
} catch { }
|
|
|
|
|
onClose();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
);
|
2026-03-07 08:40:16 -08:00
|
|
|
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
// v0.9 commands
|
|
|
|
|
commands.push(
|
|
|
|
|
{ id: "analytics", icon: "📊", label: "Graph Analytics", action: () => { navigate("/analytics"); onClose(); } },
|
|
|
|
|
{ id: "import-export", icon: "📦", label: "Import / Export", action: () => { onClose(); } },
|
|
|
|
|
{ id: "shortcuts", icon: "⌨️", label: "Keyboard Shortcuts", action: () => { onClose(); } },
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Note matches
|
|
|
|
|
const flatNotes = flattenNoteNames(notes);
|
|
|
|
|
const queryLower = query.toLowerCase();
|
|
|
|
|
if (query.trim()) {
|
|
|
|
|
const nameMatches = flatNotes
|
|
|
|
|
.filter(n => n.name.toLowerCase().includes(queryLower))
|
|
|
|
|
.slice(0, 5);
|
|
|
|
|
|
|
|
|
|
for (const note of nameMatches) {
|
|
|
|
|
commands.push({
|
|
|
|
|
id: `note-${note.path}`,
|
|
|
|
|
icon: "📄",
|
|
|
|
|
label: note.name,
|
|
|
|
|
hint: note.path,
|
|
|
|
|
action: () => { navigate(`/note/${encodeURIComponent(note.path)}`); onClose(); },
|
|
|
|
|
});
|
2026-03-07 08:40:16 -08:00
|
|
|
}
|
|
|
|
|
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
// Content search results
|
|
|
|
|
for (const result of searchResults) {
|
|
|
|
|
// Don't duplicate filename matches
|
|
|
|
|
if (commands.some(c => c.id === `note-${result.path}`)) continue;
|
|
|
|
|
commands.push({
|
|
|
|
|
id: `search-${result.path}`,
|
|
|
|
|
icon: "🔍",
|
|
|
|
|
label: result.name,
|
|
|
|
|
hint: result.context.substring(0, 80),
|
|
|
|
|
action: () => { navigate(`/note/${encodeURIComponent(result.path)}`); onClose(); },
|
|
|
|
|
});
|
2026-03-07 08:40:16 -08:00
|
|
|
}
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Clamp selection
|
|
|
|
|
const maxIndex = Math.max(0, commands.length - 1);
|
|
|
|
|
const safeIndex = Math.min(selectedIndex, maxIndex);
|
2026-03-07 08:40:16 -08:00
|
|
|
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
|
2026-03-07 08:40:16 -08:00
|
|
|
if (e.key === "ArrowDown") {
|
|
|
|
|
e.preventDefault();
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
setSelectedIndex(i => Math.min(i + 1, maxIndex));
|
2026-03-07 08:40:16 -08:00
|
|
|
} else if (e.key === "ArrowUp") {
|
|
|
|
|
e.preventDefault();
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
setSelectedIndex(i => Math.max(i - 1, 0));
|
2026-03-07 08:40:16 -08:00
|
|
|
} else if (e.key === "Enter") {
|
|
|
|
|
e.preventDefault();
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
commands[safeIndex]?.action();
|
2026-03-07 08:40:16 -08:00
|
|
|
} else if (e.key === "Escape") {
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
e.preventDefault();
|
2026-03-07 08:40:16 -08:00
|
|
|
onClose();
|
|
|
|
|
}
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
}, [commands, safeIndex, maxIndex, onClose]);
|
2026-03-07 08:40:16 -08:00
|
|
|
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
// Scroll selected item into view
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
const list = listRef.current;
|
|
|
|
|
if (!list) return;
|
|
|
|
|
const item = list.children[safeIndex] as HTMLElement | undefined;
|
|
|
|
|
item?.scrollIntoView({ block: "nearest" });
|
|
|
|
|
}, [safeIndex]);
|
2026-03-07 08:40:16 -08:00
|
|
|
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
if (!open) return null;
|
2026-03-07 08:40:16 -08:00
|
|
|
|
|
|
|
|
return (
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
<div className="cmd-backdrop" onClick={onClose}>
|
|
|
|
|
<div className="cmd-palette" onClick={e => e.stopPropagation()} onKeyDown={handleKeyDown}>
|
|
|
|
|
{/* Search input */}
|
|
|
|
|
<div className="cmd-input-wrap">
|
|
|
|
|
<svg className="cmd-input-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
2026-03-07 08:40:16 -08:00
|
|
|
<circle cx="11" cy="11" r="8" />
|
|
|
|
|
<path d="m21 21-4.35-4.35" />
|
|
|
|
|
</svg>
|
|
|
|
|
<input
|
|
|
|
|
ref={inputRef}
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
className="cmd-input"
|
2026-03-07 08:40:16 -08:00
|
|
|
type="text"
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
placeholder="Search notes, commands..."
|
2026-03-07 08:40:16 -08:00
|
|
|
value={query}
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
onChange={e => { setQuery(e.target.value); setSelectedIndex(0); }}
|
2026-03-07 08:40:16 -08:00
|
|
|
/>
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
<kbd className="cmd-kbd">ESC</kbd>
|
2026-03-07 08:40:16 -08:00
|
|
|
</div>
|
|
|
|
|
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
{/* Results */}
|
|
|
|
|
<div className="cmd-list" ref={listRef}>
|
|
|
|
|
{commands.length === 0 && query.trim() && (
|
|
|
|
|
<div className="cmd-empty">No results for "{query}"</div>
|
feat: v0.3 + v0.4 — frontmatter, templates, outline panel, vault cache
v0.3: Core file reading & markdown infrastructure
- Rust: read_note_with_meta, list_templates, save_attachment commands
- TypeScript: frontmatter.ts (parse/serialize YAML, extract headings)
- OutlinePanel with click-to-scroll headings + tabbed right panel
- CommandPalette: New from Template with {{title}}/{{date}} replacement
- Editor: image drag-and-drop to attachments/
- 130 lines of CSS for outline panel and right panel tabs
v0.4: File reading & caching
- Rust: VaultCache (cache.rs) with mtime-based invalidation
- Rewrote read_note, read_note_with_meta, build_graph, search_vault to use cache
- init_vault_cache (eager scan on startup), get_cache_stats commands
- Frontend LRU noteCache (capacity 20, stale-while-revalidate)
- notify crate added for filesystem watching foundation
2026-03-07 09:54:08 -08:00
|
|
|
)}
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
{commands.map((cmd, i) => (
|
|
|
|
|
<button
|
|
|
|
|
key={cmd.id}
|
|
|
|
|
className={`cmd-item ${i === safeIndex ? "selected" : ""}`}
|
|
|
|
|
onClick={cmd.action}
|
|
|
|
|
onMouseEnter={() => setSelectedIndex(i)}
|
|
|
|
|
>
|
|
|
|
|
<span className="cmd-item-icon">{cmd.icon}</span>
|
|
|
|
|
<span className="cmd-item-label">{cmd.label}</span>
|
|
|
|
|
{cmd.hint && <span className="cmd-item-hint">{cmd.hint}</span>}
|
|
|
|
|
</button>
|
|
|
|
|
))}
|
2026-03-07 08:40:16 -08:00
|
|
|
</div>
|
|
|
|
|
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
{/* Footer */}
|
|
|
|
|
<div className="cmd-footer">
|
2026-03-07 08:40:16 -08:00
|
|
|
<span>↑↓ navigate</span>
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
<span>↵ select</span>
|
2026-03-07 08:40:16 -08:00
|
|
|
<span>esc close</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
/* ── Helpers ────────────────────────────────────────────────── */
|
|
|
|
|
function flattenNoteNames(
|
|
|
|
|
entries: { name: string; path: string; is_dir: boolean; children?: any[] }[]
|
|
|
|
|
): { name: string; path: string }[] {
|
2026-03-07 08:40:16 -08:00
|
|
|
const result: { name: string; path: string }[] = [];
|
feat: v0.7–v0.9 — canvas, whiteboard, database, git sync, timeline, analytics, import/export, shortcuts, table editor
v0.7: GraphView rewrite (@blinksgg/canvas), WhiteboardView, DatabaseView (table/gallery/list), GitPanel, backlink context, dataview queries
v0.8: OutlinePanel, TimelineView, StatusBar (doc stats), TableEditor, RandomNote, link suggestions
v0.9: ImportExport (ZIP/folder), ShortcutsEditor (rebind+persist), GraphAnalytics (orphans/most-connected), note pinning
Backend: 15 new Rust commands, zip crate, rand crate
Frontend: 18 new components, ~1400 lines CSS
Dependencies: @blinksgg/canvas, jotai, graphology, d3-force
2026-03-08 22:57:57 -07:00
|
|
|
for (const entry of entries) {
|
|
|
|
|
if (entry.is_dir && entry.children) {
|
|
|
|
|
result.push(...flattenNoteNames(entry.children));
|
|
|
|
|
} else if (!entry.is_dir) {
|
|
|
|
|
result.push({ name: entry.name, path: entry.path });
|
2026-03-07 08:40:16 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|