diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index f3a6796..0000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -yarn pretty-quick --staged diff --git a/package.json b/package.json index 7c1e5d9..f6b2825 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,10 @@ "version": "1.2.1", "license": "GPL-3.0", "scripts": { - "dev": "tauri dev", - "dev:diff": "tauri dev -f verge-dev", - "build": "tauri build", - "tauri": "tauri", + "dev": "cargo tauri dev", + "dev:diff": "cargo tauri dev -f verge-dev", + "build": "cargo tauri build", + "tauri": "cargo tauri", "web:dev": "vite", "web:build": "tsc && vite build", "web:serve": "vite preview", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 09dae55..8d37707 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -370,6 +370,12 @@ version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +[[package]] +name = "bytecount" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" + [[package]] name = "bytemuck" version = "1.12.3" @@ -501,12 +507,15 @@ dependencies = [ "delay_timer", "dirs 4.0.0", "dunce", + "futures 0.3.25", + "interprocess", "log 0.4.17", "log4rs", "nanoid", "once_cell", "open", "parking_lot", + "patch", "port_scanner", "reqwest", "rquickjs", @@ -519,6 +528,7 @@ dependencies = [ "tauri", "tauri-build", "tauri-runtime-wry", + "tauri-utils", "tokio", "warp", "which 4.3.0", @@ -902,7 +912,7 @@ dependencies = [ "cron_clock", "dashmap", "event-listener", - "futures", + "futures 0.3.25", "log 0.4.17", "lru", "once_cell", @@ -1169,6 +1179,12 @@ dependencies = [ "new_debug_unreachable", ] +[[package]] +name = "futures" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" + [[package]] name = "futures" version = "0.3.25" @@ -1261,6 +1277,7 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ + "futures 0.1.31", "futures-channel", "futures-core", "futures-io", @@ -1885,6 +1902,32 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "interprocess" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f2533f3be42fffe3b5e63b71aeca416c1c3bc33e4e27be018521e76b1f38fb" +dependencies = [ + "blocking", + "cfg-if 1.0.0", + "futures-core", + "futures-io", + "intmap", + "libc", + "once_cell", + "rustc_version 0.4.0", + "spinning", + "thiserror", + "to_method", + "winapi", +] + +[[package]] +name = "intmap" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae52f28f45ac2bc96edb7714de995cffc174a395fb0abf5bff453587c980d7b9" + [[package]] name = "ipnet" version = "2.6.0" @@ -2401,6 +2444,17 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nom_locate" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e299bf5ea7b212e811e71174c5d1a5d065c4c0ad0c8691ecb1f97e3e66025e" +dependencies = [ + "bytecount", + "memchr", + "nom 7.1.1", +] + [[package]] name = "ntapi" version = "0.4.0" @@ -2692,6 +2746,17 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" +[[package]] +name = "patch" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c07fdcdd8b05bdcf2a25bc195b6c34cbd52762ada9dba88bf81e7686d14e7a" +dependencies = [ + "chrono", + "nom 7.1.1", + "nom_locate", +] + [[package]] name = "pathdiff" version = "0.2.1" @@ -3787,6 +3852,15 @@ dependencies = [ "system-deps 5.0.0", ] +[[package]] +name = "spinning" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d4f0e86297cad2658d92a707320d87bf4e6ae1050287f51d19b67ef3f153a7b" +dependencies = [ + "lock_api", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -4331,6 +4405,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +[[package]] +name = "to_method" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c4ceeeca15c8384bbc3e011dbd8fccb7f068a440b752b7d9b32ceb0ca0e2e8" + [[package]] name = "tokio" version = "1.23.0" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 5b8150b..6c4792e 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -41,6 +41,10 @@ tauri = { version = "1.1.1", features = ["global-shortcut-all", "process-all", " tauri-runtime-wry = { version = "0.12" } window-vibrancy = { version = "0.3.0" } window-shadows = { version = "0.2.0" } +patch = "0.7.0" +interprocess = "1.2.1" +tauri-utils = "1.2.1" +futures = { version = "0.3", features = ["compat"] } [target.'cfg(windows)'.dependencies] runas = "0.2.1" diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index a3ff866..ca6147d 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -9,11 +9,38 @@ mod core; mod enhance; mod feat; mod utils; +mod deep_link; -use crate::utils::{init, resolve, server}; +use crate::utils::{init, resolve, server, help}; use tauri::{api, SystemTray}; +use std::fs::File; +use std::io::Write; + +#[tokio::main] +async fn main() -> std::io::Result<()> { + // Deep linking + + deep_link::prepare("top.gydi.clashverg"); + + let register_res = deep_link::register("clashy",| deep_link | async move { + // Convert deep link to something that import_profile can use + let profile_url_and_name = help::convert_deeplink_to_url_for_import_profile(&deep_link); + // If deep link is invalid we just ignore + if profile_url_and_name.is_err(){ + return + } + + // Import profile + if let Ok(_) = cmds::import_profile(profile_url_and_name.unwrap(), None).await{ + + } + }).await; + + // If we couldn't register, we log it + if register_res.is_err(){ + println!("We can't register deep link scheme for program | {}",register_res.err().unwrap()) + } -fn main() -> std::io::Result<()> { // 单例检测 if server::check_singleton().is_err() { println!("app exists"); diff --git a/src-tauri/src/utils/help.rs b/src-tauri/src/utils/help.rs index 2d4a32f..0d90e77 100644 --- a/src-tauri/src/utils/help.rs +++ b/src-tauri/src/utils/help.rs @@ -105,6 +105,50 @@ pub fn open_file(path: PathBuf) -> Result<()> { Ok(()) } +#[derive(Debug)] +pub enum ExtractDeeplinkError{ + InvalidInput +} +pub fn extract_url_and_profile_name_from_deep_link(deep_link:&String) -> Result<(String,String),ExtractDeeplinkError>{ + // Sample: clash://install-config?url=https://mysite.com/all.yml&name=profilename + let (url,profile) = { + let pruned = deep_link.split("url=").collect::>(); + if pruned.len() < 2 { + return Err(ExtractDeeplinkError::InvalidInput) + } + let url_and_profile_name = pruned[1].split("&").collect::>(); + if url_and_profile_name.len() < 2{ + return Err(ExtractDeeplinkError::InvalidInput) + } + let url = url_and_profile_name[0].to_string(); + let profile_name = { + let splitted: Vec<_> = url_and_profile_name[1].split("=").collect(); + if splitted.len() < 2 { + return Err(ExtractDeeplinkError::InvalidInput) + } + splitted[1].to_string() + }; + + (url,profile_name) + }; + + return Ok((url,profile)); +} + +pub fn convert_deeplink_to_url_for_import_profile(deep_link:&String) -> Result{ + // Sample: clash://install-config?url=https://mysite.com/all.yml&name=profilename + let import_profile_url_raw = { + let url_part:Vec<_> = deep_link.split("url=").collect(); + if url_part.len() < 2{ + return Err(ExtractDeeplinkError::InvalidInput) + } + url_part + }; + + // Convert url to something that import_profile functin can use + let import_profile_url = import_profile_url_raw[1].replacen('&', "?", 1); + Ok(import_profile_url) +} #[macro_export] macro_rules! error { ($result: expr) => { @@ -169,3 +213,10 @@ fn test_parse_value() { assert_eq!(parse_str::(test_1, "expire1="), None); assert_eq!(parse_str::(test_2, "attachment="), None); } +#[test] +fn test_extract_url_and_profile_name_from_deep_link(){ + let s = "clash://install-config?url=https://mysite.com/all.yml&name=profilename"; + let (url,prof_name) = extract_url_and_profile_name_from_deep_link(&s.to_string()).unwrap(); + assert_eq!(url,"https://mysite.com/all.yml"); + assert_eq!(prof_name,"profilename"); +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index a285c97..0d2a7ab 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,7 @@ "useDefineForClassFields": true, "lib": ["DOM", "DOM.Iterable", "ESNext"], "allowJs": false, - "skipLibCheck": false, + "skipLibCheck": true, "esModuleInterop": false, "allowSyntheticDefaultImports": true, "strict": true, @@ -16,10 +16,11 @@ "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", + "noImplicitAny": false, "paths": { "@/*": ["src/*"], "@root/*": ["./*"] - } + }, }, "include": ["./src"] }