From d36ddfd61c6868f579595f8f964cc6f06b50cde2 Mon Sep 17 00:00:00 2001 From: CJ Pais Date: Wed, 7 May 2025 13:14:31 -0700 Subject: [PATCH] some opt + load directly from a store --- .cargo/config.toml | 2 + bun.lockb | Bin 64761 -> 65096 bytes package.json | 3 +- src-tauri/Cargo.lock | 1370 +---------------- src-tauri/Cargo.toml | 7 +- src-tauri/capabilities/default.json | 1 + src-tauri/src/lib.rs | 12 +- src-tauri/src/settings.rs | 0 src-tauri/src/shortcut.rs | 57 +- src-tauri/src/utils.rs | 0 src/components/icons/HandyTextLogo.tsx | 44 +- src/components/settings/KeyboardShortcuts.tsx | 54 +- src/lib/types.ts | 16 + 13 files changed, 157 insertions(+), 1409 deletions(-) create mode 100644 .cargo/config.toml create mode 100644 src-tauri/src/settings.rs create mode 100644 src-tauri/src/utils.rs create mode 100644 src/lib/types.ts diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..aecf592 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +rustc-wrapper = "sccache" diff --git a/bun.lockb b/bun.lockb index 0674da41156ef60af0b454d635cefc3fa3a0b3be..40415df12ec5bd5fa7799e4354549ec308eabe64 100755 GIT binary patch delta 10168 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, +} + +fn get_default_settings() -> AppSettings { + AppSettings { + bindings: vec![ + ShortcutBinding { + id: "transcribe".to_string(), + name: "Transcribe".to_string(), + description: "Converts your speech into text.".to_string(), + default_binding: "alt+space".to_string(), + current_binding: "alt+space".to_string(), + }, + ShortcutBinding { + id: "test".to_string(), + name: "Test".to_string(), + description: "This is a test binding.".to_string(), + default_binding: "ctrl+d".to_string(), + current_binding: "ctrl+d".to_string(), + }, + ], + } +} + fn try_send_event(event: &EventType) { if let Err(SimulateError) = simulate(event) { println!("We could not send {:?}", event); @@ -82,7 +119,25 @@ fn transcribe_released(app: &AppHandle) { }); } -pub fn enable_shortcut(app: &App) { +pub fn init_shortcuts(app: &App) { + // init store + let kb_store = app + .store("settings_store.json") + .expect("Failed to initialize store"); + + if let Some(bindings) = kb_store.get("settings") { + // print the bindings that exist + println!("Bindings: {:?}", bindings); + } else { + kb_store.set( + "settings", + serde_json::to_value(&get_default_settings()).unwrap(), + ); + // create the default bindings + } + + // load state from store + _register_shortcut_upon_start( app, "alt+space" diff --git a/src-tauri/src/utils.rs b/src-tauri/src/utils.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/components/icons/HandyTextLogo.tsx b/src/components/icons/HandyTextLogo.tsx index 26ab975..ed31cf7 100644 --- a/src/components/icons/HandyTextLogo.tsx +++ b/src/components/icons/HandyTextLogo.tsx @@ -16,68 +16,68 @@ const HandyTextLogo = ({ xmlns="http://www.w3.org/2000/svg" > diff --git a/src/components/settings/KeyboardShortcuts.tsx b/src/components/settings/KeyboardShortcuts.tsx index 4cf807c..ce0f341 100644 --- a/src/components/settings/KeyboardShortcuts.tsx +++ b/src/components/settings/KeyboardShortcuts.tsx @@ -1,44 +1,42 @@ -import React from "react"; - -interface Shortcut { - id: string; - name: string; - description: string; - keys: string[]; -} +import React, { useEffect } from "react"; +import { load } from "@tauri-apps/plugin-store"; +import { SettingsSchema, ShortcutBinding } from "../../lib/types"; export const KeyboardShortcuts: React.FC = () => { - // These would normally come from the backend configuration - const shortcuts: Shortcut[] = [ - { - id: "transcribe", - name: "Transcribe", - description: "Convert speech to text", - keys: ["⌃", "Space"], - }, - ]; + const [bindings, setBindings] = React.useState([]); + + useEffect(() => { + load("settings_store.json", { autoSave: false }).then((r) => { + console.log("loaded store", r); + + r.get("settings").then((s) => { + const settings = SettingsSchema.parse(s); + setBindings(settings.bindings); + }); + }); + }, []); return (
- {shortcuts.map((shortcut) => ( + {bindings.map((binding) => (

- {shortcut.name} + {binding.name}

-

{shortcut.description}

+

{binding.description}

- {shortcut.keys.map((key, index) => ( - - - {key} - - - ))} + + {/* */} +
+ {binding.current_binding} +
+ {/*
*/} +
))} diff --git a/src/lib/types.ts b/src/lib/types.ts new file mode 100644 index 0000000..0fcf4ad --- /dev/null +++ b/src/lib/types.ts @@ -0,0 +1,16 @@ +import { z } from "zod"; + +export const ShortcutBindingSchema = z.object({ + id: z.string(), + name: z.string(), + description: z.string(), + default_binding: z.string(), + current_binding: z.string(), +}); + +export const SettingsSchema = z.object({ + bindings: z.array(ShortcutBindingSchema), +}); + +export type ShortcutBinding = z.infer; +export type Settings = z.infer;