diff --git a/src-tauri/src/cmd/mod.rs b/src-tauri/src/cmd/mod.rs index 8a15dd68..c4fd72cf 100644 --- a/src-tauri/src/cmd/mod.rs +++ b/src-tauri/src/cmd/mod.rs @@ -15,6 +15,7 @@ pub mod verge; pub mod runtime; pub mod save_profile; pub mod system; +pub mod proxy; // Re-export all command functions for backwards compatibility pub use profile::*; @@ -27,4 +28,5 @@ pub use clash::*; pub use verge::*; pub use runtime::*; pub use save_profile::*; -pub use system::*; \ No newline at end of file +pub use system::*; +pub use proxy::*; \ No newline at end of file diff --git a/src-tauri/src/cmd/proxy.rs b/src-tauri/src/cmd/proxy.rs new file mode 100644 index 00000000..e2ddf771 --- /dev/null +++ b/src-tauri/src/cmd/proxy.rs @@ -0,0 +1,35 @@ +use super::CmdResult; +use crate::module::mihomo::MihomoManager; +use tauri::async_runtime; + +#[tauri::command] +pub async fn get_proxies() -> CmdResult { + let proxies = async_runtime::spawn_blocking(|| { + let rt = tokio::runtime::Runtime::new().unwrap(); + let manager = MihomoManager::new(); + { + let mut write_guard = manager.write(); + rt.block_on(write_guard.refresh_proxies()); + } + let read_guard = manager.read(); + read_guard.fetch_proxies().clone() + }) + .await.map_err(|e| e.to_string())?; + Ok(proxies) +} + +#[tauri::command] +pub async fn get_providers_proxies() -> CmdResult { + let providers_proxies = async_runtime::spawn_blocking(|| { + let rt = tokio::runtime::Runtime::new().unwrap(); + let manager = MihomoManager::new(); + { + let mut write_guard = manager.write(); + rt.block_on(write_guard.refresh_providers_proxies()); + } + let read_guard = manager.read(); + read_guard.fetch_providers_proxies().clone() + }) + .await.map_err(|e| e.to_string())?; + Ok(providers_proxies) +} \ No newline at end of file diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index f5b7ea68..ccfddebe 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -162,6 +162,8 @@ pub fn run() { cmd::get_runtime_logs, cmd::invoke_uwp_tool, cmd::copy_clash_env, + cmd::get_proxies, + cmd::get_providers_proxies, // verge cmd::get_verge_config, cmd::patch_verge_config, diff --git a/src-tauri/src/module/mihomo.rs b/src-tauri/src/module/mihomo.rs index b16f2d95..c1201d91 100644 --- a/src-tauri/src/module/mihomo.rs +++ b/src-tauri/src/module/mihomo.rs @@ -1,8 +1,7 @@ -use std::sync::Arc; +use crate::model::api::mihomo::MihomoAPICaller; use once_cell::sync::OnceCell; use parking_lot::RwLock; -use crate::model::api::mihomo::MihomoAPICaller; - +use std::sync::Arc; #[allow(unused)] pub struct MihomoManager { @@ -34,20 +33,27 @@ impl MihomoManager { pub async fn refresh_proxies(&mut self) { match MihomoAPICaller::get_proxies().await { - Ok(proxies) => self.proxies = proxies, - Err(e) => log::error!("Failed to get proxies: {}", e), + Ok(proxies) => { + self.proxies = proxies; + } + Err(e) => { + log::error!("Failed to get proxies: {}", e); + } } } pub async fn refresh_providers_proxies(&mut self) { match MihomoAPICaller::get_providers_proxies().await { - Ok(providers_proxies) => self.providers_proxies = providers_proxies, - Err(e) => log::error!("Failed to get providers proxies: {}", e), + Ok(providers_proxies) => { + self.providers_proxies = providers_proxies; + }, + Err(e) => { + log::error!("Failed to get providers proxies: {}", e); + }, } - } + } } - #[cfg(test)] mod tests { use super::*; @@ -55,18 +61,21 @@ mod tests { async fn test_mihomo_manager_singleton() { let manager1 = MihomoManager::new(); let manager2 = MihomoManager::new(); - - assert!(Arc::ptr_eq(&manager1, &manager2), "Should return same instance"); + + assert!( + Arc::ptr_eq(&manager1, &manager2), + "Should return same instance" + ); let manager = manager1.read(); assert!(manager.proxies.is_null()); assert!(manager.providers_proxies.is_null()); } - + #[tokio::test] async fn test_refresh_proxies() { let manager = MihomoManager::new(); - + // Test initial state { let data = manager.read(); @@ -87,7 +96,7 @@ mod tests { #[tokio::test] async fn test_refresh_providers_proxies() { let manager = MihomoManager::new(); - + // Test initial state { let data = manager.read(); @@ -108,7 +117,7 @@ mod tests { #[tokio::test] async fn test_fetch_proxies() { let manager = MihomoManager::new(); - + // Test initial state { let data = manager.read(); @@ -129,7 +138,7 @@ mod tests { #[tokio::test] async fn test_fetch_providers_proxies() { let manager = MihomoManager::new(); - + // Test initial state { let data = manager.read(); @@ -146,4 +155,4 @@ mod tests { // Would need API mocking for more thorough testing } } -} \ No newline at end of file +} diff --git a/src/services/api.ts b/src/services/api.ts index 2eec99d9..20ae5037 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -1,5 +1,7 @@ import axios, { AxiosInstance } from "axios"; import { getClashInfo } from "./cmds"; +import { invoke } from "@tauri-apps/api/core"; +import { useLockFn } from "ahooks"; let axiosIns: AxiosInstance = null!; @@ -94,13 +96,18 @@ export const updateProxy = async (group: string, proxy: string) => { // get proxy export const getProxiesInner = async () => { - const instance = await getAxios(); - const response = await instance.get("/proxies"); - return (response?.proxies || {}) as Record; + const response = await invoke>("get_proxies"); + return response.proxies; }; /// Get the Proxy information -export const getProxies = async () => { +export const getProxies = async (): Promise<{ + global: IProxyGroupItem; + direct: IProxyItem; + groups: IProxyGroupItem[]; + records: Record; + proxies: IProxyItem[]; +}> => { const [proxyRecord, providerRecord] = await Promise.all([ getProxiesInner(), getProxyProviders(), @@ -181,13 +188,10 @@ export const getProxies = async () => { // get proxy providers export const getProxyProviders = async () => { - const instance = await getAxios(); - const response = await instance.get("/providers/proxies"); - - const providers = (response.providers || {}) as Record< - string, - IProxyProviderItem - >; + const response = await invoke>( + "get_providers_proxies", + ); + const providers = response.providers; return Object.fromEntries( Object.entries(providers).filter(([key, item]) => {