diff --git a/build.sbt b/build.sbt index 0e91be0..44600db 100644 --- a/build.sbt +++ b/build.sbt @@ -2,5 +2,5 @@ import sbt._ val search = haranaProject("search").in(file(".")) .settings( - libraryDependencies += "com.harana" %%% "web" % "1.0.6" - ) \ No newline at end of file + libraryDependencies += "com.harana" %%% "web" % "1.0.7" + ) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index aeddb16..2ac89ef 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2596,12 +2596,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "cty" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" - [[package]] name = "custom_derive" version = "0.1.7" @@ -3232,12 +3226,6 @@ name = "document" version = "0.1.0" dependencies = [ "common", - "config 0.13.4", - "humansize", - "tantivy 0.1.0", - "time 0.3.34", - "timeago", - "uuid 1.8.0", ] [[package]] @@ -5134,6 +5122,7 @@ dependencies = [ "search_file", "search_index", "search_jobs", + "search_tantivy", "sentry-tauri", "serde", "signal-hook", @@ -6415,34 +6404,6 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47f142fe24a9c9944451e8349de0a56af5f3e7226dc46f3ed4d4ecc0b85af75e" -[[package]] -name = "jni" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24967112a1e4301ca5342ea339763613a37592b8a6ce6cf2e4494537c7a42faf" -dependencies = [ - "cesu8", - "combine", - "jni-sys", - "log", - "thiserror", - "walkdir", -] - -[[package]] -name = "jni" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" -dependencies = [ - "cesu8", - "combine", - "jni-sys", - "log", - "thiserror", - "walkdir", -] - [[package]] name = "jni" version = "0.20.0" @@ -10070,15 +10031,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "raw-window-handle" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" -dependencies = [ - "cty", -] - [[package]] name = "raw-window-handle" version = "0.5.2" @@ -11119,6 +11071,7 @@ dependencies = [ "search_file", "search_index", "search_jobs", + "search_tantivy", ] [[package]] @@ -11190,6 +11143,7 @@ dependencies = [ "rust-embed", "search_core", "search_extensions", + "search_tantivy", "tantivy 0.1.0", ] @@ -11216,6 +11170,21 @@ dependencies = [ "time 0.3.34", ] +[[package]] +name = "search_tantivy" +version = "0.1.0" +dependencies = [ + "common", + "config 0.13.4", + "document", + "humansize", + "search_extensions", + "tantivy 0.1.0", + "time 0.3.34", + "timeago", + "uuid 1.8.0", +] + [[package]] name = "security-framework" version = "2.10.0" @@ -12810,52 +12779,6 @@ dependencies = [ "vibrato", ] -[[package]] -name = "tao" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6fd7725dc1e593e9ecabd9fe49c112a204c8c8694db4182e78b2a5af490b1ae" -dependencies = [ - "bitflags 1.3.2", - "cairo-rs", - "cc", - "cocoa 0.24.1", - "core-foundation 0.9.4", - "core-graphics 0.22.3", - "crossbeam-channel", - "dispatch", - "gdk", - "gdk-pixbuf", - "gdk-sys", - "gdkx11-sys", - "gio", - "glib", - "glib-sys", - "gtk", - "image 0.24.9", - "instant", - "jni 0.19.0", - "lazy_static", - "libc", - "log", - "ndk", - "ndk-context", - "ndk-sys", - "objc", - "once_cell", - "parking_lot 0.12.1", - "paste", - "png 0.17.13", - "raw-window-handle 0.4.3", - "scopeguard", - "serde", - "unicode-segmentation", - "uuid 1.8.0", - "windows 0.37.0", - "windows-implement 0.37.0", - "x11-dl", -] - [[package]] name = "tao" version = "0.16.8" @@ -12882,7 +12805,7 @@ dependencies = [ "gtk", "image 0.24.9", "instant", - "jni 0.20.0", + "jni", "lazy_static", "libappindicator", "libc", @@ -12901,7 +12824,7 @@ dependencies = [ "unicode-segmentation", "uuid 1.8.0", "windows 0.39.0", - "windows-implement 0.39.0", + "windows-implement", "x11-dl", ] @@ -12941,9 +12864,9 @@ checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" [[package]] name = "tauri" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f078117725e36d55d29fafcbb4b1e909073807ca328ae8deb8c0b3843aac0fed" +checksum = "047aefcc7721bfb8024a9bc39d4719112262610502de7a224fa62c4570cd78d4" dependencies = [ "anyhow", "base64 0.21.7", @@ -12958,7 +12881,7 @@ dependencies = [ "glib", "glob", "gtk", - "heck 0.4.1", + "heck 0.5.0", "http", "ignore", "indexmap 1.9.3", @@ -12990,7 +12913,7 @@ dependencies = [ "url", "uuid 1.8.0", "webkit2gtk", - "webview2-com 0.19.1", + "webview2-com", "windows 0.39.0", "zip 0.6.6", ] @@ -13113,7 +13036,7 @@ dependencies = [ "thiserror", "url", "uuid 1.8.0", - "webview2-com 0.19.1", + "webview2-com", "windows 0.39.0", ] @@ -13132,9 +13055,9 @@ dependencies = [ "tauri-utils", "uuid 1.8.0", "webkit2gtk", - "webview2-com 0.19.1", + "webview2-com", "windows 0.39.0", - "wry 0.24.7", + "wry", ] [[package]] @@ -13445,7 +13368,6 @@ dependencies = [ "image 0.24.7", "io", "resize", - "wry 0.19.0", "zune-image", ] @@ -15145,18 +15067,6 @@ dependencies = [ "typeface", ] -[[package]] -name = "webview2-com" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a489a9420acabb3c2ed0434b6f71f6b56b9485ec32665a28dec1ee186d716e0f" -dependencies = [ - "webview2-com-macros", - "webview2-com-sys 0.16.0", - "windows 0.37.0", - "windows-implement 0.37.0", -] - [[package]] name = "webview2-com" version = "0.19.1" @@ -15164,9 +15074,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4a769c9f1a64a8734bde70caafac2b96cada12cd4aefa49196b3a386b8b4178" dependencies = [ "webview2-com-macros", - "webview2-com-sys 0.19.0", + "webview2-com-sys", "windows 0.39.0", - "windows-implement 0.39.0", + "windows-implement", ] [[package]] @@ -15180,20 +15090,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "webview2-com-sys" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0258c53ee9adc0a4f8ba1c8c317588f7a58c7048a55b621d469ba75ab3709ca1" -dependencies = [ - "regex", - "serde", - "serde_json", - "thiserror", - "windows 0.37.0", - "windows-bindgen 0.37.0", -] - [[package]] name = "webview2-com-sys" version = "0.19.0" @@ -15205,8 +15101,8 @@ dependencies = [ "serde_json", "thiserror", "windows 0.39.0", - "windows-bindgen 0.39.0", - "windows-metadata 0.39.0", + "windows-bindgen", + "windows-metadata", ] [[package]] @@ -15308,7 +15204,6 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57b543186b344cc61c85b5aab0d2e3adf4e0f99bc076eff9aa5927bcc0b8a647" dependencies = [ - "windows-implement 0.37.0", "windows_aarch64_msvc 0.37.0", "windows_i686_gnu 0.37.0", "windows_i686_msvc 0.37.0", @@ -15322,7 +15217,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1c4bd0a50ac6020f65184721f758dba47bb9fbc2133df715ec74a237b26794a" dependencies = [ - "windows-implement 0.39.0", + "windows-implement", "windows_aarch64_msvc 0.39.0", "windows_i686_gnu 0.39.0", "windows_i686_msvc 0.39.0", @@ -15359,24 +15254,14 @@ dependencies = [ "windows-targets 0.52.4", ] -[[package]] -name = "windows-bindgen" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bed7be31ade0af08fec9b5343e9edcc005d22b1f11859b8a59b24797f5858e8" -dependencies = [ - "windows-metadata 0.37.0", - "windows-tokens 0.37.0", -] - [[package]] name = "windows-bindgen" version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68003dbd0e38abc0fb85b939240f4bce37c43a5981d3df37ccbaaa981b47cb41" dependencies = [ - "windows-metadata 0.39.0", - "windows-tokens 0.39.0", + "windows-metadata", + "windows-tokens", ] [[package]] @@ -15398,16 +15283,6 @@ dependencies = [ "windows-targets 0.52.4", ] -[[package]] -name = "windows-implement" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a1062e555f7d9d66fd1130ed4f7c6ec41a47529ee0850cd0e926d95b26bb14" -dependencies = [ - "syn 1.0.109", - "windows-tokens 0.37.0", -] - [[package]] name = "windows-implement" version = "0.39.0" @@ -15415,15 +15290,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba01f98f509cb5dc05f4e5fc95e535f78260f15fea8fe1a8abdd08f774f1cee7" dependencies = [ "syn 1.0.109", - "windows-tokens 0.39.0", + "windows-tokens", ] -[[package]] -name = "windows-metadata" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f33f2b90a6664e369c41ab5ff262d06f048fc9685d9bf8a0e99a47750bb0463" - [[package]] name = "windows-metadata" version = "0.39.0" @@ -15502,12 +15371,6 @@ dependencies = [ "windows_x86_64_msvc 0.52.4", ] -[[package]] -name = "windows-tokens" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3263d25f1170419995b78ff10c06b949e8a986c35c208dc24333c64753a87169" - [[package]] name = "windows-tokens" version = "0.39.0" @@ -15756,38 +15619,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "wry" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce19dddbd3ce01dc8f14eb6d4c8f914123bf8379aaa838f6da4f981ff7104a3f" -dependencies = [ - "block", - "cocoa 0.24.1", - "core-graphics 0.22.3", - "gdk", - "gio", - "glib", - "gtk", - "http", - "jni 0.18.0", - "libc", - "log", - "objc", - "objc_id", - "once_cell", - "serde", - "serde_json", - "tao 0.12.2", - "thiserror", - "url", - "webkit2gtk", - "webkit2gtk-sys", - "webview2-com 0.16.0", - "windows 0.37.0", - "windows-implement 0.37.0", -] - [[package]] name = "wry" version = "0.24.7" @@ -15816,14 +15647,14 @@ dependencies = [ "serde_json", "sha2 0.10.8", "soup2", - "tao 0.16.8", + "tao", "thiserror", "url", "webkit2gtk", "webkit2gtk-sys", - "webview2-com 0.19.1", + "webview2-com", "windows 0.39.0", - "windows-implement 0.39.0", + "windows-implement", ] [[package]] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 5fa0e06..34d0711 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -24,6 +24,7 @@ harana_search_extensions = { package = "search_extensions", path = "../../search harana_search_file = { package = "search_file", path = "../../search-engine/src/search/file" } harana_search_index = { package = "search_index", path = "../../search-engine/src/search/index" } harana_search_jobs = { package = "search_jobs", path = "../../search-engine/src/search/jobs" } +harana_search_tantivy = { package = "search_tantivy", path = "../../search-engine/src/search/tantivy" } harana_search = { package = "search", path = "../../search-engine/src/search" } harana_thumbnailer = { package = "thumbnailer", path = "../../search-engine/src/thumbnailer" } harana_thumbnailer_core = { package = "thumbnailer_core", path = "../../search-engine/src/thumbnailer/core" } @@ -63,9 +64,9 @@ xcap = "0.0.8" zbus = "4.1.2" [target.'cfg(target_os = "macos")'.dependencies] -core-graphics = {version = "0.23.1" } +cocoa = "0.25" +core-graphics = { version = "0.23.1" } core-foundation = { version = "0.9.3" } -cocoa = { version = "0.25.0" } macos-app-nap = "0.0.1" objc = { version = "0.2.7" } objc_id = { version = "0.1.1" } diff --git a/src-tauri/assets/demos/customer.json b/src-tauri/assets/demos/ama.json similarity index 99% rename from src-tauri/assets/demos/customer.json rename to src-tauri/assets/demos/ama.json index bea594e..511d02d 100644 --- a/src-tauri/assets/demos/customer.json +++ b/src-tauri/assets/demos/ama.json @@ -461,7 +461,7 @@ }, { "id": "2", - "title": "Aurelia Smith", + "title": "Amanda Smith", "subtitle": "#1011 / 1h", "is_file": false, "primary_tokens": [], diff --git a/src-tauri/assets/demos/finance.json b/src-tauri/assets/demos/finance.json index bd7ad2a..cce417f 100644 --- a/src-tauri/assets/demos/finance.json +++ b/src-tauri/assets/demos/finance.json @@ -2,11 +2,93 @@ "virtualerp-accounts": [ { "id": "1", - "title": "Title", + "title": "Benjamin Jones", + "subtitle": "#1010 / 5m", "is_file": false, "primary_tokens": [], "secondary_tokens": [], - "cards": [] + "cards": ["demo_customer_notes", "demo_customer_info", "demo_customer_timeline", "demo_customer_lastorder", "demo_customer_spend"] + }, + { + "id": "2", + "title": "Amanda Smith", + "subtitle": "#1011 / 1h", + "is_file": false, + "primary_tokens": [], + "secondary_tokens": [], + "cards": ["demo_customer_notes", "demo_customer_info", "demo_customer_timeline", "demo_customer_lastorder", "demo_customer_spend"] + }, + { + "id": "3", + "title": "Dominic Ford", + "subtitle": "#1003 / 2h", + "is_file": false, + "primary_tokens": [], + "secondary_tokens": [], + "cards": ["demo_customer_notes", "demo_customer_info", "demo_customer_timeline", "demo_customer_lastorder", "demo_customer_spend"] + }, + { + "id": "4", + "title": "Finn Smith", + "subtitle": "#1017 / 2h", + "is_file": false, + "primary_tokens": [], + "secondary_tokens": [], + "cards": ["demo_customer_notes", "demo_customer_info", "demo_customer_timeline", "demo_customer_lastorder", "demo_customer_spend"] + }, + { + "id": "5", + "title": "Grace Ford", + "subtitle": "#1022 / 1d", + "is_file": false, + "primary_tokens": [], + "secondary_tokens": [], + "cards": ["demo_customer_notes", "demo_customer_info", "demo_customer_timeline", "demo_customer_lastorder", "demo_customer_spend"] + }, + { + "id": "6", + "title": "Luna Zimmerman", + "subtitle": "#1023 / 2d", + "is_file": false, + "primary_tokens": [], + "secondary_tokens": [], + "cards": ["demo_customer_notes", "demo_customer_info", "demo_customer_timeline", "demo_customer_lastorder", "demo_customer_spend"] + }, + { + "id": "7", + "title": "Nora Vasquez", + "subtitle": "#1024 / 2d", + "is_file": false, + "primary_tokens": [], + "secondary_tokens": [], + "cards": ["demo_customer_notes", "demo_customer_info", "demo_customer_timeline", "demo_customer_lastorder", "demo_customer_spend"] + }, + { + "id": "8", + "title": "Sophia Owens", + "subtitle": "#1025 / 3d", + "is_file": false, + "primary_tokens": [], + "secondary_tokens": [], + "cards": ["demo_customer_notes", "demo_customer_info", "demo_customer_timeline", "demo_customer_lastorder", "demo_customer_spend"] + }, + { + "id": "9", + "title": "Willa Ford", + "subtitle": "#1009 / 1w", + "is_file": false, + "primary_tokens": [], + "secondary_tokens": [], + "cards": ["demo_customer_notes", "demo_customer_info", "demo_customer_timeline", "demo_customer_lastorder", "demo_customer_spend"] + }, + { + "id": "10", + "title": "Xander Jones", + "subtitle": "#1010 / 1w", + "is_file": false, + "primary_tokens": [], + "secondary_tokens": [], + "cards": ["demo_customer_notes", "demo_customer_info", "demo_customer_timeline", "demo_customer_lastorder", "demo_customer_spend"] } ], "virtualerp-accounts-payable": [ diff --git a/src-tauri/assets/logo.png b/src-tauri/assets/logo.png new file mode 100644 index 0000000..7e5c58f Binary files /dev/null and b/src-tauri/assets/logo.png differ diff --git a/src-tauri/assets/onboarding_hero.jpg b/src-tauri/assets/onboarding_hero.jpg new file mode 100644 index 0000000..b7f227f Binary files /dev/null and b/src-tauri/assets/onboarding_hero.jpg differ diff --git a/src-tauri/src/handler_thumbnail.rs b/src-tauri/src/handler_thumbnail.rs index 5471bb0..96e87f4 100644 --- a/src-tauri/src/handler_thumbnail.rs +++ b/src-tauri/src/handler_thumbnail.rs @@ -7,6 +7,7 @@ use harana_common::log::debug; use harana_database::files_get_document_id::files_get_document_id; use harana_document::document::Document; use harana_search_extensions::extensions::Extensions; +use harana_search_tantivy::document::TantivyDocument; use harana_thumbnailer_core::image::Image; use harana_thumbnailer_core::image::ImageType; @@ -23,9 +24,8 @@ pub async fn get_document(document_id: String) -> Result<(Document, String), Str let index_name = Extensions::category(format, extension).index(); let index = INDEX_MANAGER.get().unwrap().get_index(index_name); let document_hit = index.get_document(u64_id.clone()).await.map_err(|e| e.to_string())?; - let document = Document::from_hit(document_hit); + let document = TantivyDocument::from_hit(document_hit); let thumbnailer = Extensions::thumbnailer(None, extension).await.get_name().replace("Thumbnailer", ""); - println!("Thumbnail {} for file {}", thumbnailer, extension); Ok((document, thumbnailer)) } diff --git a/src-tauri/src/handler_welcome.rs b/src-tauri/src/handler_welcome.rs index 33b94ff..62e18f2 100644 --- a/src-tauri/src/handler_welcome.rs +++ b/src-tauri/src/handler_welcome.rs @@ -1,5 +1,6 @@ use std::process::Command; use harana_common::anyhow::Result; +use harana_database::settings_upsert::settings_upsert; use harana_database::state_upsert::state_upsert; use tauri; use tauri::{AppHandle, Wry}; @@ -7,6 +8,7 @@ use tauri::{AppHandle, Wry}; use crate::globals::{ONBOARDED, WELCOME_WINDOW}; use crate::handlers::database_core; use crate::windows::init_main_window; +use crate::windows_mac; #[tauri::command] pub async fn get_onboarded() -> Result { @@ -16,47 +18,56 @@ pub async fn get_onboarded() -> Result { } #[tauri::command] -pub async fn complete_onboarding(app_handle: AppHandle) -> Result<(), String> { +pub async fn complete_onboarding(app_handle: AppHandle, allow_telemetry: bool, anonymous_mode: bool, override_spotlight: bool) -> Result<(), String> { + let shortcut_key = if override_spotlight { "CommandOrControl+Space" } else { "CommandOrControl+Shift+Space" }; + database_core(move |c| { - state_upsert(c, "has_onboarded".to_string(), "true".to_string()) + state_upsert(c, "has_onboarded".to_string(), "true".to_string()).unwrap(); + settings_upsert(c, "privacy_allow_telemetry".to_string(), allow_telemetry.to_string()).unwrap(); + settings_upsert(c, "privacy_anonymous_mode".to_string(), anonymous_mode.to_string()).unwrap(); + + settings_upsert(c, "appearance_shortcut_key".to_string(), shortcut_key.to_string()).unwrap(); + Ok(()) }).await?; - // Disable existing Spotlight key command - Command::new("defaults") - .args([ - "write", - "com.apple.symbolichotkeys.plist", - "AppleSymbolicHotKeys", - "-dict-add", - "64", - " - - enabled - value - typestandard - parameters - - 32 - 49 - 1048576 - - - -" - ]) - .output() - .expect("Failed to apply Spotlight preferences"); + if override_spotlight { + Command::new("defaults") + .args([ + "write", + "com.apple.symbolichotkeys.plist", + "AppleSymbolicHotKeys", + "-dict-add", + "64", + " + + enabled + value + typestandard + parameters + + 32 + 49 + 1048576 + + + + " + ]) + .output() + .expect("Failed to apply Spotlight preferences"); - // Apply Spotlight change settings - Command::new("/System/Library/PrivateFrameworks/SystemAdministration.framework/Resources/activateSettings") - .args(["-u"]) - .output() - .expect("Failed to apply Spotlight preferences"); + // Apply Spotlight change settings + Command::new("/System/Library/PrivateFrameworks/SystemAdministration.framework/Resources/activateSettings") + .args(["-u"]) + .output() + .expect("Failed to apply Spotlight preferences"); + } // Init main window unsafe { ONBOARDED = true; } - init_main_window(app_handle).await.unwrap(); + init_main_window(app_handle.clone()).await.unwrap(); + windows_mac::register_shortcut(app_handle.clone(), shortcut_key.to_string()); Ok(()) } diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 043d031..f57d325 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -150,7 +150,8 @@ fn main() { let _ = JOB_MANAGER.set(JobManager::new( DATABASE_PATH.get().unwrap(), - num_cpus::get() / 2, + 1, + // num_cpus::get() / 4, 1, DATABASE_MANAGER.get().unwrap(), job_handlers, diff --git a/src-tauri/src/windows.rs b/src-tauri/src/windows.rs index aade2ef..8a8c707 100644 --- a/src-tauri/src/windows.rs +++ b/src-tauri/src/windows.rs @@ -9,11 +9,11 @@ use tauri::{App, AppHandle, Manager}; use crate::globals::*; use crate::system_tray::{disable_system_tray, enable_system_tray}; -use crate::windows_main; +use crate::{windows_mac, windows_main}; pub async fn create_windows(app: &mut App) -> Result<()> { #[cfg(target_os = "macos")] - app.set_activation_policy(tauri::ActivationPolicy::Accessory); + app.set_activation_policy(tauri::ActivationPolicy::Prohibited); let billing_window = app.get_window("billing").unwrap(); billing_window.eval("window.location.replace('/billing')").unwrap(); @@ -42,7 +42,6 @@ pub async fn create_windows(app: &mut App) -> Result<()> { // Load previous search positions let positions = DATABASE_MANAGER.get().unwrap().core(|c| Ok({ if let Some(json) = state_get(c, "window_positions".to_string())? { - println!("Found JSON: {}", json.as_str()); serde_json::from_str(json.as_str()).unwrap() }else{ DashMap::new() @@ -58,6 +57,11 @@ pub async fn create_windows(app: &mut App) -> Result<()> { init_main_window(app.handle()).await.unwrap(); if has_onboarded { + let shortcut_key = DATABASE_MANAGER.get().unwrap().core(move |c| + settings_get(c, "appearance_shortcut_key".to_string()) + ).await?.unwrap(); + windows_mac::register_shortcut(app.handle(), shortcut_key.to_string()); + enable_system_tray(app.handle()).unwrap(); windows_main::show_search(app.handle()) }else{ @@ -71,12 +75,8 @@ pub async fn init_main_window(app_handle: AppHandle) -> Result<()> { settings_get(c, "appearance_always_center_window".to_string()) ).await.unwrap().map(|v| v == "1").unwrap_or(false); - let shortcut_key = DATABASE_MANAGER.get().unwrap().core(move |c| - settings_get(c, "appearance_shortcut_key".to_string()) - ).await?.unwrap_or("CommandOrControl+Space".to_string()); - let debug = env::var("HARANA_DEBUG").is_ok(); - windows_main::init_main_panel(app_handle.clone(), shortcut_key, always_center, debug); + windows_main::init_main_panel(app_handle.clone(), always_center, debug); if debug { windows_main::disable_auto_hide(app_handle.clone()); } diff --git a/src-tauri/src/windows_mac.rs b/src-tauri/src/windows_mac.rs index c0fc8d1..e2bccd7 100644 --- a/src-tauri/src/windows_mac.rs +++ b/src-tauri/src/windows_mac.rs @@ -7,8 +7,7 @@ use cocoa::{ base::{BOOL, id, nil, NO, YES}, foundation::{NSPoint, NSRect}, }; -use cocoa::appkit::NSWindow; -use harana_common::log::info; +use cocoa::appkit::{NSMainMenuWindowLevel, NSWindow}; use objc::{ class, declare::ClassDecl, @@ -70,12 +69,10 @@ macro_rules! nsstring_to_string { static INIT: Once = Once::new(); static PANEL_LABEL: &str = "search"; -pub fn init_main_panel(app_handle: AppHandle, shortcut: String, always_center: bool, show_devtools: bool) { +pub fn init_main_panel(app_handle: AppHandle, always_center: bool, show_devtools: bool) { INIT.call_once(|| { - info!("Initialising NS Panel .."); let search_window = app_handle.get_window(PANEL_LABEL).unwrap(); let _ = SEARCH_WINDOW.set(search_window.clone()); - set_state!(app_handle, always_center_window, always_center); unsafe { @@ -85,13 +82,10 @@ pub fn init_main_panel(app_handle: AppHandle, shortcut: String, always_cent if show_devtools { search_window.open_devtools(); } - - info!("Registering shortcut .."); - register_shortcut(app_handle, shortcut); }); } -fn register_shortcut(app_handle: AppHandle, shortcut: String) { +pub fn register_shortcut(app_handle: AppHandle, shortcut: String) { let mut shortcut_manager = app_handle.global_shortcut_manager(); let window = app_handle.get_window(PANEL_LABEL).unwrap(); @@ -129,7 +123,6 @@ pub fn show_search(app_handle: AppHandle) { unsafe { let welcome_window = WELCOME_WINDOW.get().unwrap(); if ONBOARDED && welcome_window.is_visible().unwrap() { - info!("Hiding welcome window .."); welcome_window.hide().unwrap(); } } @@ -387,7 +380,6 @@ impl RawNSPanelDelegate { /// Hide panel when it's no longer the key window extern "C" fn window_did_resign_key(this: &Object, _: Sel, _: id) { - //println!("WINDOW DID RESIGN KEY") let panel: id = unsafe { *this.get_ivar("panel") }; let _: () = unsafe { msg_send![panel, orderOut: nil] }; } @@ -408,31 +400,21 @@ impl RawNSPanelDelegate { } unsafe fn create_main_panel(window: &Window) -> ShareId { - // Convert NSWindow Object to NSPanel let handle: id = window.ns_window().unwrap() as _; let panel = RawNSPanel::from(handle); let panel = panel.share(); - - // Disable shadow handle.setHasShadow_(BOOL::from(false)); + panel.set_level(NSMainMenuWindowLevel + 1); + panel.set_style_mask(NSWindowStyleMaskNonActivatingPanel); - // Set panel above the main menu window level - // panel.set_level(NSMainMenuWindowLevel + 1); - - // Ensure that the panel can display over the top of fullscreen apps panel.set_collection_behaviour( NSWindowCollectionBehavior::NSWindowCollectionBehaviorTransient | NSWindowCollectionBehavior::NSWindowCollectionBehaviorCanJoinAllSpaces | NSWindowCollectionBehavior::NSWindowCollectionBehaviorFullScreenAuxiliary, ); - // Ensures panel does not activate - panel.set_style_mask(NSWindowStyleMaskNonActivatingPanel); - - // Setup delegate for an NSPanel to listen for window resign key and hide the panel toggle_delegate(panel.clone(), true); - panel } diff --git a/src-tauri/src/windows_main.rs b/src-tauri/src/windows_main.rs index ccc9e9d..7babe05 100644 --- a/src-tauri/src/windows_main.rs +++ b/src-tauri/src/windows_main.rs @@ -2,9 +2,9 @@ use tauri::{AppHandle, Wry}; #[cfg(target_os = "macos")] use crate::windows_mac; -pub fn init_main_panel(app_handle: AppHandle, shortcut: String, always_center: bool, show_devtools: bool) { +pub fn init_main_panel(app_handle: AppHandle, always_center: bool, show_devtools: bool) { #[cfg(target_os = "macos")] - windows_mac::init_main_panel(app_handle, shortcut, always_center, show_devtools) + windows_mac::init_main_panel(app_handle, always_center, show_devtools) } #[tauri::command] diff --git a/src/css/core.css b/src/css/core.css index ce471f4..57d427b 100644 --- a/src/css/core.css +++ b/src/css/core.css @@ -1094,6 +1094,10 @@ table tbody tr:last-of-type td:last-of-type { width: 250px; } +.w-275 { + width: 275px; +} + .w-300 { width: 300px; } diff --git a/src/main/scala/com/harana/search/client/cards/Card.scala b/src/main/scala/com/harana/search/client/cards/Card.scala index 19b2f88..3a02ea6 100644 --- a/src/main/scala/com/harana/search/client/cards/Card.scala +++ b/src/main/scala/com/harana/search/client/cards/Card.scala @@ -53,7 +53,7 @@ object Card { "demo_software_table" -> DemoSoftwareTableCard, "empty" -> EmptyCard, "feed" -> DemoCustomerTimelineCard, - "file" -> FileCard, + "file_info" -> FileInfoCard, "map" -> MapCard, "metadata" -> MetadataCard, "notes" -> NotesCard, diff --git a/src/main/scala/com/harana/search/client/cards/CardHandler.scala b/src/main/scala/com/harana/search/client/cards/CardHandler.scala index c63e1d4..7201724 100644 --- a/src/main/scala/com/harana/search/client/cards/CardHandler.scala +++ b/src/main/scala/com/harana/search/client/cards/CardHandler.scala @@ -33,33 +33,36 @@ class CardHandler extends ActionHandler(zoomTo(_.cardState)) { effectOnly(action(UpdateMiddleVerticalIndex(value.middleVerticalIndex + 1))) case UpdateCards(cards) => - if (cards.nonEmpty) - updated(value.copy(cards = cards), action( - ActionBatch( - UpdateMiddleHorizontalIndex(0), - UpdateMiddleVerticalIndex(0) - ) + updated(value.copy(cards = cards), action( + ActionBatch( + UpdateMiddleHorizontalIndex(0), + UpdateMiddleVerticalIndex(0) + ) + )) + + case UpdateMiddleHorizontalIndex(index: Int) => + if (index < value.cards.size) + updated(value.copy( + horizontalLeftCard = if (index > 0) Some(value.cards(index - 1).head) else None, + horizontalRightCard = if (index < value.cards.size - 1) Some(value.cards(index + 1).head) else None, + middleCard = Some(value.cards(index).head), + middleHorizontalIndex = index, + verticalTopCard = None, + verticalBottomCard = value.cards(index).lift(1) )) else noChange - case UpdateMiddleHorizontalIndex(index: Int) => - updated(value.copy( - horizontalLeftCard = if (index > 0) Some(value.cards(index - 1).head) else None, - horizontalRightCard = if (index < value.cards.size - 1) Some(value.cards(index + 1).head) else None, - middleCard = Some(value.cards(index).head), - middleHorizontalIndex = index, - verticalTopCard = None, - verticalBottomCard = value.cards(index).lift(1) - )) - case UpdateMiddleVerticalIndex(index: Int) => - val verticalCards = value.cards(value.middleHorizontalIndex) - updated(value.copy( - middleCard = Some(verticalCards(index)), - middleVerticalIndex = index, - verticalTopCard = if (index > 0) Some(verticalCards(index-1)) else None, - verticalBottomCard = if (index < verticalCards.size - 1) Some(verticalCards(index+1)) else None - )) + val verticalCards = if (value.cards.isEmpty) List() else value.cards(value.middleHorizontalIndex) + if (index < verticalCards.size) + updated(value.copy( + middleCard = Some(verticalCards(index)), + middleVerticalIndex = index, + verticalTopCard = if (index > 0) Some(verticalCards(index-1)) else None, + verticalBottomCard = if (index < verticalCards.size - 1) Some(verticalCards(index+1)) else None + )) + else + noChange } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/CardPanel.scala b/src/main/scala/com/harana/search/client/cards/CardPanel.scala index 1c478a5..11d13ba 100644 --- a/src/main/scala/com/harana/search/client/cards/CardPanel.scala +++ b/src/main/scala/com/harana/search/client/cards/CardPanel.scala @@ -64,7 +64,7 @@ import slinky.web.html._ button(disabled := !searchState.allowPreview, onClick := (_ => Circuit.dispatch(ShowPreview(searchState.selectedDocument.get))), `type` := "button", className := s"rounded-l-md px-3 $buttonClass ${if (!searchState.allowPreview) "disabled:opacity-50" }")("Preview"), button(disabled := searchState.selectedDocument.get.path.isEmpty, onClick := (_ => Circuit.dispatch(Open)), `type` := "button", className := s"-ml-px px-3 $buttonClass ${if (searchState.selectedDocument.get.path.isEmpty) "disabled:opacity-50" }")("Open"), button(disabled := searchState.selectedDocument.get.parentFolderPath.isEmpty, onClick := (_ => Circuit.dispatch(OpenParentFolder)), `type` := "button", className := s"-ml-px px-3 $buttonClass ${if (searchState.selectedDocument.get.parentFolderPath.isEmpty) "disabled:opacity-50" }")("Show Folder"), - button(onClick := (_ => Circuit.dispatch(Share)), `type` := "button", className := s"-ml-px px-3 rounded-r-md $buttonClass")("Share") + button(disabled := !searchState.allowShare, onClick := (_ => Circuit.dispatch(Share)), `type` := "button", className := s"-ml-px px-3 rounded-r-md $buttonClass ${if (!searchState.allowShare) "disabled:opacity-50" }")("Share") ), span(className := "inline-flex right justify-center rounded-md pt-6 pb-15 mr--4")( ), diff --git a/src/main/scala/com/harana/search/client/cards/demo/building/DemoBuildingThumbnailCard.scala b/src/main/scala/com/harana/search/client/cards/demo/building/DemoBuildingThumbnailCard.scala index 3d33d9e..47ae928 100644 --- a/src/main/scala/com/harana/search/client/cards/demo/building/DemoBuildingThumbnailCard.scala +++ b/src/main/scala/com/harana/search/client/cards/demo/building/DemoBuildingThumbnailCard.scala @@ -12,7 +12,7 @@ object DemoBuildingThumbnailCard extends Card { def element(document: Document, integration: IntegrationId, thumbnail: Option[String]): ReactElement = { div(className := s"flex-none card-default")( - img(style := literal("max-width" -> "320px"), src := convertFileSrc(s"assets/demos/floorplan.png")) + img(style := literal("maxWidth" -> "320px"), src := convertFileSrc(s"assets/demos/floorplan.png")) ) } diff --git a/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerInfoCard.scala b/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerInfoCard.scala index 82f5a49..0964971 100644 --- a/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerInfoCard.scala +++ b/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerInfoCard.scala @@ -12,7 +12,7 @@ object DemoCustomerInfoCard extends Card { tbody(className := "divide-y divide-gray-200 bg-white")( tr( td(className := "whitespace-nowrap py-2 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0")("Total Spend"), - td(className := "whitespace-nowrap px-3 py-2 text-sm text-gray-500")("$3,5890.03") + td(className := "whitespace-nowrap px-3 py-2 text-sm text-gray-500")("$35,890.03") ), tr( td(className := "whitespace-nowrap py-2 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0")("Orders"), @@ -23,7 +23,7 @@ object DemoCustomerInfoCard extends Card { td(className := "whitespace-nowrap px-3 py-2 text-sm text-gray-500")("Hobart, TAS") ), tr( - td(className := "whitespace-nowrap py-2 pl-4 pr-3 text-sm font-medium text-gray-00 sm:pl-0")("Last Order"), + td(className := "whitespace-nowrap py-2 pl-4 pr-3 text-sm font-medium text-gray-00 sm:pl-0")("Previous Order"), td(className := "whitespace-nowrap px-3 py-2 text-sm text-gray-500")("11 April 2024") ), tr( @@ -43,5 +43,5 @@ object DemoCustomerInfoCard extends Card { ) ) - override def title = Some("Information") + override def title = Some("Customer") } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerLastOrderCard.scala b/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerLastOrderCard.scala index 4b6019c..ded2787 100644 --- a/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerLastOrderCard.scala +++ b/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerLastOrderCard.scala @@ -37,5 +37,5 @@ object DemoCustomerLastOrderCard extends Card { ) ) - override def title = Some("Last Order") + override def title = Some("Previous Order") } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerNotesCard.scala b/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerNotesCard.scala index 29d6ed6..2242002 100644 --- a/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerNotesCard.scala +++ b/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerNotesCard.scala @@ -19,13 +19,13 @@ object DemoCustomerNotesCard extends Card { figcaption(className := "mt-8 flex items-center gap-x-4")( img(className := "h-10 w-10 rounded-full bg-gray-50", src := "https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"), div( - div(className := "font-semibold")("Aurelia Smith"), - div(className := "text-gray-600")("@aurelia") + div(className := "font-semibold")("Amanda Smith"), + div(className := "text-gray-600")("@amanda") ) ) ) ) ) - override def title = Some("Latest Notes") + override def title = Some("Notes") } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerSpendCard.scala b/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerSpendCard.scala index 1092a01..246812a 100644 --- a/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerSpendCard.scala +++ b/src/main/scala/com/harana/search/client/cards/demo/customer/DemoCustomerSpendCard.scala @@ -57,5 +57,5 @@ object DemoCustomerSpendCard extends Card { ) ) - override val title = Some("Total Spend") + override val title = Some("Recent Spend") } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/demo/software/DemoSoftwareTableCard.scala b/src/main/scala/com/harana/search/client/cards/demo/software/DemoSoftwareTableCard.scala index 9637cf5..67f431a 100644 --- a/src/main/scala/com/harana/search/client/cards/demo/software/DemoSoftwareTableCard.scala +++ b/src/main/scala/com/harana/search/client/cards/demo/software/DemoSoftwareTableCard.scala @@ -46,5 +46,5 @@ object DemoSoftwareTableCard extends Card { ) ) - override def title = Some("Information") + override def title = Some("Customer") } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/general/AudioPlayCard.scala b/src/main/scala/com/harana/search/client/cards/general/AudioPlayCard.scala index 8d91f4d..83f76b9 100644 --- a/src/main/scala/com/harana/search/client/cards/general/AudioPlayCard.scala +++ b/src/main/scala/com/harana/search/client/cards/general/AudioPlayCard.scala @@ -10,7 +10,7 @@ object AudioPlayCard extends Card { def element(document: Document, integration: IntegrationId, thumbnail: Option[String]): ReactElement = { div(className := s"flex-none card-default bg-gradient-to-br from-green-400 to-blue-600")( - span("default-icon")(Integrations.get(integration).icon) + span(className := "default-icon")(Integrations.get(integration).icon) ) } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/general/CameraCard.scala b/src/main/scala/com/harana/search/client/cards/general/CameraCard.scala index 569ba19..b132d8e 100644 --- a/src/main/scala/com/harana/search/client/cards/general/CameraCard.scala +++ b/src/main/scala/com/harana/search/client/cards/general/CameraCard.scala @@ -13,7 +13,7 @@ object CameraCard extends Card { def element(document: Document, integration: IntegrationId, thumbnail: Option[String]): ReactElement = { div(className := s"flex-none card-default bg-gradient-to-br from-purple-600 to-blue-500")( - span("default-icon")(Integrations.get(integration).icon) + span(className := "default-icon")(Integrations.get(integration).icon) ) } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/general/CodeCard.scala b/src/main/scala/com/harana/search/client/cards/general/CodeCard.scala index 10f2686..b4363f2 100644 --- a/src/main/scala/com/harana/search/client/cards/general/CodeCard.scala +++ b/src/main/scala/com/harana/search/client/cards/general/CodeCard.scala @@ -13,7 +13,7 @@ object CodeCard extends Card { def element(document: Document, integration: IntegrationId, thumbnail: Option[String]): ReactElement = { div(className := s"flex-none card-default bg-gradient-to-r from-cyan-500 to-blue-500")( - span("default-icon")(Integrations.get(integration).icon) + span(className := "default-icon")(Integrations.get(integration).icon) ) } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/general/DataSchemaCard.scala b/src/main/scala/com/harana/search/client/cards/general/DataSchemaCard.scala index 878f90f..167eabc 100644 --- a/src/main/scala/com/harana/search/client/cards/general/DataSchemaCard.scala +++ b/src/main/scala/com/harana/search/client/cards/general/DataSchemaCard.scala @@ -10,7 +10,7 @@ object DataSchemaCard extends Card { def element(document: Document, integration: IntegrationId, thumbnail: Option[String]): ReactElement = { div(className := s"flex-none card-default bg-gradient-to-br from-green-400 to-blue-600")( - span("default-icon")(Integrations.get(integration).icon) + span(className := "default-icon")(Integrations.get(integration).icon) ) } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/general/DefaultCard.scala b/src/main/scala/com/harana/search/client/cards/general/DefaultCard.scala index f7422f3..a1a50c9 100644 --- a/src/main/scala/com/harana/search/client/cards/general/DefaultCard.scala +++ b/src/main/scala/com/harana/search/client/cards/general/DefaultCard.scala @@ -13,7 +13,7 @@ object DefaultCard extends Card { def element(document: Document, integration: IntegrationId, thumbnail: Option[String]): ReactElement = { div(className := s"flex-none card-default bg-gradient-to-br from-pink-500 to-orange-400")( - span("default-icon")(Integrations.get(integration).icon) + span(className := "default-icon")(Integrations.get(integration).icon) ) } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/general/FileCard.scala b/src/main/scala/com/harana/search/client/cards/general/FileCard.scala deleted file mode 100644 index 36faafd..0000000 --- a/src/main/scala/com/harana/search/client/cards/general/FileCard.scala +++ /dev/null @@ -1,21 +0,0 @@ -package com.harana.search.client.cards.general - -import com.harana.search.client.cards.Card -import com.harana.search.client.models.Document -import com.harana.search.client.models.Integration.IntegrationId -import com.harana.web.components.when -import slinky.core.facade.ReactElement -import slinky.web.html._ - -object FileCard extends Card { - - def element(document: Document, integration: IntegrationId, thumbnail: Option[String]): ReactElement = { - div(className := s"flex-none card-top bg-gradient-to-r from-slate-500 to-gray-400")( - when(document.accessed, div(className := "card-file-row")(div("Accessed"), div(document.accessed))), - when(document.created, div(className := "card-file-row")(div("Created"), div(document.created))), - when(document.modified, div(className := "card-file-row")(div("Modified"), div(document.modified))), - when(document.size, div(className := "card-file-row")(div("Size"), div(document.size))), - when(document.extensionTitle, div(className := "card-file-row")(div("Type"), div(document.extensionTitle))) - ) - } -} \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/general/FileInfoCard.scala b/src/main/scala/com/harana/search/client/cards/general/FileInfoCard.scala new file mode 100644 index 0000000..327bb9c --- /dev/null +++ b/src/main/scala/com/harana/search/client/cards/general/FileInfoCard.scala @@ -0,0 +1,49 @@ +package com.harana.search.client.cards.general + +import com.harana.search.client.cards.Card +import com.harana.search.client.models.Document +import com.harana.search.client.models.Integration.IntegrationId +import com.harana.web.components.when +import slinky.core.facade.ReactElement +import slinky.web.html._ + +object FileInfoCard extends Card { + + def element(document: Document, integration: IntegrationId, thumbnail: Option[String]) = + table(className := "mt-2 ml-4 divide-y divide-gray-300")( + tbody(className := "divide-y divide-gray-200 bg-white")( + when(document.created, + tr( + td(className := "whitespace-nowrap py-2 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0")("Created"), + td(className := "whitespace-nowrap px-3 py-2 text-sm text-gray-500")(document.created) + ) + ), + when(document.modified, + tr( + td(className := "whitespace-nowrap py-2 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0")("Modified"), + td(className := "whitespace-nowrap px-3 py-2 text-sm text-gray-500")(document.modified) + ) + ), + when(document.accessed, + tr( + td(className := "whitespace-nowrap py-2 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0")("Accessed"), + td(className := "whitespace-nowrap px-3 py-2 text-sm text-gray-500")(document.accessed) + ) + ), + when(document.size, + tr( + td(className := "whitespace-nowrap py-2 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0")("Size"), + td(className := "whitespace-nowrap px-3 py-2 text-sm text-gray-500")(document.size) + ) + ), + when(document.extensionTitle, + tr( + td(className := "whitespace-nowrap py-2 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0")("Type"), + td(className := "whitespace-nowrap px-3 py-2 text-sm text-gray-500")(document.extensionTitle) + ) + ) + ) + ) + + override def title = Some("File Information") +} \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/general/MetadataCard.scala b/src/main/scala/com/harana/search/client/cards/general/MetadataCard.scala index 558b5c8..052bc1b 100644 --- a/src/main/scala/com/harana/search/client/cards/general/MetadataCard.scala +++ b/src/main/scala/com/harana/search/client/cards/general/MetadataCard.scala @@ -13,7 +13,7 @@ object MetadataCard extends Card { def element(document: Document, integration: IntegrationId, thumbnail: Option[String]): ReactElement = { div(className := s"flex-none card-default bg-gradient-to-br from-pink-500 to-orange-400")( - span("default-icon")(Integrations.get(integration).icon) + span(className := "default-icon")(Integrations.get(integration).icon) ) } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/general/NotesCard.scala b/src/main/scala/com/harana/search/client/cards/general/NotesCard.scala index e46ba1e..81dded5 100644 --- a/src/main/scala/com/harana/search/client/cards/general/NotesCard.scala +++ b/src/main/scala/com/harana/search/client/cards/general/NotesCard.scala @@ -19,8 +19,8 @@ object NotesCard extends Card { figcaption(className := "mt-6 flex items-center gap-x-4")( img(className := "h-10 w-10 rounded-full bg-gray-50", src := "https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"), div( - div(className := "font-semibold")("Aurelia Smith"), - div(className := "text-gray-600")("@aurelia") + div(className := "font-semibold")("Amanda Smith"), + div(className := "text-gray-600")("@amanda") ) ) ) diff --git a/src/main/scala/com/harana/search/client/cards/general/PageCard.scala b/src/main/scala/com/harana/search/client/cards/general/PageCard.scala index 6646b08..4072f2f 100644 --- a/src/main/scala/com/harana/search/client/cards/general/PageCard.scala +++ b/src/main/scala/com/harana/search/client/cards/general/PageCard.scala @@ -12,7 +12,7 @@ object PageCard extends Card { def element(document: Document, integration: IntegrationId, thumbnail: Option[String]): ReactElement = { div(className := s"flex-none card-default bg-gradient-to-r from-teal-200 to-lime-200")( - span("default-icon")(Integrations.get(integration).icon) + span(className := "default-icon")(Integrations.get(integration).icon) ) } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/general/SampleCard.scala b/src/main/scala/com/harana/search/client/cards/general/SampleCard.scala index f80b3b7..9196ab6 100644 --- a/src/main/scala/com/harana/search/client/cards/general/SampleCard.scala +++ b/src/main/scala/com/harana/search/client/cards/general/SampleCard.scala @@ -12,7 +12,7 @@ object SampleCard extends Card { def element(document: Document, integration: IntegrationId, thumbnail: Option[String]): ReactElement = { div(className := s"flex-none card-default")( - img(style := literal("max-width" -> "320px"), src := convertFileSrc(s"assets/card.jpg")) + img(style := literal("maxWidth" -> "320px"), src := convertFileSrc(s"assets/card.jpg")) ) } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/general/TableCard.scala b/src/main/scala/com/harana/search/client/cards/general/TableCard.scala index 3b7096d..7025164 100644 --- a/src/main/scala/com/harana/search/client/cards/general/TableCard.scala +++ b/src/main/scala/com/harana/search/client/cards/general/TableCard.scala @@ -23,7 +23,7 @@ object TableCard extends Card { td(className := "whitespace-nowrap px-3 py-2 text-sm text-gray-500")("@nadenf") ), tr( - td(className := "whitespace-nowrap py-2 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0")("Total Spend"), + td(className := "whitespace-nowrap py-2 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0")("Recent Spend"), td(className := "whitespace-nowrap px-3 py-2 text-sm text-gray-500")("$230.42") ), tr( @@ -35,7 +35,7 @@ object TableCard extends Card { td(className := "whitespace-nowrap px-3 py-2 text-sm text-gray-500")("@nadenf") ), tr( - td(className := "whitespace-nowrap py-2 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0")("Total Spend"), + td(className := "whitespace-nowrap py-2 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0")("Recent Spend"), td(className := "whitespace-nowrap px-3 py-2 text-sm text-gray-500")("$230.42") ) ) diff --git a/src/main/scala/com/harana/search/client/cards/general/ThumbnailCard.scala b/src/main/scala/com/harana/search/client/cards/general/ThumbnailCard.scala index f184f31..46d23de 100644 --- a/src/main/scala/com/harana/search/client/cards/general/ThumbnailCard.scala +++ b/src/main/scala/com/harana/search/client/cards/general/ThumbnailCard.scala @@ -15,7 +15,9 @@ object ThumbnailCard extends Card { if (thumbnail.nonEmpty) div(className := s"flex-none card-default card-thumbnail")(img(src := thumbnail.getOrElse("#"))) else - div(className := s"flex-none card-default bg-gradient-to-br from-pink-500 to-orange-400")( - span("default-icon")(Integrations.get(integration).icon) + div(className := s"flex-none card-default bg-gradient-to-br from-grey-600 to-grey-400")( + span(className := "default-icon")(Integrations.get(integration).icon) ) + + override def showBorder = true } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/general/VideoPlayCard.scala b/src/main/scala/com/harana/search/client/cards/general/VideoPlayCard.scala index 006473b..087035d 100644 --- a/src/main/scala/com/harana/search/client/cards/general/VideoPlayCard.scala +++ b/src/main/scala/com/harana/search/client/cards/general/VideoPlayCard.scala @@ -12,7 +12,7 @@ object VideoPlayCard extends Card { def element(document: Document, integration: IntegrationId, thumbnail: Option[String]): ReactElement = { div(className := s"flex-none card-default bg-gradient-to-r from-purple-500 to-pink-500")( - span("default-icon")(Integrations.get(integration).icon) + span(className := "default-icon")(Integrations.get(integration).icon) ) } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/orders/FraudAnalysisCard.scala b/src/main/scala/com/harana/search/client/cards/orders/FraudAnalysisCard.scala index bd16b51..54c8db4 100644 --- a/src/main/scala/com/harana/search/client/cards/orders/FraudAnalysisCard.scala +++ b/src/main/scala/com/harana/search/client/cards/orders/FraudAnalysisCard.scala @@ -10,7 +10,7 @@ object FraudAnalysisCard extends Card { def element(document: Document, integration: IntegrationId, thumbnail: Option[String]): ReactElement = { div(className := s"flex-none card-default bg-gradient-to-br from-green-400 to-blue-600")( - span("default-icon")(Integrations.get(integration).icon) + span(className := "default-icon")(Integrations.get(integration).icon) ) } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/orders/ProductsCards.scala b/src/main/scala/com/harana/search/client/cards/orders/ProductsCards.scala index 37d0207..a73eda2 100644 --- a/src/main/scala/com/harana/search/client/cards/orders/ProductsCards.scala +++ b/src/main/scala/com/harana/search/client/cards/orders/ProductsCards.scala @@ -10,7 +10,7 @@ object ProductsCard extends Card { def element(document: Document, integration: IntegrationId, thumbnail: Option[String]): ReactElement = { div(className := s"flex-none card-default bg-gradient-to-br from-green-400 to-blue-600")( - span("default-icon")(Integrations.get(integration).icon) + span(className := "default-icon")(Integrations.get(integration).icon) ) } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/cards/person/ConversationCard.scala b/src/main/scala/com/harana/search/client/cards/person/ConversationCard.scala index 27e7351..7cc39ec 100644 --- a/src/main/scala/com/harana/search/client/cards/person/ConversationCard.scala +++ b/src/main/scala/com/harana/search/client/cards/person/ConversationCard.scala @@ -10,7 +10,7 @@ object ConversationCard extends Card { def element(document: Document, integration: IntegrationId, thumbnail: Option[String]): ReactElement = { div(className := s"flex-none card-default bg-gradient-to-br from-green-400 to-blue-600")( - span("default-icon")(Integrations.get(integration).icon) + span(className := "default-icon")(Integrations.get(integration).icon) ) } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/icons/keyboard/CommandIcon.scala b/src/main/scala/com/harana/search/client/icons/keyboard/CommandIcon.scala new file mode 100644 index 0000000..739229d --- /dev/null +++ b/src/main/scala/com/harana/search/client/icons/keyboard/CommandIcon.scala @@ -0,0 +1,24 @@ +package com.harana.search.client.icons.keyboard + +import slinky.web.svg._ + +object CommandIcon { + + def apply(iconClassName: String = "", iconHeight: String = "50px") = + svg(className := iconClassName, viewBox := "0 0 187.65 139.05", height := iconHeight)( + g( + g( + path(style := cls2, d := "M40.16-24.3h107.33c8.76,0,15.86,7.11,15.86,15.86v155.92c0,8.76-7.11,15.86-15.86,15.86H40.16c-8.76,0-15.86-7.11-15.86-15.86V-8.44c0-8.75,7.11-15.86,15.86-15.86Z", transform := "translate(163.35 -24.3) rotate(90)"), + path(style := cls1, d := "M15.86,2.7h155.93c7.26,0,13.16,5.9,13.16,13.16v107.33c0,7.26-5.9,13.16-13.16,13.16H15.86c-7.26,0-13.16-5.9-13.16-13.16V15.86c0-7.26,5.9-13.16,13.16-13.16Z"), + path(style := cls2, d := "M44.14,100.04c-.64-2.4-2.11-3.62-4.43-3.66-1.75.04-3.02.72-3.81,2.05-.83,1.32-1.23,2.82-1.21,4.5,0,1.67.39,3.14,1.18,4.43.79,1.33,2.07,2.01,3.84,2.05,2.6-.04,4.13-1.42,4.57-4.14h1.84c-.28,1.73-.95,3.1-2.01,4.13-1.06,1.05-2.52,1.59-4.39,1.61-2.34-.04-4.07-.82-5.18-2.35-1.11-1.51-1.67-3.42-1.67-5.73s.6-4.13,1.78-5.71c1.15-1.57,2.84-2.38,5.07-2.42,3.5-.03,5.56,1.72,6.17,5.25h-1.76Z"), + path(style := cls2, d := "M56.02,111c-1.96-.02-3.58-.72-4.86-2.09-1.34-1.34-2.02-3.35-2.04-6.02,0-2.32.58-4.24,1.73-5.77,1.15-1.52,2.87-2.3,5.17-2.34,2.32.04,4.06.82,5.21,2.34,1.13,1.53,1.7,3.45,1.7,5.77-.02,2.47-.64,4.42-1.87,5.84-1.23,1.49-2.91,2.24-5.04,2.26ZM61.11,102.9c.02-1.87-.36-3.42-1.16-4.65-.79-1.23-2.1-1.85-3.93-1.87-1.8.04-3.1.7-3.89,1.99-.79,1.29-1.18,2.8-1.18,4.53,0,1.94.44,3.49,1.32,4.66.85,1.21,2.09,1.83,3.75,1.84,1.81-.02,3.12-.69,3.93-2.02.77-1.29,1.16-2.78,1.16-4.49Z"), + path(style := cls2, d := "M67.82,110.58h-1.71v-15.39h1.71v2.31h.05c1.06-1.79,2.64-2.69,4.76-2.71,1.4.02,2.43.3,3.09.86.65.55,1.12,1.25,1.42,2.1,1.09-1.97,2.77-2.96,5.02-2.96,1.07,0,1.92.16,2.55.49.64.34,1.11.8,1.42,1.38.32.57.54,1.21.67,1.93.1.75.14,1.5.14,2.28v9.72h-1.71v-10.63c0-1.11-.23-1.98-.69-2.61-.48-.64-1.36-.96-2.64-.96-1.39,0-2.56.59-3.51,1.75-.38.53-.64,1.19-.78,1.96-.17.77-.25,1.51-.25,2.2v8.28h-1.71v-10.63c0-1.11-.23-1.98-.69-2.61-.48-.64-1.36-.96-2.64-.96-1.38,0-2.54.59-3.5,1.76-.38.53-.64,1.18-.79,1.96-.16.77-.24,1.51-.24,2.2v8.28Z"), + path(style := cls2, d := "M92.56,110.58h-1.71v-15.39h1.71v2.31h.06c1.05-1.79,2.64-2.69,4.76-2.71,1.4.02,2.43.3,3.09.86.65.55,1.12,1.25,1.42,2.1,1.09-1.97,2.77-2.96,5.02-2.96,1.07,0,1.92.16,2.55.49.64.34,1.11.8,1.42,1.38.32.57.54,1.21.67,1.93.1.75.15,1.5.15,2.28v9.72h-1.71v-10.63c0-1.11-.23-1.98-.69-2.61-.48-.64-1.36-.96-2.64-.96-1.39,0-2.56.59-3.52,1.75-.38.53-.64,1.19-.77,1.96-.17.77-.25,1.51-.25,2.2v8.28h-1.71v-10.63c0-1.11-.23-1.98-.69-2.61-.48-.64-1.36-.96-2.64-.96-1.38,0-2.54.59-3.5,1.76-.38.53-.64,1.18-.79,1.96-.16.77-.23,1.51-.23,2.2v8.28Z"), + path(style := cls2, d := "M122.96,101.61c.35-.05.74-.11,1.18-.19.42-.1.79-.2,1.1-.32.28-.16.47-.4.55-.71.06-.32.08-.62.08-.9,0-.93-.28-1.68-.84-2.25-.57-.56-1.53-.85-2.88-.87-1.18-.02-2.16.22-2.93.71-.75.52-1.22,1.45-1.42,2.77h-1.76c.18-1.81.83-3.12,1.97-3.93,1.12-.76,2.51-1.15,4.17-1.15,1.55,0,2.83.34,3.85,1.03,1.01.73,1.53,1.98,1.56,3.74v8.38c-.03.67.09,1.09.36,1.28.25.19.74.17,1.45-.09v1.39c-.12.04-.3.09-.55.14-.27.1-.54.14-.81.14s-.52-.03-.77-.09c-.55-.11-.91-.39-1.09-.82-.17-.43-.26-.91-.28-1.44-1.5,1.67-3.35,2.52-5.57,2.54-1.34,0-2.49-.38-3.44-1.13-1-.72-1.51-1.81-1.53-3.29,0-2.6,1.73-4.14,5.2-4.64l2.39-.33ZM125.87,102.51c-.73.28-1.47.48-2.23.6-.75.14-1.5.22-2.25.26-2.77.17-4.17,1.26-4.21,3.28.02.91.36,1.59,1.01,2.05.64.47,1.38.71,2.23.71,1.44,0,2.69-.37,3.77-1.1,1.08-.71,1.64-1.83,1.67-3.38v-2.41Z"), + path(style := cls2, d := "M134.34,110.58h-1.71v-15.39h1.71v2.13c.67-.79,1.4-1.41,2.16-1.86.75-.45,1.63-.68,2.64-.68,1.9-.05,3.42.68,4.55,2.19.36.53.58,1.09.65,1.67.06.59.08,1.21.08,1.87v10.06h-1.71v-10.04c.04-2.77-1.25-4.16-3.85-4.16-1.08.02-1.96.32-2.66.9-.68.57-1.18,1.27-1.49,2.11-.27.93-.4,1.9-.38,2.91v8.28Z"), + path(style := cls2, d := "M160.66,89.2h1.71v21.38h-1.71v-2.68h-.07c-.52,1-1.25,1.76-2.21,2.27-.98.54-1.97.82-2.97.84-2.36-.04-4.08-.82-5.16-2.35-1.07-1.51-1.59-3.42-1.57-5.73,0-2.24.54-4.15,1.63-5.71,1.08-1.57,2.75-2.38,5.02-2.42,1.09,0,2.1.24,3.05.71.94.49,1.7,1.21,2.28,2.16v-8.46ZM160.66,102.84c0-1.81-.44-3.33-1.34-4.56-.88-1.23-2.12-1.86-3.72-1.9-1.78.02-3.09.69-3.92,2.02-.85,1.33-1.24,2.99-1.18,4.97.06,1.95.55,3.43,1.49,4.44.93,1.06,2.13,1.6,3.61,1.6,1.65-.02,2.91-.65,3.77-1.9.85-1.23,1.28-2.78,1.28-4.66Z"), + path(style := cls2, d := "M159.46,36.21h-2.7v-8.1h2.7c2.98,0,5.4-2.42,5.4-5.4s-2.42-5.4-5.4-5.4-5.4,2.42-5.4,5.4v2.7h-8.1v-2.7c0-2.98-2.42-5.4-5.4-5.4s-5.4,2.42-5.4,5.4,2.42,5.4,5.4,5.4h2.7v8.1h-2.7c-2.98,0-5.4,2.42-5.4,5.4s2.42,5.4,5.4,5.4,5.4-2.42,5.4-5.4v-2.7h8.1v2.7c0,2.98,2.42,5.4,5.4,5.4s5.4-2.42,5.4-5.4-2.42-5.4-5.4-5.4ZM156.76,22.71c0-1.49,1.21-2.7,2.7-2.7s2.7,1.21,2.7,2.7-1.21,2.7-2.7,2.7h-2.7v-2.7ZM137.86,22.71c0-1.49,1.21-2.7,2.7-2.7s2.7,1.21,2.7,2.7v2.7h-2.7c-1.49,0-2.7-1.21-2.7-2.7ZM143.26,41.61c0,1.49-1.21,2.7-2.7,2.7s-2.7-1.21-2.7-2.7,1.21-2.7,2.7-2.7h2.7v2.7ZM145.96,36.21v-8.1h8.1v8.1h-8.1ZM159.46,44.31c-1.49,0-2.7-1.21-2.7-2.7v-2.7h2.7c1.49,0,2.7,1.21,2.7,2.7s-1.21,2.7-2.7,2.7Z") + ) + ) + ) +} \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/icons/keyboard/ControlIcon.scala b/src/main/scala/com/harana/search/client/icons/keyboard/ControlIcon.scala new file mode 100644 index 0000000..eef5b22 --- /dev/null +++ b/src/main/scala/com/harana/search/client/icons/keyboard/ControlIcon.scala @@ -0,0 +1,29 @@ +package com.harana.search.client.icons.keyboard + +import slinky.web.svg._ + +object ControlIcon { + + def apply(iconClassName: String = "", iconHeight: String = "50px") = + svg(className := iconClassName, viewBox := "0 0 145.8 139.05", height := iconHeight)( + g( + g( + g( + path(style := cls2, d := "M19.24-3.37h107.33c8.75,0,15.86,7.11,15.86,15.86v114.08c0,8.76-7.11,15.86-15.86,15.86H19.24c-8.76,0-15.86-7.11-15.86-15.86V12.49C3.37,3.73,10.48-3.37,19.24-3.37Z", transform := "translate(142.42 -3.37) rotate(90)"), + path(style := cls1, d := "M15.86,2.7h114.08c7.26,0,13.16,5.9,13.16,13.16v107.33c0,7.26-5.9,13.16-13.16,13.16H15.86c-7.26,0-13.16-5.9-13.16-13.16V15.86c0-7.26,5.9-13.16,13.16-13.16Z") + ), + g( + path(style := cls2, d := "M41.78,100.04c-.64-2.4-2.11-3.62-4.43-3.66-1.75.04-3.02.72-3.81,2.05-.82,1.32-1.23,2.82-1.21,4.5,0,1.67.39,3.14,1.18,4.43.79,1.33,2.07,2.01,3.84,2.05,2.6-.04,4.13-1.42,4.57-4.14h1.84c-.28,1.73-.95,3.1-2.01,4.13-1.06,1.05-2.52,1.59-4.39,1.61-2.34-.04-4.07-.82-5.18-2.35-1.11-1.51-1.67-3.42-1.67-5.73s.59-4.13,1.78-5.71c1.15-1.57,2.84-2.38,5.07-2.42,3.5-.03,5.56,1.72,6.18,5.25h-1.76Z"), + path(style := cls2, d := "M53.67,111c-1.96-.02-3.58-.72-4.86-2.09-1.34-1.34-2.02-3.35-2.04-6.02,0-2.32.58-4.24,1.73-5.77,1.15-1.52,2.87-2.3,5.17-2.34,2.32.04,4.06.82,5.21,2.34,1.13,1.53,1.7,3.45,1.7,5.77-.02,2.47-.64,4.42-1.87,5.84-1.23,1.49-2.91,2.24-5.04,2.26ZM58.75,102.9c.02-1.87-.37-3.42-1.15-4.65-.79-1.23-2.1-1.85-3.93-1.87-1.8.04-3.1.7-3.89,1.99-.79,1.29-1.18,2.8-1.18,4.53,0,1.94.44,3.49,1.32,4.66.85,1.21,2.09,1.83,3.75,1.84,1.81-.02,3.12-.69,3.93-2.02.77-1.29,1.15-2.78,1.15-4.49Z"), + path(style := cls2, d := "M65.98,110.58h-1.71v-15.39h1.71v2.13c.67-.79,1.4-1.41,2.16-1.86.75-.45,1.63-.68,2.64-.68,1.9-.05,3.42.68,4.55,2.19.36.53.58,1.09.65,1.67.06.59.08,1.21.08,1.87v10.06h-1.71v-10.04c.04-2.77-1.25-4.16-3.85-4.16-1.08.02-1.96.32-2.66.9-.69.57-1.18,1.27-1.49,2.11-.27.93-.4,1.9-.38,2.91v8.28Z"), + path(style := cls2, d := "M86.01,110.64c-.21.04-.47.1-.8.17-.35.1-.74.17-1.18.19-.83,0-1.47-.23-1.9-.68-.48-.48-.72-1.28-.72-2.38v-11.27h-2.11v-1.48h2.11v-4.28h1.71v4.28h2.79v1.48h-2.79v10.57c-.02.73.06,1.27.24,1.63.15.36.57.54,1.26.54.48,0,.94-.07,1.4-.2v1.44Z"), + path(style := cls2, d := "M90.84,110.58h-1.71v-15.39h1.71v2.88h.06c.48-1.22,1.1-2.08,1.87-2.57.77-.47,1.76-.71,2.99-.71v1.91c-1.9,0-3.2.6-3.91,1.82-.69,1.23-1.03,2.74-1.01,4.52v7.54Z"), + path(style := cls2, d := "M104.31,111c-1.96-.02-3.58-.72-4.86-2.09-1.34-1.34-2.02-3.35-2.03-6.02,0-2.32.58-4.24,1.73-5.77,1.15-1.52,2.87-2.3,5.17-2.34,2.32.04,4.06.82,5.21,2.34,1.13,1.53,1.7,3.45,1.7,5.77-.02,2.47-.64,4.42-1.87,5.84-1.23,1.49-2.91,2.24-5.04,2.26ZM109.39,102.9c.02-1.87-.37-3.42-1.15-4.65-.79-1.23-2.1-1.85-3.93-1.87-1.8.04-3.1.7-3.89,1.99-.79,1.29-1.18,2.8-1.18,4.53,0,1.94.44,3.49,1.32,4.66.84,1.21,2.09,1.83,3.75,1.84,1.81-.02,3.12-.69,3.93-2.02.77-1.29,1.15-2.78,1.15-4.49Z"), + path(style := cls2, d := "M115.18,110.58v-21.38h1.71v21.38h-1.71Z"), + ), + polygon(points := "119.3 33.37 109.23 23.65 100.16 33.37 95.44 33.37 109.04 17.44 124.18 33.37 119.3 33.37") + ) + ) + ) + +} \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/icons/keyboard/OptionIcon.scala b/src/main/scala/com/harana/search/client/icons/keyboard/OptionIcon.scala new file mode 100644 index 0000000..a9eeb45 --- /dev/null +++ b/src/main/scala/com/harana/search/client/icons/keyboard/OptionIcon.scala @@ -0,0 +1,29 @@ +package com.harana.search.client.icons.keyboard +import slinky.web.svg._ + +object OptionIcon { + + def apply(iconClassName: String = "", iconHeight: String = "50px") = + svg(className := iconClassName, viewBox := "0 0 145.8 139.05", height := iconHeight)( + g( + g( + g( + path(style := cls2, d := "M19.24-3.37h107.33c8.76,0,15.86,7.11,15.86,15.86v114.07c0,8.76-7.11,15.86-15.86,15.86H19.24c-8.76,0-15.86-7.11-15.86-15.86V12.49C3.37,3.73,10.48-3.37,19.24-3.37Z", transform := "translate(142.42 -3.37) rotate(90)"), + path(style := cls1, d := "M15.86,2.7h114.08c7.26,0,13.16,5.9,13.16,13.16v107.33c0,7.26-5.9,13.16-13.16,13.16H15.86c-7.26,0-13.16-5.9-13.16-13.16V15.86c0-7.26,5.9-13.16,13.16-13.16Z") + ), + g( + path(style := cls2, d := "M47.81,110.88c-1.96-.02-3.58-.72-4.86-2.09-1.34-1.34-2.02-3.35-2.04-6.02,0-2.32.58-4.24,1.73-5.77,1.15-1.52,2.87-2.3,5.17-2.33,2.32.04,4.06.82,5.21,2.33,1.13,1.53,1.7,3.45,1.7,5.77-.02,2.47-.64,4.42-1.87,5.84-1.23,1.49-2.91,2.24-5.04,2.26ZM52.9,102.78c.02-1.87-.37-3.42-1.15-4.65-.79-1.23-2.1-1.85-3.93-1.87-1.8.04-3.1.7-3.89,1.99s-1.18,2.8-1.18,4.53c0,1.94.44,3.49,1.32,4.66.84,1.21,2.09,1.82,3.75,1.84,1.81-.02,3.12-.69,3.93-2.02.77-1.29,1.15-2.78,1.15-4.49Z"), + path(style := cls2, d := "M60.34,116.52h-1.71v-21.45h1.71v2.7h.06c.55-1.03,1.31-1.81,2.27-2.34.95-.51,1.92-.77,2.89-.77,2.4.02,4.13.79,5.21,2.31,1.02,1.51,1.53,3.43,1.53,5.77,0,2.2-.54,4.08-1.61,5.64-1.1,1.62-2.77,2.46-5.03,2.49-1.06,0-2.07-.26-3.03-.78-.95-.47-1.72-1.17-2.29-2.09v8.51ZM60.34,102.84c0,1.76.45,3.27,1.35,4.52.88,1.27,2.11,1.91,3.69,1.93,1.78-.02,3.11-.71,3.99-2.08.85-1.29,1.22-2.92,1.11-4.91-.04-1.95-.52-3.44-1.44-4.49-.94-1.04-2.16-1.55-3.66-1.55-1.63.02-2.87.64-3.72,1.87-.88,1.23-1.32,2.8-1.32,4.7Z"), + path(style := cls2, d := "M81.78,110.52c-.21.04-.47.09-.8.17-.35.11-.74.17-1.18.19-.83,0-1.47-.23-1.9-.68-.48-.48-.72-1.28-.72-2.38v-11.26h-2.11v-1.48h2.11v-4.28h1.71v4.28h2.79v1.48h-2.79v10.57c-.02.73.06,1.27.24,1.63.15.36.57.54,1.26.54.48,0,.94-.07,1.4-.2v1.44Z"), + path(style := cls2, d := "M84.99,91.72v-2.64h1.89v2.64h-1.89ZM85.08,110.46v-15.39h1.71v15.39h-1.71Z"), + path(style := cls2, d := "M97.33,110.88c-1.96-.02-3.58-.72-4.86-2.09-1.34-1.34-2.02-3.35-2.04-6.02,0-2.32.58-4.24,1.73-5.77,1.15-1.52,2.87-2.3,5.17-2.33,2.32.04,4.06.82,5.21,2.33,1.13,1.53,1.7,3.45,1.7,5.77-.02,2.47-.64,4.42-1.87,5.84-1.23,1.49-2.91,2.24-5.04,2.26ZM102.41,102.78c.02-1.87-.37-3.42-1.16-4.65-.79-1.23-2.1-1.85-3.93-1.87-1.8.04-3.1.7-3.89,1.99s-1.18,2.8-1.18,4.53c0,1.94.44,3.49,1.32,4.66.85,1.21,2.09,1.82,3.75,1.84,1.81-.02,3.12-.69,3.93-2.02.77-1.29,1.16-2.78,1.16-4.49Z"), + path(style := cls2, d := "M109.64,110.46h-1.71v-15.39h1.71v2.13c.67-.79,1.4-1.41,2.16-1.86.75-.45,1.63-.68,2.64-.68,1.9-.05,3.42.68,4.55,2.19.36.53.58,1.09.65,1.67.06.59.08,1.21.08,1.87v10.06h-1.71v-10.04c.04-2.77-1.24-4.16-3.85-4.16-1.08.02-1.96.32-2.66.9-.68.57-1.18,1.27-1.49,2.1-.27.93-.4,1.9-.38,2.91v8.28Z"), + ), + g( + rect(style := cls2, x := "103.38", y := "20.68", width := "20.25", height := "4.05"), + polygon(style := cls2, points := "123.63 38.23 102.23 38.23 94.13 24.73 85.83 24.73 85.83 20.68 96.43 20.68 104.53 34.18 123.63 34.18 123.63 38.23") + ) + ) + ) + ) +} \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/icons/keyboard/ShiftIcon.scala b/src/main/scala/com/harana/search/client/icons/keyboard/ShiftIcon.scala new file mode 100644 index 0000000..7292df6 --- /dev/null +++ b/src/main/scala/com/harana/search/client/icons/keyboard/ShiftIcon.scala @@ -0,0 +1,25 @@ +package com.harana.search.client.icons.keyboard + +import slinky.web.svg._ + +object ShiftIcon { + + def apply(iconClassName: String = "", iconHeight: String = "50px") = + svg(className := iconClassName, viewBox := "0 0 351 139.05", height := iconHeight)( + g( + g( + g( + path(style := cls2, d := "M121.84-105.97h107.33c8.76,0,15.86,7.11,15.86,15.86V229.16c0,8.76-7.11,15.86-15.86,15.86h-107.32c-8.76,0-15.86-7.11-15.86-15.86V-90.11c0-8.75,7.11-15.86,15.86-15.86Z", transform := "translate(245.02 -105.97) rotate(90)"), + path(style := cls1, d := "M15.86,2.7h319.27c7.26,0,13.16,5.9,13.16,13.16v107.33c0,7.26-5.9,13.16-13.16,13.16H15.86c-7.26,0-13.16-5.9-13.16-13.16V15.86c0-7.26,5.9-13.16,13.16-13.16Z") + ), + g( + path(style := cls2, d := "M29.51,106.21c.46,2.48,1.95,3.69,4.48,3.64,1.27-.02,2.19-.31,2.79-.89.6-.54.9-1.2.9-1.97,0-.55-.13-1.01-.38-1.37-.27-.36-.64-.63-1.1-.83-.19-.12-.42-.22-.69-.3-.27-.1-.55-.17-.83-.23-.58-.12-1.18-.23-1.78-.35-.29-.11-.57-.2-.84-.28-.28-.06-.57-.14-.86-.23-.58-.18-1.1-.42-1.56-.71-.46-.32-.82-.73-1.1-1.22-.28-.5-.42-1.12-.42-1.84,0-1.32.47-2.37,1.4-3.18.9-.79,2.17-1.2,3.82-1.22,3.32-.07,5.24,1.55,5.76,4.84h-1.76c-.15-1.19-.58-2.04-1.29-2.53-.73-.48-1.64-.71-2.74-.71-2.22.06-3.34.94-3.36,2.64,0,.5.15.92.44,1.25.26.32.62.59,1.08.81.95.42,2.03.75,3.26,1,.61.14,1.21.32,1.79.51.57.2,1.08.47,1.52.8.46.32.82.74,1.1,1.25.25.5.38,1.13.38,1.87-.02,1.47-.58,2.58-1.7,3.34-1.13.77-2.59,1.16-4.36,1.16-1.77-.02-3.13-.53-4.08-1.55-.96-.97-1.49-2.19-1.59-3.68h1.74Z"), + path(style := cls2, d := "M43.38,111.02v-21.38h1.71v8.14c.67-.79,1.4-1.42,2.16-1.87.75-.45,1.63-.68,2.64-.68,1.9-.05,3.42.68,4.55,2.19.36.53.58,1.09.65,1.67.06.59.08,1.21.08,1.87v10.06h-1.71v-10.04c.04-2.77-1.25-4.16-3.86-4.16-1.08.02-1.96.32-2.66.9-.68.57-1.18,1.27-1.49,2.1-.27.93-.4,1.9-.38,2.91v8.28h-1.71Z"), + path(style := cls2, d := "M60.07,92.29v-2.64h1.88v2.64h-1.88ZM60.16,111.02v-15.39h1.71v15.39h-1.71Z"), + path(style := cls2, d := "M65.01,97.11v-1.48h2.21v-2.44c-.07-2.59.98-3.92,3.15-3.97.51,0,.99.04,1.43.11v1.63c-.37-.1-.71-.15-1.03-.15-.87.03-1.4.33-1.59.9-.2.59-.28,1.26-.25,2.02v1.9h2.87v1.48h-2.87v13.91h-1.71v-13.91h-2.21Z"), + path(style := cls2, d := "M79.96,111.09c-.21.04-.47.09-.8.17-.35.11-.74.17-1.18.19-.83,0-1.47-.23-1.9-.68-.48-.48-.72-1.28-.72-2.38v-11.27h-2.11v-1.48h2.11v-4.28h1.71v4.28h2.79v1.48h-2.79v10.57c-.02.73.06,1.27.24,1.63.15.36.57.54,1.26.54.48,0,.94-.07,1.4-.2v1.44Z") + ) + ) + ) + ) +} \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/icons/keyboard/SpaceIcon.scala b/src/main/scala/com/harana/search/client/icons/keyboard/SpaceIcon.scala new file mode 100644 index 0000000..6017104 --- /dev/null +++ b/src/main/scala/com/harana/search/client/icons/keyboard/SpaceIcon.scala @@ -0,0 +1,14 @@ +package com.harana.search.client.icons.keyboard + +import slinky.web.svg._ + +object SpaceIcon { + + def apply(iconClassName: String = "", iconHeight: String = "50px") = + svg(className := iconClassName, viewBox := "0 0 801.9 139.05", height := iconHeight)( + g( + path(style := cls2, d := "M347.29-331.43h107.32c8.76,0,15.86,7.11,15.86,15.86V454.61c0,8.75-7.11,15.86-15.86,15.86h-107.33c-8.75,0-15.86-7.11-15.86-15.86V-315.56c0-8.76,7.11-15.86,15.86-15.86Z", transform := "translate(470.48 -331.43) rotate(90)"), + path(style := cls1, d := "M15.86,2.7h770.18c7.26,0,13.16,5.9,13.16,13.16v107.32c0,7.26-5.9,13.16-13.16,13.16H15.86c-7.26,0-13.16-5.9-13.16-13.16V15.86c0-7.26,5.9-13.16,13.16-13.16Z") + ) + ) +} \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/icons/keyboard/package.scala b/src/main/scala/com/harana/search/client/icons/keyboard/package.scala new file mode 100644 index 0000000..f59293b --- /dev/null +++ b/src/main/scala/com/harana/search/client/icons/keyboard/package.scala @@ -0,0 +1,10 @@ +package com.harana.search.client.icons + +import com.harana.web.components.literal + +package object keyboard { + + val cls1 = literal("fill" -> "#f4f4f4", "strokeWidth" -> "0px") + val cls2 = literal("fill" -> "gray", "strokeWidth" -> "0px") + +} diff --git a/src/main/scala/com/harana/search/client/integrations/ui/IntegrationsPanel.scala b/src/main/scala/com/harana/search/client/integrations/ui/IntegrationsPanel.scala index 3abbce4..3ba8b02 100644 --- a/src/main/scala/com/harana/search/client/integrations/ui/IntegrationsPanel.scala +++ b/src/main/scala/com/harana/search/client/integrations/ui/IntegrationsPanel.scala @@ -38,7 +38,7 @@ import scala.scalajs.js.JSConverters.JSRichMap val systemState = Circuit.state(_.systemState, true) val drag = new CustomAttribute[Boolean]("data-tauri-drag-region") - Tauri.invoke("update_window_size", Map("width" -> 950.0, "height" -> 465.0).toJSDictionary) + Tauri.invoke("update_window_size", Map("width" -> 950.0, "height" -> 680.0).toJSDictionary) div(className := "flex min-h-[720px] bg-white rounded-xl")( div(className := "flex w-60 flex-col")( diff --git a/src/main/scala/com/harana/search/client/main/ui/MainPanel.scala b/src/main/scala/com/harana/search/client/main/ui/MainPanel.scala index 36c97a7..1fb7c6d 100644 --- a/src/main/scala/com/harana/search/client/main/ui/MainPanel.scala +++ b/src/main/scala/com/harana/search/client/main/ui/MainPanel.scala @@ -27,9 +27,9 @@ import slinky.web.html._ val keyUpListener = (e: KeyboardEvent) => Circuit.dispatch(KeyUp(e.keyCode, e)) val blurListener = (_: FocusEvent) => if (!Circuit.state(_.systemState, false).isDebug) Circuit.dispatch(Hide) - window.addEventListener("keydown", keyDownListener, false) - window.addEventListener("keyup", keyUpListener, false) - window.addEventListener("blur", blurListener, false) + window.addEventListener("keydown", keyDownListener, true) + window.addEventListener("keyup", keyUpListener, true) + window.addEventListener("blur", blurListener, true) () => { window.removeEventListener("keydown", keyDownListener, false) @@ -87,7 +87,7 @@ import slinky.web.html._ ) Transition(show = true, as = Fragment.component, appear = true)( - Dialog(as = "div", className = "relative z-10", onClose = (_: Boolean) => {})( + Dialog(as = "div", className = "mb-1 relative z-10", onClose = (_: Boolean) => {})( TransitionChild( as = Fragment.component, enter = "ease-out duration-300", enterFrom = "opacity-0", enterTo = "opacity-100", @@ -101,7 +101,7 @@ import slinky.web.html._ enter = "ease-out duration-300", enterFrom = "opacity-0 scale-95", enterTo = "opacity-100 scale-100", leave = "ease-in duration-200", leaveFrom = "opacity-100 scale-100", leaveTo = "opacity-0 scale-95" )( - DialogPanel(className := "mx-auto w-full overflow-auto transform divide-y divide-gray-100 rounded-xl bg-white bg-opacity-70 transition-all")( + DialogPanel(className := "border border-gray-300 mx-auto w-full overflow-auto transform divide-y divide-gray-100 rounded-xl bg-white bg-opacity-70 transition-all")( Popover()( popoverTransition(popoverPanel), div( diff --git a/src/main/scala/com/harana/search/client/models/Document.scala b/src/main/scala/com/harana/search/client/models/Document.scala index 3e21ddf..e701e8f 100644 --- a/src/main/scala/com/harana/search/client/models/Document.scala +++ b/src/main/scala/com/harana/search/client/models/Document.scala @@ -3,6 +3,7 @@ package com.harana.search.client.models import com.harana.search.client.models.Document.DocumentId import com.harana.search.client.models.Integration.IntegrationId import io.circe.generic.extras.ConfiguredJsonCodec +import typings.std.global.console import scala.scalajs.js @@ -55,7 +56,7 @@ case class Document(id: DocumentId, object Document { type DocumentId = String - def apply(rd: RawDocument, integrationId: IntegrationId): Document = { + def apply(rd: RawDocument, integrationId: IntegrationId): Document = Document( rd.id, integrationId, @@ -79,5 +80,4 @@ object Document { Option(rd.metadata), rd.cards.toList ) - } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/preview/PreviewHandler.scala b/src/main/scala/com/harana/search/client/preview/PreviewHandler.scala index 679da17..39bfc3e 100644 --- a/src/main/scala/com/harana/search/client/preview/PreviewHandler.scala +++ b/src/main/scala/com/harana/search/client/preview/PreviewHandler.scala @@ -36,7 +36,6 @@ class PreviewHandler extends ActionHandler(zoomTo(_.previewState)) { case KeyDown(key, event) => effectOnly { event.stopPropagation() - event.preventDefault() key match { case Keys.Space | Keys.Escape => @@ -54,6 +53,8 @@ class PreviewHandler extends ActionHandler(zoomTo(_.previewState)) { } case KeyUp(key, event) => + event.stopPropagation() + noChange case LoadDocument(json) => diff --git a/src/main/scala/com/harana/search/client/search/SearchHandler.scala b/src/main/scala/com/harana/search/client/search/SearchHandler.scala index a172734..a2c94b0 100644 --- a/src/main/scala/com/harana/search/client/search/SearchHandler.scala +++ b/src/main/scala/com/harana/search/client/search/SearchHandler.scala @@ -57,17 +57,15 @@ class SearchHandler extends ActionHandler(zoomTo(_.searchState)) { ) ) else { - val searchTerm = if (term.get == "s") "Sample1" else term.get effectOnly( Effect( - Tauri.invoke("search", Map("query" -> searchTerm)).map { (jsResults: js.Dictionary[js.Array[RawDocument]]) => { + Tauri.invoke("search", Map("query" -> term.get)).map { (jsResults: js.Dictionary[js.Array[RawDocument]]) => { val results = jsResults.toMap.view .map(pair => (pair._1, pair._2.toList.sortBy(_.title.toLowerCase).map(rd => Document(rd, pair._1)))) .toList .sortBy(pair => Integrations.get(pair._1).title.toLowerCase) UpdateSearchResults(results) - } - } + }} ) + Effect( Tauri.invoke("search_application", Map("query" -> term.get)).map { (result: js.UndefOr[RawApplication]) => { @@ -168,7 +166,7 @@ class SearchHandler extends ActionHandler(zoomTo(_.searchState)) { case SelectDocument(documentId, scroll) => val doc = document(documentId) effectOnly( - if (value.selectedDocumentId.isEmpty || value.selectedDocumentId.get != documentId) { + if (value.selectedDocumentId.isEmpty || value.selectedDocumentId.get != documentId) Effect( Tauri.invoke[Unit]("emit_preview_message", Map("name" -> "preview_document_changed", "payload" -> doc.asJson.noSpaces)).map(_ => NoChange) ) + (if (doc.path.isDefined) Effect(Tauri.invoke[String]("get_viewer", Map("path" -> doc.path.get)).map(viewer => UpdateAllowPreview(viewer != "Noop"))) else Effect.action(NoChange)) + @@ -181,7 +179,7 @@ class SearchHandler extends ActionHandler(zoomTo(_.searchState)) { if (scroll) ScrollToDocument(documentId) else NoChange ) ) - } else + else action(UpdateFocusedPanel(SearchColumn.Document)) ) @@ -219,6 +217,9 @@ class SearchHandler extends ActionHandler(zoomTo(_.searchState)) { case UpdateAllowPreview(preview) => updated(value.copy(allowPreview = preview)) + case UpdateAllowShare(share) => + updated(value.copy(allowShare = share)) + case UpdateErrorMessage(message) => updated(value.copy(errorMessage = message)) diff --git a/src/main/scala/com/harana/search/client/search/SearchKeyHandler.scala b/src/main/scala/com/harana/search/client/search/SearchKeyHandler.scala index d72850a..5e064d7 100644 --- a/src/main/scala/com/harana/search/client/search/SearchKeyHandler.scala +++ b/src/main/scala/com/harana/search/client/search/SearchKeyHandler.scala @@ -38,7 +38,6 @@ class SearchKeyHandler extends ActionHandler(zoomTo(_.searchState)) { case Keys.Space => if (value.searchTerm.isEmpty || value.searchTerm.get.isBlank) { - event.preventDefault() event.stopPropagation() } action(NoChange) @@ -48,10 +47,6 @@ class SearchKeyHandler extends ActionHandler(zoomTo(_.searchState)) { } case SearchColumn.Integration => - - event.preventDefault() - event.stopPropagation() - key match { case Keys.Down => if (value.selectedIntegration.get != value.searchResults.last._1) @@ -99,8 +94,6 @@ class SearchKeyHandler extends ActionHandler(zoomTo(_.searchState)) { } case SearchColumn.Document => - - event.preventDefault() event.stopPropagation() val documents = value.searchResults.find(_._1 == value.selectedIntegration.get).get._2 @@ -162,8 +155,6 @@ class SearchKeyHandler extends ActionHandler(zoomTo(_.searchState)) { } case SearchColumn.Cards => - - event.preventDefault() event.stopPropagation() val cardState = Circuit.state(_.cardState, false) @@ -204,7 +195,11 @@ class SearchKeyHandler extends ActionHandler(zoomTo(_.searchState)) { } } - case KeyUp(key, _) => + case KeyUp(key, event) => + effectOnly(action(NoChange)) + + event.stopPropagation() + effectOnly { if (key == Keys.Escape) if (value.searchTerm.isEmpty) { @@ -220,8 +215,11 @@ class SearchKeyHandler extends ActionHandler(zoomTo(_.searchState)) { ) else action(Search(None)) - else + else { + event.stopPropagation() + event.preventDefault() action(NoChange) + } } } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/search/SearchStore.scala b/src/main/scala/com/harana/search/client/search/SearchStore.scala index 2a0ac9a..62f0076 100644 --- a/src/main/scala/com/harana/search/client/search/SearchStore.scala +++ b/src/main/scala/com/harana/search/client/search/SearchStore.scala @@ -12,6 +12,7 @@ object SearchStore { type SearchTerm = String case class State(allowPreview: Boolean, + allowShare: Boolean, integrations: List[Integration], focusedPanel: SearchColumn, errorMessage: Option[String], @@ -25,7 +26,7 @@ object SearchStore { selectedDocumentId: Option[DocumentId], selectedDocument: Option[Document]) - val initialState = State(false, Integrations.list, SearchColumn.Search, None, Map(), None, List(), None, 1, 1, None, None, None) + val initialState = State(false, false, Integrations.list, SearchColumn.Search, None, Map(), None, List(), None, 1, 1, None, None, None) case class KeyDown(key: Int, event: KeyboardEvent) extends DiodeAction case class KeyUp(key: Int, event: KeyboardEvent) extends DiodeAction @@ -67,6 +68,7 @@ object SearchStore { case object ScrollToLastIntegration extends DiodeAction case class UpdateAllowPreview(preview: Boolean) extends DiodeAction + case class UpdateAllowShare(share: Boolean) extends DiodeAction case class UpdateErrorMessage(message: Option[String]) extends DiodeAction case class UpdateIntegrations(integrations: List[Integration]) extends DiodeAction case class UpdateFocusedPanel(panel: SearchColumn) extends DiodeAction diff --git a/src/main/scala/com/harana/search/client/search/ui/SearchPanel.scala b/src/main/scala/com/harana/search/client/search/ui/SearchPanel.scala index 39154ed..50ee914 100644 --- a/src/main/scala/com/harana/search/client/search/ui/SearchPanel.scala +++ b/src/main/scala/com/harana/search/client/search/ui/SearchPanel.scala @@ -4,25 +4,20 @@ import com.harana.search.client.Circuit import com.harana.search.client.cards.CardPanel import com.harana.search.client.search.SearchStore._ import com.harana.search.client.search.ui.rows.{DocumentRow, IntegrationRow} -import com.harana.search.client.{Tauri => SearchTauri} import com.harana.web.components.when import com.harana.web.external.tailwind.OutlineIcons._ import com.harana.web.external.tailwind.SolidIcons._ -import com.harana.web.external.tailwind.dialog._ -import com.harana.web.external.tailwind.popover._ -import com.harana.web.external.tailwind.transition.{Transition, TransitionChild} +import com.harana.web.external.tailwind.popover.PopoverButton import com.harana.web.external.tauri.Tauri import com.harana.web.external.virtuoso.{Style, Virtuoso} -import diode.ActionBatch import org.scalajs.dom._ import slinky.core.annotations.react import slinky.core.facade.Hooks.useEffect -import slinky.core.facade.{Fragment, React} +import slinky.core.facade.React import slinky.core.{CustomAttribute, FunctionalComponent} import slinky.web.html._ import scala.scalajs.js -import scala.scalajs.js.Date import scala.scalajs.js.JSConverters._ @react object SearchPanel { @@ -46,16 +41,16 @@ import scala.scalajs.js.JSConverters._ Seq.empty ) - //Tauri.invoke("update_window_size", Map("width" -> 950.0, "height" -> (if (state.searchResults.nonEmpty) 466.0 else 58.0)).toJSDictionary) + Tauri.invoke("update_window_size", Map("width" -> 950.0, "height" -> (if (state.searchResults.nonEmpty) 680.0 else 58.0)).toJSDictionary) val dragRegionAttr = new CustomAttribute[Boolean]("data-tauri-drag-region") div( div(className := "relative", dragRegionAttr := true)( - MagnifyingGlassIcon("pointer-events-none absolute left-4 mt-half top-4 h-5 w-5 text-gray-400"), + MagnifyingGlassOutlineIcon("pointer-events-none absolute left-4 mt-half top-4 h-5 w-5 text-gray-400"), input( - className := "h-14 w-350 search-input border-0 bg-transparent ml-10 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-md", + className := "h-14 w-350 search-input border-0 bg-transparent ml-10 text-gray-900 placeholder:text-gray-600 focus:ring-0 sm:text-md", placeholder := "Search...", autoComplete := "false", ref := inputRef, diff --git a/src/main/scala/com/harana/search/client/share/ShareKeyHandler.scala b/src/main/scala/com/harana/search/client/share/ShareKeyHandler.scala index 409171b..8595ecb 100644 --- a/src/main/scala/com/harana/search/client/share/ShareKeyHandler.scala +++ b/src/main/scala/com/harana/search/client/share/ShareKeyHandler.scala @@ -15,6 +15,7 @@ class ShareKeyHandler extends ActionHandler(zoomTo(_.shareState)) { override def handle = { case KeyDown(key, event) => + println("KEY DOWN IN SHARE") effectOnly { if (key == Keys.Enter) action(UpdateActivePanel(Panel.Search)) @@ -24,7 +25,6 @@ class ShareKeyHandler extends ActionHandler(zoomTo(_.shareState)) { case KeyUp(key, event) => println("KEY UP IN SHARE") - effectOnly { if (key == Keys.Escape) action(UpdateActivePanel(Panel.Search)) diff --git a/src/main/scala/com/harana/search/client/share/ui/SharePanel.scala b/src/main/scala/com/harana/search/client/share/ui/SharePanel.scala index 4d5eb42..9cc72cf 100644 --- a/src/main/scala/com/harana/search/client/share/ui/SharePanel.scala +++ b/src/main/scala/com/harana/search/client/share/ui/SharePanel.scala @@ -15,10 +15,14 @@ import scala.scalajs.js.JSConverters._ val component = FunctionalComponent[Unit] { _ => - Tauri.invoke("update_window_size", Map("width" -> 960.0, "height" -> 465.0).toJSDictionary) + Tauri.invoke("update_window_size", Map("width" -> 960.0, "height" -> 680.0).toJSDictionary) val buttonClass = "relative inline-flex bg-white py-2 text-xs font-semibold ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10" + val recentUrls = List( + ("https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=200&h=200&q=90", "Emma Clarke", "Frontend Developer"), + ) + val personUrls = List( ("https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=200&h=200&q=90", "Emma Clarke", "Frontend Developer"), ("https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=200&h=200&q=90", "Isabella Rossi", "VP, Sales"), @@ -32,7 +36,7 @@ import scala.scalajs.js.JSConverters._ div(className := "sm:col-span-1 pr-6")( h2(className := "text-sm text-gray-600 mb-4")("Recent"), ul(role := "grid gap-x-8 gap-y-8")( - personUrls.map(p => person(p._1, p._2, p._3, personUrls.indexOf(p) == 0)) + recentUrls.map(p => person(p._1, p._2, p._3, personUrls.indexOf(p) == 0)) ) ), div(className := "sm:col-span-1 pr-6")( @@ -58,7 +62,7 @@ import scala.scalajs.js.JSConverters._ } def person(url: String, name: String, role: String, selected: Boolean) = - li(className := s"mb-2 p-2 ${if (selected) "ring-2 ring-inset ring-emerald-600 rounded-md"}")( + li(className := s"mb-2 p-2 ${if (selected) "ring-1 ring-inset ring-emerald-600 rounded-md"}")( div(className := "flex items-center gap-x-6 gap-y-6")( img(className := "h-10 w-10 rounded-full", src := url), div( diff --git a/src/main/scala/com/harana/search/client/system/SystemHandler.scala b/src/main/scala/com/harana/search/client/system/SystemHandler.scala index 5ff7500..733e9d5 100644 --- a/src/main/scala/com/harana/search/client/system/SystemHandler.scala +++ b/src/main/scala/com/harana/search/client/system/SystemHandler.scala @@ -22,7 +22,6 @@ class SystemHandler extends ActionHandler(zoomTo(_.systemState)) { appIconsUrl = convertFileSrc(appIconsPath) isDebug <- Tauri.invoke[String]("is_debug") - isDemo <- Tauri.invoke[String]("is_demo") previewsPath <- Tauri.invoke[String]("get_previews_path") previewsUrl = convertFileSrc(previewsPath) @@ -50,6 +49,9 @@ class SystemHandler extends ActionHandler(zoomTo(_.systemState)) { case UpdateIsDebug(debug) => updated(value.copy(isDebug = debug)) + case UpdateIsDemo(demo) => + updated(value.copy(isDemo = demo)) + case UpdatePreviewsUrl(url) => updated(value.copy(previewsUrl = url)) diff --git a/src/main/scala/com/harana/search/client/welcome/WelcomeHandler.scala b/src/main/scala/com/harana/search/client/welcome/WelcomeHandler.scala index 378843c..11d89ec 100644 --- a/src/main/scala/com/harana/search/client/welcome/WelcomeHandler.scala +++ b/src/main/scala/com/harana/search/client/welcome/WelcomeHandler.scala @@ -57,9 +57,22 @@ class WelcomeHandler extends ActionHandler(zoomTo(_.welcomeState)) { case CompleteOnboarding => value.statusTimer.get.cancel() effectOnly( - Effect(Tauri.invoke[Unit]("complete_onboarding", Map()).map(_ => NoChange)) + Effect(Tauri.invoke[Unit]("complete_onboarding", Map( + "allowTelemetry" -> value.allowTelemetry, + "anonymousMode" -> value.anonymousMode, + "overrideSpotlight" -> value.overrideSpotlight, + )).map(_ => NoChange)) ) + case UpdateAllowTelemetry(allow) => + updated(value.copy(allowTelemetry = allow)) + + case UpdateAnonymousMode(anonymous) => + updated(value.copy(anonymousMode = anonymous)) + + case UpdateOverrideSpotlight(os) => + updated(value.copy(overrideSpotlight = os)) + case UpdateSearchFolderStatus(status) => updated(value.copy(searchFolderStatus = status)) diff --git a/src/main/scala/com/harana/search/client/welcome/WelcomeStore.scala b/src/main/scala/com/harana/search/client/welcome/WelcomeStore.scala index 8bcc0d3..1740031 100644 --- a/src/main/scala/com/harana/search/client/welcome/WelcomeStore.scala +++ b/src/main/scala/com/harana/search/client/welcome/WelcomeStore.scala @@ -7,19 +7,25 @@ import java.util.Timer object WelcomeStore { - case class State(searchFolders: List[SearchFolder], + case class State(allowTelemetry: Boolean, + anonymousMode: Boolean, + overrideSpotlight: Boolean, + searchFolders: List[SearchFolder], searchFolderStatus: Map[String, Boolean], selectedStep: Int, statusTimer: Option[Timer], windowShown: Boolean) - val initialState = State(List(), Map(), 1, None, false) + val initialState = State(false, false, false, List(), Map(), 1, None, false) case object ShowWindow extends DiodeAction case object HideWindow extends DiodeAction case object RefreshStatus extends DiodeAction case object CompleteOnboarding extends DiodeAction + case class UpdateAllowTelemetry(allowTelemetry: Boolean) extends DiodeAction + case class UpdateAnonymousMode(anonymousMode: Boolean) extends DiodeAction + case class UpdateOverrideSpotlight(overrideSpotlight: Boolean) extends DiodeAction case class UpdateSearchFolder(folder: SearchFolder) extends DiodeAction case class UpdateSearchFolders(folders: List[SearchFolder]) extends DiodeAction case class UpdateSearchFolderStatus(status: Map[String, Boolean]) extends DiodeAction diff --git a/src/main/scala/com/harana/search/client/welcome/ui/Step1Panel.scala b/src/main/scala/com/harana/search/client/welcome/ui/Step1Panel.scala index 4504368..582ae04 100644 --- a/src/main/scala/com/harana/search/client/welcome/ui/Step1Panel.scala +++ b/src/main/scala/com/harana/search/client/welcome/ui/Step1Panel.scala @@ -21,54 +21,25 @@ import scala.scalajs.js val state = Circuit.state(_.welcomeState, true) span( - h2(className := "text-base font-semibold leading-7 text-green-600 logo")("harana"), - p(className := "mt-2 text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl headlinee")("Welcome"), - p(className := "mt-6 text-lg leading-8 text-gray-600")( - "Select the folders you want to search." - ), - div(className := "grid grid-cols-3 gap-4 pt-14")( + p(className := titleCls)("Select the folders to search."), + div(className := "grid grid-cols-2 gap-4 pt-14 pb-4 pl-4")( state.searchFolders.map(sf => div(className := "flex items-center")( div( - state.searchFolderStatus.get(sf.nameOrPath) match { - case None => - Switch( - name = s"folder_${sf.nameOrPath}", - label = None, - className = "px-4 py-2", -// enabledColor = "bg-emerald-600", - onChange = (_: js.Any) => Circuit.dispatch(UpdateSearchFolder(sf.copy(enabled = !sf.enabled))), - enabled = sf.enabled - ) - - case Some(status) => - if (status) - div(className := "pl-4 pr-8")(CheckCircleOutlineIcon("h-7 w-7")) - else - div(className := "pl-4 pr-10")(div(className := "loader")) - }, + Switch( + name = s"folder_${sf.nameOrPath}", + label = None, + className = "px-2 py-2", + onChange = (_: js.Any) => Circuit.dispatch(UpdateSearchFolder(sf.copy(enabled = !sf.enabled))), + enabled = sf.enabled + ) ), span(className := "pl-3 ml-3 text-sm font-medium text-gray-900")(sf.title) ) ) ), when(state.searchFolderStatus.nonEmpty, - div(className := "pt-20 center")( - Button( - label = Some("Continue"), - size = ButtonSize.Large, - textColor = "white", - backgroundColor = "bg-emerald-600", - hoverColor = "bg-emerald-500", - rounded = true, - onClick = () => Circuit.dispatch( - ActionBatch( - CompleteOnboarding, - UpdateSelectedStep(2) - ) - ) - ) - ) + continueButton(UpdateSelectedStep(2)) ) ) } diff --git a/src/main/scala/com/harana/search/client/welcome/ui/Step2Panel.scala b/src/main/scala/com/harana/search/client/welcome/ui/Step2Panel.scala index afde0d2..12f3d23 100644 --- a/src/main/scala/com/harana/search/client/welcome/ui/Step2Panel.scala +++ b/src/main/scala/com/harana/search/client/welcome/ui/Step2Panel.scala @@ -1,8 +1,8 @@ package com.harana.search.client.welcome.ui import com.harana.search.client.Circuit -import com.harana.search.client.welcome.WelcomeStore.{HideWindow, UpdateSearchFolder} -import com.harana.web.external.tailwind.{Button, ButtonSize, Switch} +import com.harana.search.client.welcome.WelcomeStore._ +import com.harana.web.external.tailwind.Switch import slinky.core.FunctionalComponent import slinky.core.annotations.react import slinky.web.html._ @@ -17,18 +17,25 @@ import scala.scalajs.js val state = Circuit.state(_.welcomeState, true) - val cls = "inline-flex justify-center items-center py-2 bg-white border border-gray-200 font-mono text-gray-800 rounded-md shadow-[0px_2px_0px_0px_rgba(0,0,0,0.08)] dark:bg-slate-900 dark:border-gray-700 dark:text-gray-200 dark:shadow-[0px_2px_0px_0px_rgba(255,255,255,0.1)]" + val items = List( + ("Replace Spotlight Shortcut", "Make Harana the primary search tool on your Mac", "by adopting the Command-Space shortcut.", state.overrideSpotlight, (_: js.Any) => Circuit.dispatch(UpdateOverrideSpotlight(!state.overrideSpotlight))), + ("Share Analytics with Harana", "Help Harana improve its products by automatically", "sending anonymous diagnostics and usage data.", state.allowTelemetry, (_: js.Any) => Circuit.dispatch(UpdateAllowTelemetry(!state.allowTelemetry))), + ("Anonymous Mode", "Disables search history, Airdrop style sharing and", "other related features for the ultimate in privacy.", state.anonymousMode, (_: js.Any) => Circuit.dispatch(UpdateAnonymousMode(!state.anonymousMode))), + ) div( - h2(className := "text-base font-semibold leading-7 text-green-600 logo")("harana"), - p(className := "mt-2 text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl")("Ready"), - p(className := "mt-6 text-lg leading-8 text-gray-600")( - "Press the following to continue." - ), - span(className := "inline-flex w-full justify-center rounded-md pt-20 pb-15")( - kbd(className := s"$cls text-lg px-6 py-4")("⌘"), - kbd(className := s"$cls text-m px-8 py-4")("Space"), - ) + p(className := titleCls)("Customise your search experience."), + items.map { item => + div(className := "flex items-center justify-between pb-6 ml-6 mt-2")( + Switch("always_center_window", None, item._4, item._5, ""), + span(className := "flex flex-grow flex-col pl-6 pt-4 ml-4")( + span(className := "pb-1 text-sm font-small leading-6 text-gray-900")(item._1), + span(className := "text-xs font-medium text-gray-500")(item._2), + span(className := "text-xs font-medium text-gray-500")(item._3) + ) + ) + }, + continueButton(UpdateSelectedStep(3)) ) } } \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/welcome/ui/Step3Panel.scala b/src/main/scala/com/harana/search/client/welcome/ui/Step3Panel.scala new file mode 100644 index 0000000..8932d57 --- /dev/null +++ b/src/main/scala/com/harana/search/client/welcome/ui/Step3Panel.scala @@ -0,0 +1,59 @@ +package com.harana.search.client.welcome.ui + +import com.harana.search.client.welcome.WelcomeStore.{CompleteOnboarding, UpdateSelectedStep} +import com.harana.web.external.tailwind.OutlineIcons._ +import diode.ActionBatch +import slinky.core.FunctionalComponent +import slinky.core.annotations.react +import slinky.core.facade.ReactElement +import slinky.web.html._ + +@react object Step3Panel { + + type Props = Unit + + val iconCls = "w-50 text-gray-600 mt-1" + + def todayItems = List( + ("File Searching", DocumentMagnifyingGlassOutlineIcon(iconCls), "Locates files using names or content, enabling quick and efficient retrieval."), + ("Metadata Extraction", FilmOutlineIcon(iconCls), "Extracts essential information from files, such as creator and date, for organization."), + ("Thumbnail Generation", PhotoOutlineIcon(iconCls), "Generates small preview images from files for easy visual identification.") + ) + + def laterItems = List( + ("Speech Recognition", SpeakerWaveOutlineIcon(iconCls), "Transforms spoken words within audio files into editable, searchable text."), + ("Object Recognition", ViewfinderCircleOutlineIcon(iconCls), "Identifies and labels objects in images or videos, simplifying searches."), + ("Text Recognition", DocumentTextOutlineIcon(iconCls), "Converts text found in images into digital text for easy access."), + ) + + val component = FunctionalComponent[Unit] { _ => + div( + p(className := titleCls)("What to expect over the coming days."), + div(className := "grid grid-cols-2 gap-6 pr-8 mb-6")( + div( + p(className := "mt-1 mb-2 text-sm font-bold leading-8 text-gray-800")("Today"), + todayItems.map { item => iconRow(item._1, item._2, item._3) }, + ), + div( + p(className := "mt-1 mb-2 text-sm font-bold leading-8 text-gray-800")("Later"), + laterItems.map { item => iconRow(item._1, item._2, item._3) } + ) + ), + continueButton( + ActionBatch( + CompleteOnboarding, + UpdateSelectedStep(4) + ) + ) + ) + } + + def iconRow(title: String, icon: ReactElement, description: String) = + span(className := "flex items-start gap-x-6 mb-6")( + icon, + div( + div(className := "text-sm font-small leading-6 text-gray-900")(title), + div(className := "text-xs mt-1 text-gray-500")(description), + ) + ) +} \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/welcome/ui/Step4Panel.scala b/src/main/scala/com/harana/search/client/welcome/ui/Step4Panel.scala new file mode 100644 index 0000000..4159998 --- /dev/null +++ b/src/main/scala/com/harana/search/client/welcome/ui/Step4Panel.scala @@ -0,0 +1,35 @@ +package com.harana.search.client.welcome.ui + +import com.harana.search.client.Circuit +import com.harana.search.client.icons.keyboard._ +import com.harana.web.components.literal +import slinky.core.FunctionalComponent +import slinky.core.annotations.react +import slinky.web.html._ + +@react object Step4Panel { + + type Props = Unit + + + val component = FunctionalComponent[Unit] { _ => + val state = Circuit.state(_.welcomeState, true) + + div( + p(className := titleCls)("Press the following to open Harana."), + div(style := literal("paddingTop" -> "120px"))( + if (state.overrideSpotlight) + span(className := "inline-flex pl-14")( + CommandIcon("pr-2", "43px"), + SpaceIcon("", "43px") + ) + else + span(className := "inline-flex")( + CommandIcon("mr-2 drop-shadow-md", "43px"), + ShiftIcon("mr-2 drop-shadow-md", "43px"), + SpaceIcon("drop-shadow-md", "43px") + ) + ) + ) + } +} \ No newline at end of file diff --git a/src/main/scala/com/harana/search/client/welcome/ui/WelcomePanel.scala b/src/main/scala/com/harana/search/client/welcome/ui/WelcomePanel.scala index 6898a1d..ed4f392 100644 --- a/src/main/scala/com/harana/search/client/welcome/ui/WelcomePanel.scala +++ b/src/main/scala/com/harana/search/client/welcome/ui/WelcomePanel.scala @@ -2,7 +2,9 @@ package com.harana.search.client.welcome.ui import com.harana.search.client.Circuit import com.harana.search.client.welcome.WelcomeStore.ShowWindow +import com.harana.web.components.literal import com.harana.web.external.tailwind.OutlineIcons.XMarkOutlineIcon +import com.harana.web.external.tauri.Tauri.convertFileSrc import slinky.core.FunctionalComponent import slinky.core.annotations.react import slinky.core.facade.Hooks.useEffect @@ -24,23 +26,20 @@ import scala.scalajs.js.Dynamic.{literal => css} }) div(className := "bg-white")( - div(className := "relative isolate px-8 pt-12")( - div(className := "absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80")( - div(className := "relative left-[calc(50%-11rem)] aspect-[1155/678] w-[36.125rem] -translate-x-1/2 rotate-[30deg] bg-gradient-to-tr from-[#ff80b5] to-[#9089fc] opacity-30 sm:left-[calc(50%-30rem)] sm:w-[72.1875rem]", - style := css("clipPath" -> "polygon(74.1% 44.1%, 100% 61.6%, 97.5% 26.9%, 85.5% 0.1%, 80.7% 2%, 72.5% 32.5%, 60.2% 62.4%, 52.4% 68.1%, 47.5% 58.3%, 45.2% 34.5%, 27.5% 76.7%, 0.1% 64.9%, 17.9% 100%, 27.6% 76.8%, 76.1% 97.7%, 74.1% 44.1%)") - ) - ) - ), - div(className := "mx-auto max-w-7xl px-6 lg:px-8")( - div(className := "mx-auto grid max-w-2xl grid-cols-1 gap-x-8 gap-y-16 sm:gap-y-20 lg:mx-0 lg:max-w-none lg:grid-cols-2")( - div(className := "lg:pr-8 lg:pt-4")( - div(className := "lg:max-w-lg")( - state.selectedStep match { - case 1 => Step1Panel() - case 2 => Step2Panel() - } - ) + div(className := "grid grid-cols-3")( + div(className := "pl-10 col-span-2 pr-4")( + div( + img(className := "pt-8", style := literal("maxWidth" -> "84px"), src := convertFileSrc(s"assets/logo.png")), + state.selectedStep match { + case 1 => Step1Panel() + case 2 => Step2Panel() + case 3 => Step3Panel() + case 4 => Step4Panel() + } ) + ), + div(className := "fixed right-0", style := literal("width" -> "280px"))( + img(src := convertFileSrc(s"assets/onboarding_hero.jpg")), ) ) ) diff --git a/src/main/scala/com/harana/search/client/welcome/ui/package.scala b/src/main/scala/com/harana/search/client/welcome/ui/package.scala new file mode 100644 index 0000000..ffddb43 --- /dev/null +++ b/src/main/scala/com/harana/search/client/welcome/ui/package.scala @@ -0,0 +1,25 @@ +package com.harana.search.client.welcome + +import com.harana.search.client.Circuit +import com.harana.web.components +import com.harana.web.external.tailwind.{Button, ButtonSize} +import diode.Action +import slinky.web.html.{className, div, style} + +package object ui { + + val titleCls = "mt-4 mb-6 text-lg leading-7 text-gray-500" + + def continueButton(action: Action) = + div(className := "fixed bottom-0 pb-8", style := components.literal("marginLeft" -> "150px"))( + Button( + label = Some("Continue"), + size = ButtonSize.Large, + textColor = "text-white", + backgroundColor = "bg-teal-600", + hoverColor = "bg-teal-500", + className = Some("rounded-md"), + onClick = () => Circuit.dispatch(action) + ) + ) +} \ No newline at end of file