From 0a77026a006294dfa45401d8b4bd5d8a109c4cd1 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 | 5 +- 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-tauri/src/service/window.rs | 13 ++++- src/components/elements/dropdown.tsx | 12 ++-- src/components/elements/input.tsx | 27 +++++++++ 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 +++-- .../pages/settings/settings-general.tsx | 58 +++++++++++++------ .../pages/settings/settings-hotkeys.tsx | 36 +++++------- .../utils/clipboard/clipboard-footer.tsx | 5 +- .../utils/clipboard/clipboard-header.tsx | 2 +- src/components/utils/shortcut.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 ++ src/types/enums.ts | 34 ++++++++++- src/types/index.ts | 10 +++- 39 files changed, 333 insertions(+), 183 deletions(-) create mode 100644 src/components/elements/input.tsx 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..216c1936 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 COLORBT_SHOW_HIDDEN=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..47e0769b 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; @@ -16,7 +19,7 @@ pub static ABOUT_WINDOW_X: i32 = 375; pub static ABOUT_WINDOW_Y: i32 = 600; pub static SETTINGS_WINDOW_X: i32 = 500; -pub static SETTINGS_WINDOW_Y: i32 = 450; +pub static SETTINGS_WINDOW_Y: i32 = 550; pub static MAX_IMAGE_DIMENSIONS: u32 = 1280; pub static MAX_TEXT_PREVIEW: usize = 500; // Adjust preview length as needed 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-tauri/src/service/window.rs b/src-tauri/src/service/window.rs index fcb03937..db03de97 100644 --- a/src-tauri/src/service/window.rs +++ b/src-tauri/src/service/window.rs @@ -49,7 +49,10 @@ pub fn toggle_main_window() { get_main_window().hide().expect("Failed to hide window"); unregister_hotkeys(false); get_main_window() - .emit(ListenEvent::EnableGlobalHotkeyEvent.to_string().as_str(), false) + .emit( + ListenEvent::EnableGlobalHotkeyEvent.to_string().as_str(), + false, + ) .expect("Failed to emit set global hotkey event"); } else { position_window_near_cursor(); @@ -63,7 +66,10 @@ pub fn toggle_main_window() { register_hotkeys(true); get_main_window() - .emit(ListenEvent::EnableGlobalHotkeyEvent.to_string().as_str(), true) + .emit( + ListenEvent::EnableGlobalHotkeyEvent.to_string().as_str(), + true, + ) .expect("Failed to emit set global hotkey event"); get_app() @@ -166,7 +172,9 @@ pub async fn create_about_window() { // Close existing window if it exists if let Some(window) = app.get_webview_window(WebWindow::About.to_string().as_str()) { + printlog!("closing existing about window"); window.close().expect("Failed to close window"); + tokio::time::sleep(std::time::Duration::from_millis(100)).await; } let window = WebviewWindowBuilder::new( @@ -191,6 +199,7 @@ pub async fn create_settings_window() { // Close existing window if it exists if let Some(window) = app.get_webview_window(WebWindow::Settings.to_string().as_str()) { window.close().expect("Failed to close window"); + tokio::time::sleep(std::time::Duration::from_millis(100)).await; } let window = WebviewWindowBuilder::new( diff --git a/src/components/elements/dropdown.tsx b/src/components/elements/dropdown.tsx index 09782a4e..6d0b8781 100644 --- a/src/components/elements/dropdown.tsx +++ b/src/components/elements/dropdown.tsx @@ -1,11 +1,11 @@ import { VsArrowSwap } from "solid-icons/vs"; import { Component, createSignal } from "solid-js"; -import { GlobalShortcutKeys } from "../../utils/constants"; interface DropdownProps { - items: string[]; + className?: string; + items: { value: string; label: string }[]; value: string; - onChange: (value: GlobalShortcutKeys | (string & {})) => void; + onChange: (value: string) => void; } export const Dropdown: Component = (props) => { @@ -14,7 +14,7 @@ export const Dropdown: Component = (props) => { return (
ref()?.dispatchEvent(new MouseEvent("mousedown"))} - class="group flex items-center rounded-md border border-gray-300 p-1 text-sm focus:outline-none focus:ring-0 dark:border-dark-light dark:bg-dark-light dark:text-white" + class={`${props.className ? props.className : ""} group flex items-center justify-between rounded-md border border-gray-300 p-1 px-1.5 text-sm focus:outline-none focus:ring-0 dark:border-dark-light dark:bg-dark-light dark:text-white`} > diff --git a/src/components/elements/input.tsx b/src/components/elements/input.tsx new file mode 100644 index 00000000..f6dc1b6b --- /dev/null +++ b/src/components/elements/input.tsx @@ -0,0 +1,27 @@ +import { Component } from "solid-js"; + +interface InputProps { + className?: string; + value: string; + onChange: (value: string) => void; + placeholder?: string; + type?: string; +} + +export const Input: Component = (props) => { + return ( +
+ props.onChange(e.currentTarget.value)} + placeholder={props.placeholder} + class="w-full appearance-none bg-transparent text-sm focus:outline-none focus:ring-0 dark:text-white" + /> +
+ ); +}; 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 = ({}) => {
updateSettings({ ...settings()!, startup: check })} + checked={SettingsStore.settings()?.startup} + onChange={async (check: boolean) => + SettingsStore.updateSettings({ ...SettingsStore.settings()!, startup: check }) + } />
- -
Show desktop notifications.
+ +
Change language
-
- updateSettings({ ...settings()!, notification: check })} - /> + + ({ value: value, label: key }))} + value={SettingsStore.settings()!.language} + onChange={(language) => { + SettingsStore.updateSettings({ ...SettingsStore.settings()!, language: language as Language }); + }} + /> +
+ +
+
+ +
Display Scale
+ + { + SettingsStore.updateSettings({ ...SettingsStore.settings()!, display_scale: parseInt(display_scale) }); + }} + />
diff --git a/src/components/pages/settings/settings-hotkeys.tsx b/src/components/pages/settings/settings-hotkeys.tsx index 80871711..0e038362 100644 --- a/src/components/pages/settings/settings-hotkeys.tsx +++ b/src/components/pages/settings/settings-hotkeys.tsx @@ -1,32 +1,26 @@ import { RiDeviceKeyboardFill } from "solid-icons/ri"; import { Component, For } from "solid-js"; +import { HotkeyStore } from "../../../store/hotkey-store"; import { TextBlock } from "../../elements/text-block"; import { Shortcut } from "../../utils/shortcut"; -import { HotkeyStore } from "../../../store/hotkey-store"; interface SettingsHotkeysProps {} export const SettingsHotkeys: Component = ({}) => { - const { hotkeys } = HotkeyStore; - return ( - <> - -
- - {(hotkey, index) => { - return ( - <> -
- -
- {hotkeys().length !== index() + 1 &&
} - - ); - }} -
-
-
- + +
+ + {(hotkey, index) => ( + <> +
+ +
+ {HotkeyStore.hotkeys().length !== index() + 1 &&
} + + )} +
+
+
); }; diff --git a/src/components/utils/clipboard/clipboard-footer.tsx b/src/components/utils/clipboard/clipboard-footer.tsx index f15f589e..81f9b5ad 100644 --- a/src/components/utils/clipboard/clipboard-footer.tsx +++ b/src/components/utils/clipboard/clipboard-footer.tsx @@ -10,10 +10,7 @@ interface ClipboardFooterProps { export const ClipboardFooter: Component = (props) => { return ( <> -
- {dayjs.utc(props.data.clipboard.created_date).fromNow()} -
-
+ ); }; diff --git a/src/components/utils/clipboard/clipboard-header.tsx b/src/components/utils/clipboard/clipboard-header.tsx index 70ad25f4..d5b8de52 100644 --- a/src/components/utils/clipboard/clipboard-header.tsx +++ b/src/components/utils/clipboard/clipboard-header.tsx @@ -13,7 +13,7 @@ export const ClipboardHeader: Component = (props) => { const { globalHotkeyEvent } = HotkeyStore; return ( -
+
diff --git a/src/components/utils/shortcut.tsx b/src/components/utils/shortcut.tsx index b4f7057a..623eec9f 100644 --- a/src/components/utils/shortcut.tsx +++ b/src/components/utils/shortcut.tsx @@ -33,7 +33,7 @@ export const Shortcut: Component = (props) => { /> ({ value: key, label: key }))} value={props.hotkey.key} onChange={(currentKey) => { if (typeof currentKey === "number") return; diff --git a/src/index.tsx b/src/index.tsx index 25a6a662..492d84c0 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -14,11 +14,11 @@ const Index = () => { onMount(() => { listenEvent(ListenEvent.Init, AppStore.init); - listenEvent(ListenEvent.EnableGlobalHotkeyEvent, HotkeyStore.setGlobalHotkeyEvent); + listenEvent(ListenEvent.EnableGlobalHotkeyEvent, HotkeyStore.enableGlobalHotkeyEvent); - listenEvent(ListenEvent.ChangeTab, AppStore.setCurrentTab); + listenEvent(ListenEvent.ChangeTab, AppStore.changeTab); - listenEvent(ListenEvent.NewClipboard, ClipboardStore.addClipboard); + listenEvent(ListenEvent.NewClipboard, ClipboardStore.newClipboard); }); return ; diff --git a/src/store/app-store.ts b/src/store/app-store.ts index 7b627460..7f538197 100644 --- a/src/store/app-store.ts +++ b/src/store/app-store.ts @@ -38,12 +38,11 @@ function createAppStore() { }, ]); - const setCurrentTab = (id: Tab) => { - setTabs((prev) => prev.map((s) => ({ ...s, current: s.id === id }))); - }; + const setCurrentTab = (id: Tab) => setTabs((prev) => prev.map((s) => ({ ...s, current: s.id === id }))); const getCurrentTab = () => tabs().find((s) => s.current); const init = async () => { + console.log("init"); HotkeyStore.initHotkeys(); ClipboardStore.initClipboards(); await SettingsStore.initSettings(); @@ -58,7 +57,7 @@ function createAppStore() { return { tabs, setTabs, - setCurrentTab, + changeTab: setCurrentTab, getCurrentTab, init, darkMode, diff --git a/src/store/clipboard-store.ts b/src/store/clipboard-store.ts index 21ef41ed..ca630c2c 100644 --- a/src/store/clipboard-store.ts +++ b/src/store/clipboard-store.ts @@ -90,7 +90,7 @@ function createClipboardStore() { return { clipboards, - addClipboard, + newClipboard: addClipboard, setClipboards, where, setWhere, diff --git a/src/store/hotkey-store.ts b/src/store/hotkey-store.ts index c37de933..a7b8b651 100644 --- a/src/store/hotkey-store.ts +++ b/src/store/hotkey-store.ts @@ -5,7 +5,7 @@ import { InvokeCommand } from "../types/tauri-invoke"; import { invokeCommand } from "../utils/tauri"; function createHotkeyStore() { - const [globalHotkeyEvent, setGlobalHotkeyEvent] = createSignal(false); + const [globalHotkeyEvent, enableGlobalHotkeyEvent] = createSignal(false); const [hotkeys, setHotkeys] = createSignal([]); const updateHotkey = async (hotkey: Hotkey, upload: boolean | undefined = true) => { @@ -22,7 +22,7 @@ function createHotkeyStore() { return { globalHotkeyEvent, - setGlobalHotkeyEvent, + enableGlobalHotkeyEvent, hotkeys, setHotkeys, updateHotkey, diff --git a/src/store/settings-store.ts b/src/store/settings-store.ts index bd07222b..85b69fe5 100644 --- a/src/store/settings-store.ts +++ b/src/store/settings-store.ts @@ -42,7 +42,7 @@ function createSettingsStore() { setSettings(settings); }; - const syncClipboard = async () => invokeCommand(InvokeCommand.GetSettings); + const syncClipboard = async () => invokeCommand(InvokeCommand.SyncClipboardHistory); const openWindow = async (windowName: WebWindow) => invokeCommand(InvokeCommand.OpenNewWindow, { windowName }); diff --git a/src/styles.css b/src/styles.css index 47193193..642e1b3f 100644 --- a/src/styles.css +++ b/src/styles.css @@ -41,3 +41,7 @@ input::-webkit-inner-spin-button { .checkbox:checked + .check-icon { @apply flex; } + +.clipboard { + @apply flex w-full cursor-pointer select-none items-center gap-2 border-b border-zinc-400 px-3 py-2 hover:bg-zinc-200 focus:outline-none dark:border-b-zinc-700 dark:hover:bg-neutral-700; +} diff --git a/src/types/enums.ts b/src/types/enums.ts index df62993c..bc6d971f 100644 --- a/src/types/enums.ts +++ b/src/types/enums.ts @@ -6,7 +6,39 @@ export enum WebWindow { export enum FolderLocation { Database = "database", - Config = "config" + Config = "config", +} + +export enum Language { + // ~1.1 billion speakers + English = "en", + + // ~1.1 billion speakers + Mandarin = "zh", + + // ~600 million speakers + Hindi = "hi", + + // ~550 million speakers + Spanish = "es", + + // ~320 million speakers + French = "fr", + + // ~310 million speakers + Arabic = "ar", + + // ~260 million speakers + Bengali = "bn", + + // ~240 million speakers + Portuguese = "pt", + + // ~230 million speakers + Russian = "ru", + + // ~200 million speakers + Urdu = "ur", } export enum HotkeyEvent { diff --git a/src/types/index.ts b/src/types/index.ts index 581ae38b..905f5726 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,6 +1,6 @@ import { IconTypes } from "solid-icons"; import { SettingsTabName, Tab, TabName } from "../utils/constants"; -import { ClipboardTextType, ClipboardType, HotkeyEvent } from "./enums"; +import { ClipboardTextType, ClipboardType, HotkeyEvent, Language } from "./enums"; export type DatabaseInfo = { records: number; @@ -106,8 +106,14 @@ export type Hotkey = { export type Settings = { id: number; + language: Language; startup: boolean; - notification: boolean; synchronize: boolean; dark_mode: boolean; + display_scale: number; + max_file_size: number; + max_image_size: number; + max_text_size: number; + max_rtf_size: number; + max_html_size: number; };