From 470ea1f760c395ed4c8318515647b856aea76915 Mon Sep 17 00:00:00 2001 From: Ricky Dane Perlick Date: Sun, 21 Jun 2026 15:38:04 +0200 Subject: [PATCH] feat: update note tool, note preview toggle, search window centering, and bump version to 0.2.1 --- package.json | 2 +- src-tauri/Cargo.lock | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/src/lib.rs | 25 +++++++ src-tauri/tauri.conf.json | 2 +- src/App.tsx | 28 +++++-- src/components/NotesView.tsx | 124 ++++++++++++++++++++++++------- src/components/ToolCallsView.tsx | 7 ++ src/plugins/notes.tsx | 22 ++++++ 9 files changed, 180 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index 1f5552c..3ae0de3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "gquick", "private": true, - "version": "0.2.0", + "version": "0.2.1", "type": "module", "engines": { "node": ">=24.15.0" diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 3d3b0c3..2a7ccc6 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2105,7 +2105,7 @@ dependencies = [ [[package]] name = "gquick" -version = "0.2.0" +version = "0.2.1" dependencies = [ "base64 0.22.1", "chrono", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index f2c936d..1f3cb15 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gquick" -version = "0.2.0" +version = "0.2.1" description = "A simple, fast and feature rich launcher" authors = ["Ricky Dane Perlick"] edition = "2021" diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index d1868d4..235dfbe 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -3540,6 +3540,30 @@ fn hide_main_window(window: tauri::Window) -> Result<(), String> { hide_window(&window, true) } +#[tauri::command] +fn center_main_window(window: tauri::Window) -> Result<(), String> { + let app = window.app_handle(); + if let Some(monitor) = monitor_for_mouse(app).or_else(|| app.primary_monitor().ok().flatten()) { + let scale_factor = monitor.scale_factor(); + let (logical_monitor_pos, logical_monitor_size) = + monitor_to_logical_geometry(&monitor); + + let window_size = window.inner_size().unwrap_or(tauri::PhysicalSize { + width: 760, + height: 800, + }); + let logical_window_size = window_size.to_logical::(scale_factor); + + let x = logical_monitor_pos.x + + (logical_monitor_size.width - logical_window_size.width) / 2.0; + let y = logical_monitor_pos.y + + (logical_monitor_size.height - logical_window_size.height) / 2.5; + + let _ = window.set_position(tauri::Position::Logical(tauri::LogicalPosition { x, y })); + } + Ok(()) +} + fn docker_output(args: &[String]) -> Result { let status = docker_status_blocking(); if !status.cli_installed { @@ -6736,6 +6760,7 @@ pub fn run() { cancel_terminal_command, cancel_all_terminal_commands, hide_main_window, + center_main_window, execute_python, execute_sql, brew_status, diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index b2a6c6f..1579683 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "GQuick", - "version": "0.2.0", + "version": "0.2.1", "identifier": "com.gquick.dev", "build": { "beforeDevCommand": "npm run dev", diff --git a/src/App.tsx b/src/App.tsx index cf407e8..f07c9d9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -333,6 +333,7 @@ function App() { const [autoCheckUpdateInfo, setAutoCheckUpdateInfo] = useState<{ version: string; body: string | null } | null>(null); const [autoCheckUpdateObj, setAutoCheckUpdateObj] = useState(null); const appliedWindowModeRef = useRef<"launcher" | "expanded" | null>(null); + const shouldCenterOnNextResizeRef = useRef(false); const inlineCommandRef = useRef(null); const searchRequestIdRef = useRef(0); const latestSearchQueryRef = useRef(query); @@ -547,7 +548,7 @@ function App() { ? appliedLauncherHeightRef.current : size.height; await appWindow.setSize(new LogicalSize(size.width, launcherHeight)); - await appWindow.center(); + await invoke("center_main_window"); } catch (error) { console.error("Failed to resize window:", error); } @@ -556,6 +557,10 @@ function App() { void resizeWindow(); }, [view]); + useEffect(() => { + shouldCenterOnNextResizeRef.current = true; + }, [view]); + useEffect(() => { const root = document.getElementById("root"); root?.classList.toggle("gquick-expanded-root", isExpandedView(view)); @@ -581,11 +586,22 @@ function App() { const targetHeight = pendingLauncherHeightRef.current; if (targetHeight == null) return; - if (targetHeight === appliedLauncherHeightRef.current) return; + + const sizeChanged = targetHeight !== appliedLauncherHeightRef.current; + const shouldCenter = shouldCenterOnNextResizeRef.current; + + if (!sizeChanged && !shouldCenter) return; try { - await getCurrentWindow().setSize(new LogicalSize(LAUNCHER_WINDOW_SIZE.width, targetHeight)); - appliedLauncherHeightRef.current = targetHeight; + const appWindow = getCurrentWindow(); + if (sizeChanged) { + await appWindow.setSize(new LogicalSize(LAUNCHER_WINDOW_SIZE.width, targetHeight)); + appliedLauncherHeightRef.current = targetHeight; + } + if (shouldCenter) { + await invoke("center_main_window"); + shouldCenterOnNextResizeRef.current = false; + } } catch (error) { console.error("Failed to resize launcher window:", error); } @@ -1552,6 +1568,7 @@ function App() { read_file: "Access the content of local text files.", search_notes: "Search your saved notes.", create_note: "Save new information to your notes database.", + update_note: "Update an existing note in your notes database.", get_current_weather: "Get current weather conditions for a location.", get_weather_forecast: "Get 7-day weather forecast for a location.", calculate: "Perform mathematical calculations.", @@ -1579,7 +1596,8 @@ function App() { const dataMgmtSection = [ enabledToolNames.has("read_file") && "* `read_file`: Access the content of local text files.", - enabledToolNames.has("create_note") && "* `create_note`: Save new information to your notes database." + enabledToolNames.has("create_note") && "* `create_note`: Save new information to your notes database.", + enabledToolNames.has("update_note") && "* `update_note`: Update an existing note in your notes database." ].filter((val): val is string => typeof val === "string").join("\n"); const codeExecSection = [ diff --git a/src/components/NotesView.tsx b/src/components/NotesView.tsx index 682ddb0..a2c6b2c 100644 --- a/src/components/NotesView.tsx +++ b/src/components/NotesView.tsx @@ -47,6 +47,7 @@ export function NotesView({ initialNoteId, searchQuery = "" }: NotesViewProps) { const [loading, setLoading] = useState(true); const [editingNote, setEditingNote] = useState(null); const [isCreating, setIsCreating] = useState(false); + const [isEditMode, setIsEditMode] = useState(false); const [editTitle, setEditTitle] = useState(""); const [editContent, setEditContent] = useState(""); const [copiedId, setCopiedId] = useState(null); @@ -57,11 +58,12 @@ export function NotesView({ initialNoteId, searchQuery = "" }: NotesViewProps) { hasHandledInitialNote.current = false; }, [initialNoteId]); - const startEdit = useCallback((note: Note) => { + const startEdit = useCallback((note: Note, editDirectly = false) => { setEditingNote(note); setEditTitle(note.title); setEditContent(note.content); setIsCreating(false); + setIsEditMode(editDirectly); }, []); const fetchNotes = useCallback(async () => { @@ -73,7 +75,7 @@ export function NotesView({ initialNoteId, searchQuery = "" }: NotesViewProps) { if (initialNoteId && !hasHandledInitialNote.current && !isCreating && !editingNote) { const targetNote = data.find((n) => n.id === initialNoteId); if (targetNote) { - startEdit(targetNote); + startEdit(targetNote, false); } hasHandledInitialNote.current = true; } @@ -124,6 +126,7 @@ export function NotesView({ initialNoteId, searchQuery = "" }: NotesViewProps) { setIsCreating(false); setEditTitle(""); setEditContent(""); + setIsEditMode(false); fetchNotes(); } catch (e) { console.error("Failed to save note:", e); @@ -161,6 +164,7 @@ export function NotesView({ initialNoteId, searchQuery = "" }: NotesViewProps) { setEditingNote(null); setEditTitle(""); setEditContent(""); + setIsEditMode(true); }; const cancelEdit = () => { @@ -168,6 +172,7 @@ export function NotesView({ initialNoteId, searchQuery = "" }: NotesViewProps) { setIsCreating(false); setEditTitle(""); setEditContent(""); + setIsEditMode(false); }; const filteredNotes = searchQuery.trim() @@ -178,28 +183,87 @@ export function NotesView({ initialNoteId, searchQuery = "" }: NotesViewProps) { ) : notes; - const isEditing = isCreating || editingNote !== null; + const isDetailActive = isCreating || editingNote !== null; return ( -
+
- {isEditing ? ( -
- setEditTitle(e.target.value)} - placeholder="Note title (optional)" - className="w-full bg-zinc-800 border border-white/10 rounded-xl px-3 py-2 text-sm text-zinc-200 placeholder-zinc-500 outline-none focus:border-blue-500/50 transition-all" - /> -