From 4bde986521642e11ebdcef0d649ff5f9a6f35b6c Mon Sep 17 00:00:00 2001 From: don Date: Sat, 21 Dec 2024 00:30:31 +0100 Subject: [PATCH] fix toggle in front end --- .gitignore | 5 ++- .prettierignore | 2 +- package.json | 2 +- src-tauri/Cargo.lock | 20 ++++++++++ src-tauri/Cargo.toml | 2 + src-tauri/common/src/constants.rs | 3 ++ src-tauri/entity/src/settings.rs | 3 -- .../migration/src/m000007_create_settings.rs | 4 +- src-tauri/src/connection.rs | 4 +- src-tauri/src/main.rs | 2 + src-tauri/src/service/hotkey.rs | 15 ++++--- src-tauri/src/service/settings.rs | 39 +++++++++++++------ src/components/elements/toggle.tsx | 31 ++++++++++----- src/components/navigation/app-sidebar.tsx | 17 ++++---- src/components/pages/app/app.tsx | 15 +++---- .../pages/app/clipboard/clipboards.tsx | 5 ++- .../pages/app/clipboard/file-clipboard.tsx | 20 +++++----- .../pages/app/clipboard/image-clipboard.tsx | 21 +++++----- .../pages/app/clipboard/text-clipboard.tsx | 21 +++++----- .../pages/app/recent-clipboards.tsx | 9 +---- src/components/pages/app/search-bar.tsx | 6 +-- src/components/pages/app/view-more.tsx | 31 ++++++++------- .../pages/settings/settings-backup.tsx | 13 ++++--- .../utils/clipboard/clipboard-footer.tsx | 5 +-- .../utils/clipboard/clipboard-header.tsx | 2 +- src/index.tsx | 6 +-- src/store/app-store.ts | 7 ++-- src/store/clipboard-store.ts | 2 +- src/store/hotkey-store.ts | 4 +- src/store/settings-store.ts | 2 +- src/styles.css | 4 ++ 31 files changed, 191 insertions(+), 131 deletions(-) diff --git a/.gitignore b/.gitignore index 4e25bac5..68cc5ea6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ node_modules dist -clippy.sqlite +*.sqlite yarn.lock package-lock.json pnpm-lock.yamlor.log @@ -15,4 +15,5 @@ bun.lockb # will have compiled files and executables target/ context.txt -sea_orm_*.txt \ No newline at end of file +sea_orm_*.txt +config.json \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index 637ead1c..06a8d889 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,6 @@ node_modules dist -clippy.sqlite +*.sqlite yarn.lock package-lock.json pnpm-lock.yaml diff --git a/package.json b/package.json index d3e0bb26..65cfc2ca 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "dev": "vite", "build": "vite build", "tauri": "cross-env NO_STRIP=true tauri", - "d": "tauri dev", + "d": "cross-env RUST_BACKTRACE=1 tauri dev", "gen": "sea-orm-cli migrate refresh -v -d src-tauri/migration && sea-orm-cli generate entity -l -o src-tauri/entity/src --expanded-format --with-serde both", "icon": "tauri icon" }, diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index ed695827..526ca331 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -933,6 +933,7 @@ version = "1.3.0" dependencies = [ "base64 0.22.1", "chrono", + "color-backtrace", "common", "enigo", "entity", @@ -987,6 +988,16 @@ dependencies = [ "objc", ] +[[package]] +name = "color-backtrace" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "150fd80a270c0671379f388c8204deb6a746bb4eac8a6c03fe2460b2c0127ea0" +dependencies = [ + "backtrace", + "termcolor", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -5968,6 +5979,15 @@ dependencies = [ "utf-8", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "thin-slice" version = "0.1.1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 77108e8d..7eb4730e 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -56,6 +56,8 @@ infer = "0" mime_guess = "2" tree_magic_mini = "3" +color-backtrace = "0" + [profile.release] # panic = "abort" # codegen-units = 1 diff --git a/src-tauri/common/src/constants.rs b/src-tauri/common/src/constants.rs index 8c3e6614..43638eb5 100644 --- a/src-tauri/common/src/constants.rs +++ b/src-tauri/common/src/constants.rs @@ -9,6 +9,9 @@ pub static GLOBAL_EVENTS: LazyLock> = LazyLock::new(|| { ] }); +pub static DB_NAME: &str = "clippy.sqlite"; +pub static CONFIG_NAME: &str = "config.json"; + pub static MAIN_WINDOW_X: i32 = 375; pub static MAIN_WINDOW_Y: i32 = 600; diff --git a/src-tauri/entity/src/settings.rs b/src-tauri/entity/src/settings.rs index 6af0aa88..73e74023 100644 --- a/src-tauri/entity/src/settings.rs +++ b/src-tauri/entity/src/settings.rs @@ -17,7 +17,6 @@ pub struct Model { pub id: i32, pub language: String, pub startup: bool, - pub notification: bool, pub synchronize: bool, pub dark_mode: bool, pub display_scale: f32, @@ -33,7 +32,6 @@ pub enum Column { Id, Language, Startup, - Notification, Synchronize, DarkMode, DisplayScale, @@ -66,7 +64,6 @@ impl ColumnTrait for Column { Self::Id => ColumnType::Integer.def(), Self::Language => ColumnType::String(StringLen::N(2u32)).def(), Self::Startup => ColumnType::Boolean.def(), - Self::Notification => ColumnType::Boolean.def(), Self::Synchronize => ColumnType::Boolean.def(), Self::DarkMode => ColumnType::Boolean.def(), Self::DisplayScale => ColumnType::Float.def(), diff --git a/src-tauri/migration/src/m000007_create_settings.rs b/src-tauri/migration/src/m000007_create_settings.rs index c11580e3..ca81d7a9 100644 --- a/src-tauri/migration/src/m000007_create_settings.rs +++ b/src-tauri/migration/src/m000007_create_settings.rs @@ -9,7 +9,7 @@ use common::{ }; use sea_orm_migration::{ prelude::*, - schema::{boolean, float, integer, pk_auto, string}, + schema::{boolean, float, integer, pk_auto, string}, }; #[derive(Iden)] @@ -19,7 +19,6 @@ enum Settings { Language, // Startup, - Notification, Synchronize, DarkMode, DisplayScale, @@ -49,7 +48,6 @@ impl MigrationTrait for Migration { .default(get_system_language().to_string()), ) .col(boolean(Settings::Startup).default(true)) - .col(boolean(Settings::Notification).default(false)) .col(boolean(Settings::Synchronize).default(false)) .col(boolean(Settings::DarkMode).default(true)) .col( diff --git a/src-tauri/src/connection.rs b/src-tauri/src/connection.rs index f11fe9ad..57817f54 100644 --- a/src-tauri/src/connection.rs +++ b/src-tauri/src/connection.rs @@ -1,6 +1,6 @@ use crate::prelude::*; use crate::service::settings::get_data_path; -use common::types::types::Config; +use common::{constants::DB_NAME, types::types::Config}; use migration::{DbErr, Migrator, MigratorTrait}; use std::sync::Once; @@ -9,7 +9,7 @@ static INIT: Once = Once::new(); pub async fn db() -> Result { let database_url = if cfg!(debug_assertions) { - String::from("sqlite://../clippy.sqlite?mode=rwc") + format!("sqlite://../{}?mode=rwc", DB_NAME) } else { get_prod_database_url() }; diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 641a5566..4bfdbe0f 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -3,6 +3,8 @@ #[tokio::main] async fn main() { + color_backtrace::install(); + #[cfg(target_os = "linux")] { // See: https://github.com/spacedriveapp/spacedrive/issues/1512#issuecomment-1758550164 diff --git a/src-tauri/src/service/hotkey.rs b/src-tauri/src/service/hotkey.rs index a37f599e..286fb5bb 100644 --- a/src-tauri/src/service/hotkey.rs +++ b/src-tauri/src/service/hotkey.rs @@ -1,4 +1,4 @@ -use super::global::{get_app_window, get_main_window}; +use super::global::{get_app, get_main_window}; use crate::prelude::*; use crate::{ connection, @@ -8,7 +8,7 @@ use common::types::enums::{ListenEvent, WebWindow}; use core::future::Future; use entity::hotkey::{self, ActiveModel, Model}; use sea_orm::{ActiveModelTrait, EntityTrait}; -use tauri::Emitter; +use tauri::{Emitter, Manager}; pub async fn get_all_hotkeys_db() -> Result, DbErr> { let db: DatabaseConnection = connection::db().await?; @@ -45,9 +45,14 @@ where get_main_window() .emit(ListenEvent::Init.to_string().as_str(), ()) .expect("Failed to emit init event"); - get_app_window(WebWindow::Settings) - .emit(ListenEvent::Init.to_string().as_str(), ()) - .expect("Failed to emit init event"); + + if let Some(settings_window) = + get_app().get_webview_window(WebWindow::Settings.to_string().as_str()) + { + settings_window + .emit(ListenEvent::Init.to_string().as_str(), ()) + .expect("Failed to emit init event"); + } result } diff --git a/src-tauri/src/service/settings.rs b/src-tauri/src/service/settings.rs index 7e869487..49a380e9 100644 --- a/src-tauri/src/service/settings.rs +++ b/src-tauri/src/service/settings.rs @@ -4,6 +4,8 @@ use crate::connection; use crate::prelude::*; use crate::service::window::get_monitor_scale_factor; use crate::{commands::settings::get_settings, service::hotkey::with_hotkeys}; +use common::constants::CONFIG_NAME; +use common::constants::DB_NAME; use common::language::get_system_language; use common::types::types::Config; use common::types::types::DataPath; @@ -73,23 +75,34 @@ pub fn init_settings() { } pub fn get_data_path() -> DataPath { - let config_path = get_app() - .path() - .app_data_dir() - .expect("Failed to get app data dir") - .to_string_lossy() - .to_string(); + let config_path = if cfg!(debug_assertions) { + // Get absolute project root directory + let current_dir = std::env::current_dir() + .expect("Failed to get current directory") + .parent() + .expect("Failed to get parent directory") + .to_path_buf(); + + current_dir.to_string_lossy().to_string() + } else { + // Use app data dir in production + get_app() + .path() + .app_data_dir() + .expect("Failed to get app data dir") + .to_string_lossy() + .to_string() + }; fs::create_dir_all(&config_path).expect("Failed to create config directory"); - // let config_file = Path::new(&config_dir).join("config.json"); - let config_file_path = [&config_path, "config.json"] + let config_file_path = [&config_path, CONFIG_NAME] .iter() .collect::() .to_string_lossy() .to_string(); - let db_file_path = [&config_path, "clippy.sqlite"] + let db_file_path = [&config_path, DB_NAME] .iter() .collect::() .to_string_lossy() @@ -122,11 +135,14 @@ pub async fn sync_clipboard_history_enable() { let dir = dir.to_string(); let dir_file = format!("{}/clippy.sqlite", &dir); - println!("selected dir: {}", dir); - // check if backup file exists if !Path::new(&dir_file).exists() { // copy current database to backup location + printlog!( + "copying database to backup location {} {}", + &config.db, + &dir_file + ); fs::copy(&config.db, &dir_file).expect("Failed to copy database"); } @@ -169,6 +185,7 @@ pub async fn sync_clipboard_history_disable() { pub async fn sync_clipboard_history_toggle() { let settings = get_settings().await.expect("Failed to get settings"); + printlog!("synchronize: {}", settings.synchronize); with_hotkeys(false, async move { if settings.synchronize { sync_clipboard_history_disable().await; diff --git a/src/components/elements/toggle.tsx b/src/components/elements/toggle.tsx index e06b07d4..3d4e96e2 100644 --- a/src/components/elements/toggle.tsx +++ b/src/components/elements/toggle.tsx @@ -1,6 +1,6 @@ import { FiCheck } from "solid-icons/fi"; import { VsClose } from "solid-icons/vs"; -import { Component, Setter } from "solid-js"; +import { Component, Setter, createEffect, createSignal } from "solid-js"; type SwitchProps = { checked?: boolean; @@ -8,21 +8,34 @@ type SwitchProps = { }; export const Toggle: Component = (props) => { + let inputRef: HTMLInputElement | undefined; + const [internalChecked, setInternalChecked] = createSignal(props.checked || false); + + createEffect(() => { + if (props.checked !== undefined) { + setInternalChecked(props.checked); + if (inputRef) { + inputRef.checked = props.checked; + } + } + }); + + const handleChange = () => { + const newValue = !internalChecked(); + setInternalChecked(newValue); + props.onChange(newValue); + }; + return ( diff --git a/src/components/navigation/app-sidebar.tsx b/src/components/navigation/app-sidebar.tsx index 7db45938..797ab642 100644 --- a/src/components/navigation/app-sidebar.tsx +++ b/src/components/navigation/app-sidebar.tsx @@ -5,14 +5,11 @@ import { HotkeyStore } from "../../store/hotkey-store"; interface AppSidebarProps {} export const AppSidebar: Component = ({}) => { - const { hotkeys, globalHotkeyEvent, getHotkey } = HotkeyStore; - const { setCurrentTab, tabs } = AppStore; - return ( - - + + {({ current, Icon, name, id }) => { - const currentHotkey = hotkeys()?.find((key) => key?.name === name); + const currentHotkey = HotkeyStore.hotkeys()?.find((key) => key?.name === name); return (
= ({}) => { current ? "text-black dark:text-white" : "text-zinc-600 dark:text-gray-dark" } relative flex h-6 w-full cursor-pointer select-none items-center justify-center py-5 text-xl hover:text-black dark:hover:text-white`} title={currentHotkey?.name} - onClick={() => setCurrentTab(id)} + onClick={() => AppStore.changeTab(id)} > - +
{currentHotkey!.key}
diff --git a/src/components/pages/app/app.tsx b/src/components/pages/app/app.tsx index 87d9ff05..c0d014d5 100644 --- a/src/components/pages/app/app.tsx +++ b/src/components/pages/app/app.tsx @@ -10,9 +10,6 @@ import { StarredClipboards } from "./starred-clipboards"; import { ViewMore } from "./view-more"; function App() { - const { settings } = SettingsStore; - const { getCurrentTab } = AppStore; - return (
@@ -21,26 +18,26 @@ function App() {

- {getCurrentTab()?.name?.toUpperCase()} + {AppStore.getCurrentTab()?.name?.toUpperCase()}

- }> + }>
- + - + - + - +
diff --git a/src/components/pages/app/clipboard/clipboards.tsx b/src/components/pages/app/clipboard/clipboards.tsx index 612a1958..d42d48aa 100644 --- a/src/components/pages/app/clipboard/clipboards.tsx +++ b/src/components/pages/app/clipboard/clipboards.tsx @@ -4,6 +4,7 @@ import utc from "dayjs/plugin/utc"; import { FiArrowUp } from "solid-icons/fi"; import { Component, For, Show, createSignal, onMount } from "solid-js"; import clippy from "../../../../assets/clippy.png"; +import { AppStore } from "../../../../store/app-store"; import { ClipboardStore } from "../../../../store/clipboard-store"; import { HotkeyStore } from "../../../../store/hotkey-store"; import { HotkeyEvent } from "../../../../types/enums"; @@ -35,7 +36,7 @@ export const Clipboards: Component = () => { } }; - onMount(() => listenEvent(ListenEvent.ScrollToTop, () => ClipboardStore.clipboardRef()!.scrollTo(0, 0))); + onMount(() => listenEvent(ListenEvent.ScrollToTop, () => ClipboardStore.clipboardRef()?.scrollTo(0, 0))); onMount(() => { window.addEventListener("keydown", ClipboardStore.handleKeyDown); @@ -57,7 +58,7 @@ export const Clipboards: Component = () => { ); }; diff --git a/src/components/pages/app/clipboard/image-clipboard.tsx b/src/components/pages/app/clipboard/image-clipboard.tsx index 4a5c4d10..0d307725 100644 --- a/src/components/pages/app/clipboard/image-clipboard.tsx +++ b/src/components/pages/app/clipboard/image-clipboard.tsx @@ -1,3 +1,4 @@ +import dayjs from "dayjs"; import { BsImages } from "solid-icons/bs"; import { Component } from "solid-js"; import { ClipboardWithRelations } from "../../../../types"; @@ -5,7 +6,6 @@ import { ClipboardType } from "../../../../types/enums"; import { InvokeCommand } from "../../../../types/tauri-invoke"; import { formatBytes } from "../../../../utils/helpers"; import { invokeCommand } from "../../../../utils/tauri"; -import { ClipboardFooter } from "../../../utils/clipboard/clipboard-footer"; import { ClipboardHeader } from "../../../utils/clipboard/clipboard-header"; interface ImageClipboardProps { @@ -39,14 +39,10 @@ export const ImageClipboard: Component = (props) => { `${props.data.image.width}x${props.data.image.height} ${formatBytes(Number(props.data.image.size || "0"))}`; return ( - ); }; diff --git a/src/components/pages/app/clipboard/text-clipboard.tsx b/src/components/pages/app/clipboard/text-clipboard.tsx index 80cb2587..d66f1af2 100644 --- a/src/components/pages/app/clipboard/text-clipboard.tsx +++ b/src/components/pages/app/clipboard/text-clipboard.tsx @@ -1,10 +1,10 @@ +import dayjs from "dayjs"; import { IoText } from "solid-icons/io"; import { Component } from "solid-js"; import { ClipboardWithRelations } from "../../../../types"; import { ClipboardType } from "../../../../types/enums"; import { InvokeCommand } from "../../../../types/tauri-invoke"; import { invokeCommand } from "../../../../utils/tauri"; -import { ClipboardFooter } from "../../../utils/clipboard/clipboard-footer"; import { ClipboardHeader } from "../../../utils/clipboard/clipboard-header"; interface TextClipboardProps { @@ -34,19 +34,20 @@ export const TextClipboard: Component = (props) => { }; return ( - ); }; diff --git a/src/components/pages/app/recent-clipboards.tsx b/src/components/pages/app/recent-clipboards.tsx index e051b351..4b5d964a 100644 --- a/src/components/pages/app/recent-clipboards.tsx +++ b/src/components/pages/app/recent-clipboards.tsx @@ -1,16 +1,11 @@ -import { Component, onMount } from "solid-js"; -import { Clipboards } from "./clipboard/clipboards"; +import { Component } from "solid-js"; import { ClipboardStore } from "../../../store/clipboard-store"; +import { Clipboards } from "./clipboard/clipboards"; interface RecentClipboardsProps {} export const RecentClipboards: Component = ({}) => { const { setClipboards, getClipboards, resetWhere } = ClipboardStore; - onMount(async () => { - resetWhere(); - setClipboards(await getClipboards()); - }); - return ; }; diff --git a/src/components/pages/app/search-bar.tsx b/src/components/pages/app/search-bar.tsx index 03d54598..040bad04 100644 --- a/src/components/pages/app/search-bar.tsx +++ b/src/components/pages/app/search-bar.tsx @@ -1,11 +1,11 @@ import { FaRegularImage } from "solid-icons/fa"; import { FiSearch } from "solid-icons/fi"; import { Component, createEffect, createSignal, onCleanup, onMount } from "solid-js"; -import { InvokeCommand } from "../../../types/tauri-invoke"; -import { invokeCommand } from "../../../utils/tauri"; import { AppStore } from "../../../store/app-store"; import { ClipboardStore, initialWhere } from "../../../store/clipboard-store"; import { HotkeyStore } from "../../../store/hotkey-store"; +import { InvokeCommand } from "../../../types/tauri-invoke"; +import { invokeCommand } from "../../../utils/tauri"; interface SearchBarProps {} @@ -15,7 +15,7 @@ export const SearchBar: Component = ({}) => { const [showImages, setShowImages] = createSignal(false); const { getCurrentTab } = AppStore; const { setClipboards, setWhere, getClipboards } = ClipboardStore; - const { setGlobalHotkeyEvent } = HotkeyStore; + const { enableGlobalHotkeyEvent: setGlobalHotkeyEvent } = HotkeyStore; onMount(async () => { input?.focus(); diff --git a/src/components/pages/app/view-more.tsx b/src/components/pages/app/view-more.tsx index 84f5eeff..fc6f0225 100644 --- a/src/components/pages/app/view-more.tsx +++ b/src/components/pages/app/view-more.tsx @@ -1,31 +1,32 @@ import { Component, Show } from "solid-js"; +import { HotkeyStore } from "../../../store/hotkey-store"; +import { SettingsStore } from "../../../store/settings-store"; import { Hotkey } from "../../../types"; import { WebWindow } from "../../../types/enums"; import { ViewMoreName } from "../../../utils/constants"; import { Toggle } from "../../elements/toggle"; -import { HotkeyStore } from "../../../store/hotkey-store"; -import { SettingsStore } from "../../../store/settings-store"; interface ViewMoreProps {} export const ViewMore: Component = ({}) => { - const { settings, syncClipboard, openWindow, exitApp } = SettingsStore; - const { hotkeys, globalHotkeyEvent } = HotkeyStore; - - const createButton = (name: ViewMoreName, onClick: () => void) => { - const hotkey = hotkeys().find((key) => key.name === name) as Hotkey; + const createButton = (name: ViewMoreName, callback: () => void) => { + const hotkey = HotkeyStore.hotkeys().find((key) => key.name === name) as Hotkey; return ( @@ -43,13 +46,13 @@ export const ViewMore: Component = ({}) => { return ( <> {/* Sync Clipboard History */} - {createButton("Sync Clipboard History", syncClipboard)} + {createButton("Sync Clipboard History", SettingsStore.syncClipboard)} {/* Settings */} - {createButton("Settings", async () => openWindow(WebWindow.Settings))} + {createButton("Settings", () => SettingsStore.openWindow(WebWindow.Settings))} {/* About */} - {createButton("About", async () => openWindow(WebWindow.About))} + {createButton("About", () => SettingsStore.openWindow(WebWindow.About))} {/* Exit */} - {createButton("Exit", exitApp)} + {createButton("Exit", SettingsStore.exitApp)} ); }; diff --git a/src/components/pages/settings/settings-backup.tsx b/src/components/pages/settings/settings-backup.tsx index ae222084..f112320c 100644 --- a/src/components/pages/settings/settings-backup.tsx +++ b/src/components/pages/settings/settings-backup.tsx @@ -14,11 +14,10 @@ interface SettingsBackupProps {} export const SettingsBackup: Component = ({}) => { const [url, setUrl] = createSignal(); - const { settings, syncClipboard } = SettingsStore; createEffect( on( - () => settings()?.synchronize, + () => SettingsStore.settings()?.synchronize, () => setTimeout(async () => setUrl(await invokeCommand(InvokeCommand.GetDbPath)), 100) ) ); @@ -31,9 +30,11 @@ export const SettingsBackup: Component = ({}) => {
Synchronize clipboard history
-
- void syncClipboard()} /> -
+ + void SettingsStore.syncClipboard()} + />
@@ -50,7 +51,7 @@ export const SettingsBackup: Component = ({}) => {