diff --git a/src-tauri/src/cmd.rs b/src-tauri/src/cmd.rs index e976d40..7fe8b43 100644 --- a/src-tauri/src/cmd.rs +++ b/src-tauri/src/cmd.rs @@ -1,6 +1,9 @@ use crate::{ - config::{read_profiles, save_profiles, ProfileItem}, - events::{emit::ClashInfoPayload, state::ClashInfoState}, + config::{read_profiles, save_profiles, ProfileItem, ProfilesConfig}, + events::{ + emit::ClashInfoPayload, + state::{ClashInfoState, ProfileLock}, + }, utils::{app_home_dir, clash, fetch::fetch_profile}, }; use std::fs::File; @@ -28,7 +31,7 @@ pub fn get_clash_info(clash_info: State<'_, ClashInfoState>) -> Option Result { +pub async fn import_profile(url: String, lock: State<'_, ProfileLock>) -> Result { let result = match fetch_profile(&url).await { Some(r) => r, None => { @@ -43,6 +46,12 @@ pub async fn import_profile(url: String) -> Result { .write(result.data.as_bytes()) .unwrap(); + // get lock + match lock.0.lock() { + Ok(_) => {} + Err(_) => return Err(format!("can not get file locked")), + }; + // update profiles.yaml let mut profiles = read_profiles(); let mut items = match profiles.items { @@ -65,3 +74,60 @@ pub async fn import_profile(url: String) -> Result { Ok(format!("success")) } + +#[tauri::command] +pub fn get_profiles(lock: State<'_, ProfileLock>) -> Option { + match lock.0.lock() { + Ok(_) => Some(read_profiles()), + Err(_) => None, + } +} + +#[tauri::command] +pub fn set_profiles( + current: usize, + profile: ProfileItem, + lock: State<'_, ProfileLock>, +) -> Result<(), String> { + match lock.0.lock() { + Ok(_) => {} + Err(_) => return Err(format!("can not get file locked")), + }; + + let mut profiles = read_profiles(); + let mut items = match profiles.items { + Some(p) => p, + None => vec![], + }; + + if current >= items.len() { + return Err(format!("out of profiles bound")); + } + + let mut origin = items[current].clone(); + + if profile.name.is_some() { + origin.name = profile.name; + } + if profile.file.is_some() { + origin.file = profile.file; + } + if profile.mode.is_some() { + origin.mode = profile.mode; + } + if profile.url.is_some() { + origin.url = profile.url; + } + if profile.selected.is_some() { + origin.selected = profile.selected; + } + if profile.extra.is_some() { + origin.extra = profile.extra; + } + + items[current] = origin; + profiles.items = Some(items); + save_profiles(&profiles); + + Ok(()) +} diff --git a/src-tauri/src/events/state.rs b/src-tauri/src/events/state.rs index 22aa77f..7640003 100644 --- a/src-tauri/src/events/state.rs +++ b/src-tauri/src/events/state.rs @@ -4,3 +4,6 @@ use super::emit::ClashInfoPayload; #[derive(Default)] pub struct ClashInfoState(pub Arc>); + +#[derive(Default)] +pub struct ProfileLock(pub Mutex); diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 41d9719..1a47948 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -10,7 +10,7 @@ mod config; mod events; mod utils; -use crate::{events::state::ClashInfoState, utils::clash::put_clash_profile}; +use crate::{events::state, utils::clash::put_clash_profile}; use std::sync::{Arc, Mutex}; use tauri::{ api, CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem, @@ -57,9 +57,11 @@ fn main() -> std::io::Result<()> { _ => {} }) .invoke_handler(tauri::generate_handler![ - cmd::import_profile, cmd::restart_sidebar, cmd::get_clash_info, + cmd::import_profile, + cmd::get_profiles, + cmd::set_profiles ]) .build(tauri::generate_context!()) .expect("error while running tauri application"); @@ -77,7 +79,8 @@ fn main() -> std::io::Result<()> { }; }); - app.manage(ClashInfoState(Arc::new(Mutex::new(info)))); + app.manage(state::ClashInfoState(Arc::new(Mutex::new(info)))); + app.manage(state::ProfileLock::default()); app.run(|app_handle, e| match e { tauri::Event::CloseRequested { label, api, .. } => {