diff --git a/Cargo.lock b/Cargo.lock index 59d57e8..b15811b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -954,6 +954,17 @@ dependencies = [ "objc2 0.6.3", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "dlib" version = "0.5.2" @@ -1246,6 +1257,15 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + [[package]] name = "futures" version = "0.3.31" @@ -1979,6 +1999,108 @@ dependencies = [ "png 0.16.8", ] +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + [[package]] name = "image" version = "0.25.9" @@ -2267,6 +2389,12 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + [[package]] name = "litrs" version = "1.0.0" @@ -3232,6 +3360,15 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -3594,6 +3731,7 @@ dependencies = [ "tokio", "toml 0.9.8", "tray-icon", + "url", ] [[package]] @@ -3972,6 +4110,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "sys-locale" version = "0.3.2" @@ -4114,6 +4263,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.10.0" @@ -4362,6 +4521,23 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "uuid" version = "1.19.0" @@ -5331,6 +5507,12 @@ version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + [[package]] name = "x11" version = "2.21.0" @@ -5416,6 +5598,29 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "synstructure", +] + [[package]] name = "zbus" version = "5.12.0" @@ -5503,6 +5708,60 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "zune-core" version = "0.4.12" diff --git a/Cargo.toml b/Cargo.toml index 7ced980..0142046 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,3 +25,4 @@ serde = { version = "1.0.228", features = ["derive"] } tokio = { version = "1.48.0", features = ["full"] } toml = "0.9.8" tray-icon = "0.21.3" +url = { version = "2.5.8", default-features = false } diff --git a/src/app/menubar.rs b/src/app/menubar.rs index a543e88..6f115ba 100644 --- a/src/app/menubar.rs +++ b/src/app/menubar.rs @@ -52,9 +52,7 @@ fn get_image() -> DynamicImage { "/Applications/Rustcast.app/Contents/Resources/icon.png" }; - let image = ImageReader::open(image_path).unwrap().decode().unwrap(); - - image + ImageReader::open(image_path).unwrap().decode().unwrap() } fn init_event_handler(sender: ExtSender, hotkey_id: u32) { diff --git a/src/app/tile/update.rs b/src/app/tile/update.rs index dccc354..07199c4 100644 --- a/src/app/tile/update.rs +++ b/src/app/tile/update.rs @@ -25,6 +25,7 @@ use crate::config::Config; use crate::haptics::HapticPattern; use crate::haptics::perform_haptic; use crate::utils::get_installed_apps; +use crate::utils::is_valid_url; use crate::{ app::{Message, Page, tile::Tile}, macos::focus_this_app, @@ -98,12 +99,12 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task { height: 55. + DEFAULT_WINDOW_HEIGHT, }, ); - } else if tile.query_lc.ends_with("?") { + } else if tile.query_lc.split(" ").count() > 1 || tile.query_lc.ends_with("?") { tile.results = vec![App { open_command: AppCommand::Function(Function::GoogleSearch(tile.query.clone())), icons: None, - desc: "Search".to_string(), - name: format!("Search for: {}", tile.query), + desc: "Web Search".to_string(), + name: format!("Google for: {}", tile.query), name_lc: String::new(), }]; return window::resize( @@ -128,6 +129,14 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task { name: res.eval().to_string(), name_lc: "".to_string(), }); + } else if tile.results.is_empty() && is_valid_url(&tile.query) { + tile.results.push(App { + open_command: AppCommand::Function(Function::OpenWebsite(tile.query.clone())), + desc: "Web Browsing".to_string(), + icons: None, + name: "Open Website: ".to_string() + &tile.query, + name_lc: "".to_string(), + }); } let new_length = tile.results.len(); diff --git a/src/commands.rs b/src/commands.rs index 8fe8bea..536969c 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -13,6 +13,7 @@ use crate::{calculator::Expression, clipboard::ClipBoardContentType, config::Con pub enum Function { OpenApp(String), RunShellCommand(String, String), + OpenWebsite(String), RandomVar(i32), // Easter egg function CopyToClipboard(ClipBoardContentType), GoogleSearch(String), @@ -65,6 +66,23 @@ impl Function { }); } + Function::OpenWebsite(url) => { + let open = if url.starts_with("http") { + url.to_owned() + } else { + format!("https://{}", url) + }; + thread::spawn(move || { + NSWorkspace::new().openURL( + &NSURL::URLWithString_relativeToURL( + &objc2_foundation::NSString::from_str(&open), + None, + ) + .unwrap(), + ); + }); + } + Function::Calculate(expr) => { Clipboard::new() .unwrap() diff --git a/src/utils.rs b/src/utils.rs index b188c96..02f6e6b 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -187,3 +187,16 @@ pub fn open_settings() { )); }); } + +pub fn is_valid_url(s: &str) -> bool { + s.ends_with(".com") + || s.ends_with(".net") + || s.ends_with(".org") + || s.ends_with(".edu") + || s.ends_with(".gov") + || s.ends_with(".io") + || s.ends_with(".co") + || s.ends_with(".me") + || s.ends_with(".app") + || s.ends_with(".dev") +}