refactor: impl as struct methods
This commit is contained in:
parent
e32bfd9aab
commit
03f9fa4bc2
@ -1,60 +1,42 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
config::{ProfileItem, ProfilesConfig},
|
config::{ProfileItem, ProfilesConfig},
|
||||||
events::state::{ClashInfoState, ProfileLock},
|
events::state::{ClashInfoState, ProfilesState},
|
||||||
utils::{
|
utils::{clash, fetch},
|
||||||
app_home_dir,
|
|
||||||
clash::put_clash_profile,
|
|
||||||
config::{read_profiles, save_profiles},
|
|
||||||
fetch::fetch_profile,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Write;
|
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
|
||||||
use tauri::State;
|
use tauri::State;
|
||||||
|
|
||||||
|
/// get all profiles from `profiles.yaml`
|
||||||
|
/// do not acquire the lock of ProfileLock
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn get_profiles(profiles: State<'_, ProfilesState>) -> Result<ProfilesConfig, String> {
|
||||||
|
match profiles.0.lock() {
|
||||||
|
Ok(profiles) => Ok(profiles.clone()),
|
||||||
|
Err(_) => Err("can not get profiles lock".into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// synchronize data irregularly
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn sync_profiles(profiles: State<'_, ProfilesState>) -> Result<(), String> {
|
||||||
|
match profiles.0.lock() {
|
||||||
|
Ok(mut profiles) => profiles.sync_file(),
|
||||||
|
Err(_) => Err("can not get profiles lock".into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Import the profile from url
|
/// Import the profile from url
|
||||||
/// and save to `profiles.yaml`
|
/// and save to `profiles.yaml`
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn import_profile(url: String, lock: State<'_, ProfileLock>) -> Result<(), String> {
|
pub async fn import_profile(url: String, profiles: State<'_, ProfilesState>) -> Result<(), String> {
|
||||||
let result = match fetch_profile(&url).await {
|
let result = match fetch::fetch_profile(&url).await {
|
||||||
Some(r) => r,
|
Some(r) => r,
|
||||||
None => {
|
None => return Err(format!("failed to fetch profile from `{}`", url)),
|
||||||
log::error!("failed to fetch profile from `{}`", url);
|
|
||||||
return Err(format!("failed to fetch profile from `{}`", url));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// get lock
|
match profiles.0.lock() {
|
||||||
if lock.0.lock().is_err() {
|
Ok(mut profiles) => profiles.import_from_url(url, result),
|
||||||
return Err(format!("can not get file lock"));
|
Err(_) => Err("can not get profiles lock".into()),
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the profile file
|
|
||||||
let path = app_home_dir().join("profiles").join(&result.file);
|
|
||||||
let file_data = result.data.as_bytes();
|
|
||||||
File::create(path).unwrap().write(file_data).unwrap();
|
|
||||||
|
|
||||||
// update `profiles.yaml`
|
|
||||||
let mut profiles = read_profiles();
|
|
||||||
let mut items = profiles.items.unwrap_or(vec![]);
|
|
||||||
|
|
||||||
let now = SystemTime::now()
|
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.unwrap()
|
|
||||||
.as_secs();
|
|
||||||
|
|
||||||
items.push(ProfileItem {
|
|
||||||
name: Some(result.name),
|
|
||||||
file: Some(result.file),
|
|
||||||
mode: Some(format!("rule")),
|
|
||||||
url: Some(url),
|
|
||||||
selected: Some(vec![]),
|
|
||||||
extra: Some(result.extra),
|
|
||||||
updated: Some(now as usize),
|
|
||||||
});
|
|
||||||
profiles.items = Some(items);
|
|
||||||
save_profiles(&profiles)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the profile
|
/// Update the profile
|
||||||
@ -62,129 +44,78 @@ pub async fn import_profile(url: String, lock: State<'_, ProfileLock>) -> Result
|
|||||||
/// http request firstly
|
/// http request firstly
|
||||||
/// then acquire the lock of `profiles.yaml`
|
/// then acquire the lock of `profiles.yaml`
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn update_profile(index: usize, lock: State<'_, ProfileLock>) -> Result<(), String> {
|
pub async fn update_profile(
|
||||||
// get lock
|
index: usize,
|
||||||
if lock.0.lock().is_err() {
|
profiles: State<'_, ProfilesState>,
|
||||||
return Err(format!("can not get file lock"));
|
) -> Result<(), String> {
|
||||||
}
|
// maybe we can get the url from the web app directly
|
||||||
|
let url = {
|
||||||
// update `profiles.yaml`
|
match profiles.0.lock() {
|
||||||
let mut profiles = read_profiles();
|
Ok(mut profile) => {
|
||||||
let mut items = profiles.items.unwrap_or(vec![]);
|
let items = profile.items.take().unwrap_or(vec![]);
|
||||||
|
if index >= items.len() {
|
||||||
if index >= items.len() {
|
return Err("the index out of bound".into());
|
||||||
return Err(format!("the index out of bound"));
|
}
|
||||||
}
|
let url = match &items[index].url {
|
||||||
|
Some(u) => u.clone(),
|
||||||
let url = match &items[index].url {
|
None => return Err("failed to update profile for `invalid url`".into()),
|
||||||
Some(u) => u,
|
};
|
||||||
None => return Err(format!("invalid url")),
|
profile.items = Some(items);
|
||||||
};
|
url
|
||||||
|
}
|
||||||
let result = match fetch_profile(&url).await {
|
Err(_) => return Err("can not get profiles lock".into()),
|
||||||
Some(r) => r,
|
|
||||||
None => {
|
|
||||||
log::error!("failed to fetch profile from `{}`", url);
|
|
||||||
return Err(format!("failed to fetch profile from `{}`", url));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let now = SystemTime::now()
|
let result = match fetch::fetch_profile(&url).await {
|
||||||
.duration_since(UNIX_EPOCH)
|
Some(r) => r,
|
||||||
.unwrap()
|
None => return Err(format!("failed to fetch profile from `{}`", url)),
|
||||||
.as_secs() as usize;
|
};
|
||||||
|
|
||||||
// update file
|
match profiles.0.lock() {
|
||||||
let file_path = &items[index].file.as_ref().unwrap();
|
Ok(mut profiles) => profiles.update_item(index, result),
|
||||||
let file_path = app_home_dir().join("profiles").join(file_path);
|
Err(_) => Err("can not get profiles lock".into()),
|
||||||
let file_data = result.data.as_bytes();
|
|
||||||
File::create(file_path).unwrap().write(file_data).unwrap();
|
|
||||||
|
|
||||||
items[index].name = Some(result.name);
|
|
||||||
items[index].extra = Some(result.extra);
|
|
||||||
items[index].updated = Some(now);
|
|
||||||
profiles.items = Some(items);
|
|
||||||
save_profiles(&profiles)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// get all profiles from `profiles.yaml`
|
|
||||||
/// do not acquire the lock of ProfileLock
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn get_profiles() -> Result<ProfilesConfig, String> {
|
|
||||||
Ok(read_profiles())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// patch the profile config
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn set_profiles(
|
|
||||||
index: usize,
|
|
||||||
profile: ProfileItem,
|
|
||||||
lock: State<'_, ProfileLock>,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
// get lock
|
|
||||||
if lock.0.lock().is_err() {
|
|
||||||
return Err(format!("can not get file lock"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut profiles = read_profiles();
|
|
||||||
let mut items = profiles.items.unwrap_or(vec![]);
|
|
||||||
|
|
||||||
if index >= items.len() {
|
|
||||||
return Err(format!("the index out of bound"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if profile.name.is_some() {
|
|
||||||
items[index].name = profile.name;
|
|
||||||
}
|
|
||||||
if profile.file.is_some() {
|
|
||||||
items[index].file = profile.file;
|
|
||||||
}
|
|
||||||
if profile.mode.is_some() {
|
|
||||||
items[index].mode = profile.mode;
|
|
||||||
}
|
|
||||||
if profile.url.is_some() {
|
|
||||||
items[index].url = profile.url;
|
|
||||||
}
|
|
||||||
if profile.selected.is_some() {
|
|
||||||
items[index].selected = profile.selected;
|
|
||||||
}
|
|
||||||
if profile.extra.is_some() {
|
|
||||||
items[index].extra = profile.extra;
|
|
||||||
}
|
|
||||||
|
|
||||||
profiles.items = Some(items);
|
|
||||||
save_profiles(&profiles)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// change the current profile
|
/// change the current profile
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn put_profiles(
|
pub async fn select_profile(
|
||||||
current: usize,
|
index: usize,
|
||||||
lock: State<'_, ProfileLock>,
|
profiles: State<'_, ProfilesState>,
|
||||||
clash_info: State<'_, ClashInfoState>,
|
clash_info: State<'_, ClashInfoState>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
if lock.0.lock().is_err() {
|
match profiles.0.lock() {
|
||||||
return Err(format!("can not get file lock"));
|
Ok(mut profiles) => profiles.put_current(index)?,
|
||||||
}
|
Err(_) => return Err("can not get profiles lock".into()),
|
||||||
|
};
|
||||||
|
|
||||||
let clash_info = match clash_info.0.lock() {
|
let arc = match clash_info.0.lock() {
|
||||||
Ok(arc) => arc.clone(),
|
Ok(arc) => arc.clone(),
|
||||||
_ => return Err(format!("can not get clash info")),
|
_ => return Err("can not get clash info lock".into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut profiles = read_profiles();
|
clash::put_clash_profile(&arc).await
|
||||||
let items_len = match &profiles.items {
|
}
|
||||||
Some(list) => list.len(),
|
|
||||||
None => 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
if current >= items_len {
|
/// delete profile item
|
||||||
return Err(format!("the index out of bound"));
|
#[tauri::command]
|
||||||
}
|
pub fn delete_profile(index: usize, profiles: State<'_, ProfilesState>) -> Result<(), String> {
|
||||||
|
match profiles.0.lock() {
|
||||||
profiles.current = Some(current);
|
Ok(mut profiles) => profiles.delete_item(index),
|
||||||
match save_profiles(&profiles) {
|
Err(_) => Err("can not get profiles lock".into()),
|
||||||
Ok(_) => put_clash_profile(&clash_info).await,
|
}
|
||||||
Err(err) => Err(err),
|
}
|
||||||
|
|
||||||
|
/// patch the profile config
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn patch_profile(
|
||||||
|
index: usize,
|
||||||
|
profile: ProfileItem,
|
||||||
|
profiles: State<'_, ProfilesState>,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
match profiles.0.lock() {
|
||||||
|
Ok(mut profiles) => profiles.patch_item(index, profile),
|
||||||
|
Err(_) => Err("can not get profiles lock".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
use crate::utils::{app_home_dir, config};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
/// Define the `profiles.yaml` schema
|
/// Define the `profiles.yaml` schema
|
||||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||||
@ -50,3 +54,156 @@ pub struct ProfileResponse {
|
|||||||
pub data: String,
|
pub data: String,
|
||||||
pub extra: ProfileExtra,
|
pub extra: ProfileExtra,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PROFILE_YAML: &str = "profiles.yaml";
|
||||||
|
|
||||||
|
impl ProfilesConfig {
|
||||||
|
/// read the config from the file
|
||||||
|
pub fn read_file() -> Self {
|
||||||
|
config::read_yaml::<ProfilesConfig>(app_home_dir().join(PROFILE_YAML))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// save the config to the file
|
||||||
|
pub fn save_file(&self) -> Result<(), String> {
|
||||||
|
config::save_yaml(
|
||||||
|
app_home_dir().join(PROFILE_YAML),
|
||||||
|
self,
|
||||||
|
Some("# Profiles Config for Clash Verge\n\n"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// sync the config between file and memory
|
||||||
|
pub fn sync_file(&mut self) -> Result<(), String> {
|
||||||
|
let data = config::read_yaml::<Self>(app_home_dir().join(PROFILE_YAML));
|
||||||
|
if data.current.is_none() {
|
||||||
|
Err("failed to read profiles.yaml".into())
|
||||||
|
} else {
|
||||||
|
self.current = data.current;
|
||||||
|
self.items = data.items;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// import the new profile from the url
|
||||||
|
/// and update the config file
|
||||||
|
pub fn import_from_url(&mut self, url: String, result: ProfileResponse) -> Result<(), String> {
|
||||||
|
// save the profile file
|
||||||
|
let path = app_home_dir().join("profiles").join(&result.file);
|
||||||
|
let file_data = result.data.as_bytes();
|
||||||
|
File::create(path).unwrap().write(file_data).unwrap();
|
||||||
|
|
||||||
|
// update `profiles.yaml`
|
||||||
|
let data = ProfilesConfig::read_file();
|
||||||
|
let mut items = data.items.unwrap_or(vec![]);
|
||||||
|
|
||||||
|
let now = SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_secs();
|
||||||
|
|
||||||
|
items.push(ProfileItem {
|
||||||
|
name: Some(result.name),
|
||||||
|
file: Some(result.file),
|
||||||
|
mode: Some(format!("rule")),
|
||||||
|
url: Some(url),
|
||||||
|
selected: Some(vec![]),
|
||||||
|
extra: Some(result.extra),
|
||||||
|
updated: Some(now as usize),
|
||||||
|
});
|
||||||
|
|
||||||
|
self.items = Some(items);
|
||||||
|
if data.current.is_none() {
|
||||||
|
self.current = Some(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.save_file()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// set the current and save to file
|
||||||
|
pub fn put_current(&mut self, index: usize) -> Result<(), String> {
|
||||||
|
let items = self.items.take().unwrap_or(vec![]);
|
||||||
|
|
||||||
|
if index >= items.len() {
|
||||||
|
return Err("the index out of bound".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.items = Some(items);
|
||||||
|
self.current = Some(index);
|
||||||
|
self.save_file()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// update the target profile
|
||||||
|
/// and save to config file
|
||||||
|
/// only support the url item
|
||||||
|
pub fn update_item(&mut self, index: usize, result: ProfileResponse) -> Result<(), String> {
|
||||||
|
let mut items = self.items.take().unwrap_or(vec![]);
|
||||||
|
|
||||||
|
let now = SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_secs() as usize;
|
||||||
|
|
||||||
|
// update file
|
||||||
|
let file_path = &items[index].file.as_ref().unwrap();
|
||||||
|
let file_path = app_home_dir().join("profiles").join(file_path);
|
||||||
|
let file_data = result.data.as_bytes();
|
||||||
|
File::create(file_path).unwrap().write(file_data).unwrap();
|
||||||
|
|
||||||
|
items[index].name = Some(result.name);
|
||||||
|
items[index].extra = Some(result.extra);
|
||||||
|
items[index].updated = Some(now);
|
||||||
|
|
||||||
|
self.items = Some(items);
|
||||||
|
self.save_file()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// patch item
|
||||||
|
pub fn patch_item(&mut self, index: usize, profile: ProfileItem) -> Result<(), String> {
|
||||||
|
let mut items = self.items.take().unwrap_or(vec![]);
|
||||||
|
if index >= items.len() {
|
||||||
|
return Err("index out of bound".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if profile.name.is_some() {
|
||||||
|
items[index].name = profile.name;
|
||||||
|
}
|
||||||
|
if profile.file.is_some() {
|
||||||
|
items[index].file = profile.file;
|
||||||
|
}
|
||||||
|
if profile.mode.is_some() {
|
||||||
|
items[index].mode = profile.mode;
|
||||||
|
}
|
||||||
|
if profile.url.is_some() {
|
||||||
|
items[index].url = profile.url;
|
||||||
|
}
|
||||||
|
if profile.selected.is_some() {
|
||||||
|
items[index].selected = profile.selected;
|
||||||
|
}
|
||||||
|
if profile.extra.is_some() {
|
||||||
|
items[index].extra = profile.extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.items = Some(items);
|
||||||
|
self.save_file()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// delete the item
|
||||||
|
pub fn delete_item(&mut self, index: usize) -> Result<(), String> {
|
||||||
|
let mut current = self.current.clone().unwrap_or(0);
|
||||||
|
let mut items = self.items.clone().unwrap_or(vec![]);
|
||||||
|
|
||||||
|
if index >= items.len() {
|
||||||
|
return Err("index out of bound".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
items.remove(index);
|
||||||
|
|
||||||
|
if current == index {
|
||||||
|
current = 0;
|
||||||
|
} else if current > index {
|
||||||
|
current = current - 1;
|
||||||
|
}
|
||||||
|
self.current = Some(current);
|
||||||
|
self.save_file()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use super::emit::ClashInfoPayload;
|
use super::emit::ClashInfoPayload;
|
||||||
use crate::{config::VergeConfig, utils::sysopt::SysProxyConfig};
|
use crate::{
|
||||||
|
config::{ProfilesConfig, VergeConfig},
|
||||||
|
utils::sysopt::SysProxyConfig,
|
||||||
|
};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use tauri::api::process::CommandChild;
|
use tauri::api::process::CommandChild;
|
||||||
|
|
||||||
@ -7,7 +10,7 @@ use tauri::api::process::CommandChild;
|
|||||||
pub struct ClashInfoState(pub Arc<Mutex<ClashInfoPayload>>);
|
pub struct ClashInfoState(pub Arc<Mutex<ClashInfoPayload>>);
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ProfileLock(pub Mutex<bool>);
|
pub struct ProfilesState(pub Arc<Mutex<ProfilesConfig>>);
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct VergeConfLock(pub Arc<Mutex<VergeConfig>>);
|
pub struct VergeConfLock(pub Arc<Mutex<VergeConfig>>);
|
||||||
|
@ -35,7 +35,7 @@ fn main() -> std::io::Result<()> {
|
|||||||
.manage(state::VergeConfLock::default())
|
.manage(state::VergeConfLock::default())
|
||||||
.manage(state::ClashInfoState::default())
|
.manage(state::ClashInfoState::default())
|
||||||
.manage(state::SomthingState::default())
|
.manage(state::SomthingState::default())
|
||||||
.manage(state::ProfileLock::default())
|
.manage(state::ProfilesState::default())
|
||||||
.setup(|app| Ok(resolve::resolve_setup(app)))
|
.setup(|app| Ok(resolve::resolve_setup(app)))
|
||||||
.system_tray(SystemTray::new().with_menu(menu))
|
.system_tray(SystemTray::new().with_menu(menu))
|
||||||
.on_system_tray_event(move |app_handle, event| match event {
|
.on_system_tray_event(move |app_handle, event| match event {
|
||||||
@ -87,9 +87,11 @@ fn main() -> std::io::Result<()> {
|
|||||||
cmds::some::patch_verge_config,
|
cmds::some::patch_verge_config,
|
||||||
cmds::profile::import_profile,
|
cmds::profile::import_profile,
|
||||||
cmds::profile::update_profile,
|
cmds::profile::update_profile,
|
||||||
|
cmds::profile::delete_profile,
|
||||||
|
cmds::profile::select_profile,
|
||||||
|
cmds::profile::patch_profile,
|
||||||
|
cmds::profile::sync_profiles,
|
||||||
cmds::profile::get_profiles,
|
cmds::profile::get_profiles,
|
||||||
cmds::profile::set_profiles,
|
|
||||||
cmds::profile::put_profiles,
|
|
||||||
])
|
])
|
||||||
.build(tauri::generate_context!())
|
.build(tauri::generate_context!())
|
||||||
.expect("error while running tauri application")
|
.expect("error while running tauri application")
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
config::{ClashController, ProfilesConfig, VergeConfig},
|
config::{ClashController, VergeConfig},
|
||||||
utils::app_home_dir,
|
utils::app_home_dir,
|
||||||
};
|
};
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
@ -103,20 +103,6 @@ pub fn read_clash_controller() -> ClashController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get Profiles Config
|
|
||||||
pub fn read_profiles() -> ProfilesConfig {
|
|
||||||
read_yaml::<ProfilesConfig>(app_home_dir().join("profiles.yaml"))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Save Verge App Config
|
|
||||||
pub fn save_profiles(profiles: &ProfilesConfig) -> Result<(), String> {
|
|
||||||
save_yaml(
|
|
||||||
app_home_dir().join("profiles.yaml"),
|
|
||||||
profiles,
|
|
||||||
Some("# Profiles Config for Clash Verge\n\n"),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the `verge.yaml`
|
/// Get the `verge.yaml`
|
||||||
pub fn read_verge() -> VergeConfig {
|
pub fn read_verge() -> VergeConfig {
|
||||||
read_yaml::<VergeConfig>(app_home_dir().join("verge.yaml"))
|
read_yaml::<VergeConfig>(app_home_dir().join("verge.yaml"))
|
||||||
|
@ -22,8 +22,7 @@ import {
|
|||||||
} from "@mui/icons-material";
|
} from "@mui/icons-material";
|
||||||
import { updateProxy } from "../services/api";
|
import { updateProxy } from "../services/api";
|
||||||
import { ApiType } from "../services/types";
|
import { ApiType } from "../services/types";
|
||||||
import { getProfiles, setProfiles } from "../services/cmds";
|
import { getProfiles, patchProfile } from "../services/cmds";
|
||||||
import noop from "../utils/noop";
|
|
||||||
|
|
||||||
interface ItemProps {
|
interface ItemProps {
|
||||||
proxy: ApiType.ProxyItem;
|
proxy: ApiType.ProxyItem;
|
||||||
@ -105,7 +104,7 @@ const ProxyGroup = ({ group }: Props) => {
|
|||||||
profile.selected[index] = { name: group.name, now: name };
|
profile.selected[index] = { name: group.name, now: name };
|
||||||
}
|
}
|
||||||
|
|
||||||
setProfiles(profiles.current!, profile).catch(console.error);
|
patchProfile(profiles.current!, profile).catch(console.error);
|
||||||
} catch {
|
} catch {
|
||||||
setNow(oldValue);
|
setNow(oldValue);
|
||||||
// Todo
|
// Todo
|
||||||
|
@ -3,8 +3,8 @@ import useSWR, { useSWRConfig } from "swr";
|
|||||||
import { Box, Button, Grid, TextField, Typography } from "@mui/material";
|
import { Box, Button, Grid, TextField, Typography } from "@mui/material";
|
||||||
import {
|
import {
|
||||||
getProfiles,
|
getProfiles,
|
||||||
putProfiles,
|
selectProfile,
|
||||||
setProfiles,
|
patchProfile,
|
||||||
importProfile,
|
importProfile,
|
||||||
} from "../services/cmds";
|
} from "../services/cmds";
|
||||||
import { getProxies, updateProxy } from "../services/api";
|
import { getProxies, updateProxy } from "../services/api";
|
||||||
@ -52,7 +52,7 @@ const ProfilePage = () => {
|
|||||||
name,
|
name,
|
||||||
now,
|
now,
|
||||||
}));
|
}));
|
||||||
setProfiles(profiles.current!, profile).catch(console.error);
|
patchProfile(profiles.current!, profile).catch(console.error);
|
||||||
// update proxies cache
|
// update proxies cache
|
||||||
if (hasChange) mutate("getProxies", getProxies());
|
if (hasChange) mutate("getProxies", getProxies());
|
||||||
});
|
});
|
||||||
@ -66,7 +66,7 @@ const ProfilePage = () => {
|
|||||||
try {
|
try {
|
||||||
await importProfile(url);
|
await importProfile(url);
|
||||||
mutate("getProfiles", getProfiles());
|
mutate("getProfiles", getProfiles());
|
||||||
if (!profiles.items?.length) putProfiles(0).catch(noop);
|
if (!profiles.items?.length) selectProfile(0).catch(noop);
|
||||||
notice.success("Successfully import profile.");
|
notice.success("Successfully import profile.");
|
||||||
} catch {
|
} catch {
|
||||||
notice.error("Failed to import profile.");
|
notice.error("Failed to import profile.");
|
||||||
@ -80,7 +80,7 @@ const ProfilePage = () => {
|
|||||||
if (index === profiles.current || lockRef.current) return;
|
if (index === profiles.current || lockRef.current) return;
|
||||||
if (lockRef.current) return;
|
if (lockRef.current) return;
|
||||||
lockRef.current = true;
|
lockRef.current = true;
|
||||||
putProfiles(index)
|
selectProfile(index)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate("getProfiles", { ...profiles, current: index }, true);
|
mutate("getProfiles", { ...profiles, current: index }, true);
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,37 @@
|
|||||||
import { invoke } from "@tauri-apps/api/tauri";
|
import { invoke } from "@tauri-apps/api/tauri";
|
||||||
import { ApiType, CmdType } from "./types";
|
import { ApiType, CmdType } from "./types";
|
||||||
|
|
||||||
|
export async function getProfiles() {
|
||||||
|
return (await invoke<CmdType.ProfilesConfig>("get_profiles")) ?? {};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function syncProfiles() {
|
||||||
|
return invoke<void>("sync_profiles");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function importProfile(url: string) {
|
||||||
|
return invoke<void>("import_profile", { url });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateProfile(index: number) {
|
||||||
|
return invoke<void>("update_profile", { index });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteProfile(index: number) {
|
||||||
|
return invoke<void>("delete_profile", { index });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function patchProfile(
|
||||||
|
index: number,
|
||||||
|
profile: CmdType.ProfileItem
|
||||||
|
) {
|
||||||
|
return invoke<void>("patch_profile", { index, profile });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function selectProfile(index: number) {
|
||||||
|
return invoke<void>("select_profile", { index });
|
||||||
|
}
|
||||||
|
|
||||||
export async function restartSidecar() {
|
export async function restartSidecar() {
|
||||||
return invoke<void>("restart_sidecar");
|
return invoke<void>("restart_sidecar");
|
||||||
}
|
}
|
||||||
@ -13,26 +44,6 @@ export async function patchClashConfig(payload: Partial<ApiType.ConfigData>) {
|
|||||||
return invoke<void>("patch_clash_config", { payload });
|
return invoke<void>("patch_clash_config", { payload });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function importProfile(url: string) {
|
|
||||||
return invoke<void>("import_profile", { url });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updateProfile(index: number) {
|
|
||||||
return invoke<void>("update_profile", { index });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getProfiles() {
|
|
||||||
return (await invoke<CmdType.ProfilesConfig>("get_profiles")) ?? {};
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function setProfiles(index: number, profile: CmdType.ProfileItem) {
|
|
||||||
return invoke<void>("set_profiles", { index, profile });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function putProfiles(current: number) {
|
|
||||||
return invoke<void>("put_profiles", { current });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function setSysProxy(enable: boolean) {
|
export async function setSysProxy(enable: boolean) {
|
||||||
return invoke<void>("set_sys_proxy", { enable });
|
return invoke<void>("set_sys_proxy", { enable });
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user