mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2024-11-16 03:32:36 +08:00
refactor: done
This commit is contained in:
parent
34daffbc96
commit
2667ed13f1
|
@ -5,7 +5,7 @@ use crate::{
|
|||
utils::{dirs, help},
|
||||
};
|
||||
use crate::{ret_err, wrap_err};
|
||||
use anyhow::Result;
|
||||
use anyhow::{Context, Result};
|
||||
use serde_yaml::Mapping;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use sysproxy::Sysproxy;
|
||||
|
@ -19,7 +19,9 @@ pub fn get_profiles() -> CmdResult<IProfiles> {
|
|||
|
||||
#[tauri::command]
|
||||
pub async fn enhance_profiles() -> CmdResult {
|
||||
wrap_err!(feat::handle_activate().await)
|
||||
wrap_err!(CoreManager::global().update_config().await)?;
|
||||
handle::Handle::refresh_clash();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
|
@ -40,75 +42,41 @@ pub async fn update_profile(index: String, option: Option<PrfOption>) -> CmdResu
|
|||
wrap_err!(feat::update_profile(index, option).await)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn select_profile(index: String) -> CmdResult {
|
||||
wrap_err!({ Config::profiles().draft().put_current(index) })?;
|
||||
|
||||
match feat::handle_activate().await {
|
||||
Ok(_) => {
|
||||
Config::profiles().apply();
|
||||
wrap_err!(Config::profiles().data().save_file())?;
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
Config::profiles().discard();
|
||||
log::error!(target: "app", "{err}");
|
||||
Err(format!("{err}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// change the profile chain
|
||||
#[tauri::command]
|
||||
pub async fn change_profile_chain(chain: Option<Vec<String>>) -> CmdResult {
|
||||
wrap_err!({ Config::profiles().draft().put_chain(chain) })?;
|
||||
|
||||
match feat::handle_activate().await {
|
||||
Ok(_) => {
|
||||
Config::profiles().apply();
|
||||
wrap_err!(Config::profiles().data().save_file())?;
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
Config::profiles().discard();
|
||||
log::error!(target: "app", "{err}");
|
||||
Err(format!("{err}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn change_profile_valid(valid: Option<Vec<String>>) -> CmdResult {
|
||||
wrap_err!({ Config::profiles().draft().put_valid(valid) })?;
|
||||
|
||||
match feat::handle_activate().await {
|
||||
Ok(_) => {
|
||||
Config::profiles().apply();
|
||||
wrap_err!(Config::profiles().data().save_file())?;
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
Config::profiles().discard();
|
||||
log::error!(target: "app", "{err}");
|
||||
Err(format!("{err}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn delete_profile(index: String) -> CmdResult {
|
||||
let should_update = wrap_err!({ Config::profiles().data().delete_item(index) })?;
|
||||
if should_update {
|
||||
wrap_err!(feat::handle_activate().await)?;
|
||||
wrap_err!(CoreManager::global().update_config().await)?;
|
||||
handle::Handle::refresh_clash();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 修改profiles的
|
||||
#[tauri::command]
|
||||
pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult {
|
||||
wrap_err!({ Config::profiles().draft().patch_config(profiles) })?;
|
||||
|
||||
match CoreManager::global().update_config().await {
|
||||
Ok(_) => {
|
||||
handle::Handle::refresh_clash();
|
||||
Config::profiles().apply();
|
||||
wrap_err!(Config::profiles().data().save_file())?;
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
Config::profiles().discard();
|
||||
log::error!(target: "app", "{err}");
|
||||
Err(format!("{err}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 修改某个profile item的
|
||||
#[tauri::command]
|
||||
pub fn patch_profile(index: String, profile: PrfItem) -> CmdResult {
|
||||
wrap_err!(Config::profiles().data().patch_item(index, profile))?;
|
||||
|
||||
wrap_err!(timer::Timer::global().refresh())
|
||||
}
|
||||
|
||||
|
@ -157,34 +125,29 @@ pub fn get_clash_info() -> CmdResult<ClashInfoN> {
|
|||
|
||||
#[tauri::command]
|
||||
pub fn get_runtime_config() -> CmdResult<Option<Mapping>> {
|
||||
Ok(CoreManager::global().runtime_config.lock().config.clone())
|
||||
Ok(Config::runtime().latest().config.clone())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_runtime_yaml() -> CmdResult<Option<String>> {
|
||||
Ok(CoreManager::global()
|
||||
.runtime_config
|
||||
.lock()
|
||||
.config_yaml
|
||||
.clone())
|
||||
pub fn get_runtime_yaml() -> CmdResult<String> {
|
||||
let runtime = Config::runtime();
|
||||
let runtime = runtime.latest();
|
||||
let config = runtime.config.as_ref();
|
||||
wrap_err!(config
|
||||
.ok_or(anyhow::anyhow!("failed to parse config to yaml file"))
|
||||
.and_then(
|
||||
|config| serde_yaml::to_string(config).context("failed to convert config to yaml")
|
||||
))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_runtime_exists() -> CmdResult<Vec<String>> {
|
||||
Ok(CoreManager::global()
|
||||
.runtime_config
|
||||
.lock()
|
||||
.exists_keys
|
||||
.clone())
|
||||
Ok(Config::runtime().latest().exists_keys.clone())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_runtime_logs() -> CmdResult<HashMap<String, Vec<(String, String)>>> {
|
||||
Ok(CoreManager::global()
|
||||
.runtime_config
|
||||
.lock()
|
||||
.chain_logs
|
||||
.clone())
|
||||
Ok(Config::runtime().latest().chain_logs.clone())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::utils::{config, dirs};
|
||||
use crate::utils::{dirs, help};
|
||||
use anyhow::Result;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
|
@ -8,7 +8,7 @@ pub struct IClashTemp(pub Mapping);
|
|||
|
||||
impl IClashTemp {
|
||||
pub fn new() -> Self {
|
||||
match dirs::clash_path().and_then(|path| config::read_merge_mapping(&path)) {
|
||||
match dirs::clash_path().and_then(|path| help::read_merge_mapping(&path)) {
|
||||
Ok(map) => Self(map),
|
||||
Err(err) => {
|
||||
log::error!(target: "app", "{err}");
|
||||
|
@ -20,7 +20,7 @@ impl IClashTemp {
|
|||
pub fn template() -> Self {
|
||||
let mut map = Mapping::new();
|
||||
|
||||
map.insert("mixed-port".into(), 7892.into());
|
||||
map.insert("mixed-port".into(), 7890.into());
|
||||
map.insert("log-level".into(), "info".into());
|
||||
map.insert("allow-lan".into(), false.into());
|
||||
map.insert("mode".into(), "rule".into());
|
||||
|
@ -37,10 +37,10 @@ impl IClashTemp {
|
|||
}
|
||||
|
||||
pub fn save_config(&self) -> Result<()> {
|
||||
config::save_yaml(
|
||||
dirs::clash_path()?,
|
||||
help::save_yaml(
|
||||
&dirs::clash_path()?,
|
||||
&self.0,
|
||||
Some("# Default Config For ClashN Core\n\n"),
|
||||
Some("# Generated by Clash Verge"),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,20 @@
|
|||
use super::{Draft, IClashTemp, IProfiles, IVerge};
|
||||
use super::{Draft, IClashTemp, IProfiles, IRuntime, IVerge};
|
||||
use crate::{
|
||||
enhance,
|
||||
utils::{dirs, help},
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::{env::temp_dir, path::PathBuf};
|
||||
|
||||
pub const RUNTIME_CONFIG: &str = "clash-verge.yaml";
|
||||
pub const CHECK_CONFIG: &str = "clash-verge-check.yaml";
|
||||
|
||||
pub struct Config {
|
||||
clash_config: Draft<IClashTemp>,
|
||||
verge_config: Draft<IVerge>,
|
||||
profiles_config: Draft<IProfiles>,
|
||||
runtime_config: Draft<IRuntime>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
|
@ -15,6 +25,7 @@ impl Config {
|
|||
clash_config: Draft::from(IClashTemp::new()),
|
||||
verge_config: Draft::from(IVerge::new()),
|
||||
profiles_config: Draft::from(IProfiles::new()),
|
||||
runtime_config: Draft::from(IRuntime::new()),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -29,4 +40,72 @@ impl Config {
|
|||
pub fn profiles() -> Draft<IProfiles> {
|
||||
Self::global().profiles_config.clone()
|
||||
}
|
||||
|
||||
pub fn runtime() -> Draft<IRuntime> {
|
||||
Self::global().runtime_config.clone()
|
||||
}
|
||||
|
||||
/// 初始化配置
|
||||
pub fn init_config() -> Result<()> {
|
||||
crate::log_err!(Self::generate());
|
||||
if let Err(err) = Self::generate_file(ConfigType::Run) {
|
||||
log::error!(target: "app", "{err}");
|
||||
|
||||
let runtime_path = dirs::app_home_dir()?.join(RUNTIME_CONFIG);
|
||||
// 如果不存在就将默认的clash文件拿过来
|
||||
if !runtime_path.exists() {
|
||||
help::save_yaml(
|
||||
&runtime_path,
|
||||
&Config::clash().latest().0,
|
||||
Some("# Clash Verge Runtime"),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 将配置丢到对应的文件中
|
||||
pub fn generate_file(typ: ConfigType) -> Result<PathBuf> {
|
||||
let path = match typ {
|
||||
ConfigType::Run => dirs::app_home_dir()?.join(RUNTIME_CONFIG),
|
||||
ConfigType::Check => temp_dir().join(CHECK_CONFIG),
|
||||
};
|
||||
|
||||
let runtime = Config::runtime();
|
||||
let runtime = runtime.latest();
|
||||
let config = runtime
|
||||
.config
|
||||
.as_ref()
|
||||
.ok_or(anyhow!("failed to get runtime config"))?;
|
||||
|
||||
help::save_yaml(&path, &config, Some("# Generated by Clash Verge"))?;
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
/// 生成配置存好
|
||||
pub fn generate() -> Result<()> {
|
||||
let clash_config = { Config::clash().latest().clone() };
|
||||
|
||||
let tun_mode = { Config::verge().latest().enable_tun_mode.clone() };
|
||||
let tun_mode = tun_mode.unwrap_or(false);
|
||||
|
||||
let pa = { Config::profiles().latest().gen_activate()? };
|
||||
|
||||
let (config, exists_keys, logs) =
|
||||
enhance::enhance_config(clash_config.0, pa.current, pa.chain, pa.valid, tun_mode);
|
||||
|
||||
*Config::runtime().draft() = IRuntime {
|
||||
config: Some(config),
|
||||
exists_keys,
|
||||
chain_logs: logs,
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ConfigType {
|
||||
Run,
|
||||
Check,
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::{IClashTemp, IProfiles, IVerge};
|
||||
use super::{IClashTemp, IProfiles, IRuntime, IVerge};
|
||||
use parking_lot::{MappedMutexGuard, Mutex, MutexGuard};
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -10,6 +10,7 @@ pub struct Draft<T: Clone + ToOwned> {
|
|||
macro_rules! draft_define {
|
||||
($id: ident) => {
|
||||
impl Draft<$id> {
|
||||
#[allow(unused)]
|
||||
pub fn data(&self) -> MappedMutexGuard<$id> {
|
||||
MutexGuard::map(self.inner.lock(), |guard| &mut guard.0)
|
||||
}
|
||||
|
@ -65,9 +66,9 @@ macro_rules! draft_define {
|
|||
|
||||
// draft_define!(IClash);
|
||||
draft_define!(IClashTemp);
|
||||
draft_define!(IVerge);
|
||||
// draft_define!(Mapping);
|
||||
draft_define!(IProfiles);
|
||||
draft_define!(IRuntime);
|
||||
draft_define!(IVerge);
|
||||
|
||||
#[test]
|
||||
fn test_draft() {
|
||||
|
|
|
@ -3,6 +3,7 @@ mod config;
|
|||
mod draft;
|
||||
mod prfitem;
|
||||
mod profiles;
|
||||
mod runtime;
|
||||
mod verge;
|
||||
|
||||
pub use self::clash::*;
|
||||
|
@ -10,4 +11,5 @@ pub use self::config::*;
|
|||
pub use self::draft::*;
|
||||
pub use self::prfitem::*;
|
||||
pub use self::profiles::*;
|
||||
pub use self::runtime::*;
|
||||
pub use self::verge::*;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::utils::{config, dirs, help, tmpl};
|
||||
use crate::utils::{dirs, help, tmpl};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use reqwest::StatusCode;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -388,7 +388,7 @@ impl PrfItem {
|
|||
}),
|
||||
"merge" => Some(ChainItem {
|
||||
uid,
|
||||
data: ChainType::Merge(config::read_merge_mapping(&path).ok()?),
|
||||
data: ChainType::Merge(help::read_merge_mapping(&path).ok()?),
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use super::{prfitem::PrfItem, ChainItem};
|
||||
use crate::utils::{config, dirs, help};
|
||||
use crate::utils::{dirs, help};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::Mapping;
|
||||
use std::collections::HashMap;
|
||||
use std::{fs, io::Write};
|
||||
|
||||
/// Define the `profiles.yaml` schema
|
||||
|
@ -32,7 +31,7 @@ macro_rules! patch {
|
|||
|
||||
impl IProfiles {
|
||||
pub fn new() -> Self {
|
||||
match dirs::profiles_path().and_then(|path| config::read_yaml::<Self>(&path)) {
|
||||
match dirs::profiles_path().and_then(|path| help::read_yaml::<Self>(&path)) {
|
||||
Ok(mut profiles) => {
|
||||
if profiles.items.is_none() {
|
||||
profiles.items = Some(vec![]);
|
||||
|
@ -62,21 +61,45 @@ impl IProfiles {
|
|||
}
|
||||
}
|
||||
|
||||
/// save the config to the file
|
||||
pub fn save_file(&self) -> Result<()> {
|
||||
config::save_yaml(
|
||||
dirs::profiles_path()?,
|
||||
help::save_yaml(
|
||||
&dirs::profiles_path()?,
|
||||
self,
|
||||
Some("# Profiles Config for Clash Verge\n\n"),
|
||||
Some("# Profiles Config for Clash Verge"),
|
||||
)
|
||||
}
|
||||
|
||||
/// get the current uid
|
||||
/// 只修改current,valid和chain
|
||||
pub fn patch_config(&mut self, patch: IProfiles) -> Result<()> {
|
||||
if self.items.is_none() {
|
||||
self.items = Some(vec![]);
|
||||
}
|
||||
|
||||
if let Some(current) = patch.current {
|
||||
let items = self.items.as_ref().unwrap();
|
||||
let some_uid = Some(current);
|
||||
|
||||
if items.iter().any(|e| e.uid == some_uid) {
|
||||
self.current = some_uid;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(chain) = patch.chain {
|
||||
self.chain = Some(chain);
|
||||
}
|
||||
|
||||
if let Some(valid) = patch.valid {
|
||||
self.valid = Some(valid);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_current(&self) -> Option<String> {
|
||||
self.current.clone()
|
||||
}
|
||||
|
||||
/// only change the main to the target id
|
||||
#[deprecated]
|
||||
pub fn put_current(&mut self, uid: String) -> Result<()> {
|
||||
if self.items.is_none() {
|
||||
self.items = Some(vec![]);
|
||||
|
@ -93,13 +116,13 @@ impl IProfiles {
|
|||
bail!("invalid uid \"{uid}\"");
|
||||
}
|
||||
|
||||
/// just change the `chain`
|
||||
#[deprecated]
|
||||
pub fn put_chain(&mut self, chain: Option<Vec<String>>) -> Result<()> {
|
||||
self.chain = chain;
|
||||
self.save_file()
|
||||
}
|
||||
|
||||
/// just change the `field`
|
||||
#[deprecated]
|
||||
pub fn put_valid(&mut self, valid: Option<Vec<String>>) -> Result<()> {
|
||||
self.valid = valid;
|
||||
self.save_file()
|
||||
|
@ -283,7 +306,7 @@ impl IProfiles {
|
|||
None => bail!("failed to get the file field"),
|
||||
};
|
||||
|
||||
return Ok(config::read_merge_mapping(&file_path)?);
|
||||
return Ok(help::read_merge_mapping(&file_path)?);
|
||||
}
|
||||
}
|
||||
bail!("failed to find the current profile \"uid:{current}\"");
|
||||
|
@ -316,13 +339,3 @@ pub struct PrfActivate {
|
|||
pub chain: Vec<ChainItem>,
|
||||
pub valid: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct RuntimeResult {
|
||||
pub config: Option<Mapping>,
|
||||
pub config_yaml: Option<String>,
|
||||
// 记录在配置中(包括merge和script生成的)出现过的keys
|
||||
// 这些keys不一定都生效
|
||||
pub exists_keys: Vec<String>,
|
||||
pub chain_logs: HashMap<String, Vec<(String, String)>>,
|
||||
}
|
||||
|
|
18
src-tauri/src/config/runtime.rs
Normal file
18
src-tauri/src/config/runtime.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::Mapping;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct IRuntime {
|
||||
pub config: Option<Mapping>,
|
||||
// 记录在配置中(包括merge和script生成的)出现过的keys
|
||||
// 这些keys不一定都生效
|
||||
pub exists_keys: Vec<String>,
|
||||
pub chain_logs: HashMap<String, Vec<(String, String)>>,
|
||||
}
|
||||
|
||||
impl IRuntime {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::utils::{config, dirs};
|
||||
use crate::utils::{dirs, help};
|
||||
use anyhow::Result;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -85,7 +85,7 @@ pub struct IVergeTheme {
|
|||
|
||||
impl IVerge {
|
||||
pub fn new() -> Self {
|
||||
match dirs::verge_path().and_then(|path| config::read_yaml::<IVerge>(&path)) {
|
||||
match dirs::verge_path().and_then(|path| help::read_yaml::<IVerge>(&path)) {
|
||||
Ok(config) => config,
|
||||
Err(err) => {
|
||||
log::error!(target: "app", "{err}");
|
||||
|
@ -113,11 +113,7 @@ impl IVerge {
|
|||
|
||||
/// Save IVerge App Config
|
||||
pub fn save_file(&self) -> Result<()> {
|
||||
config::save_yaml(
|
||||
dirs::verge_path()?,
|
||||
&self,
|
||||
Some("# The Config for Clash IVerge App\n\n"),
|
||||
)
|
||||
help::save_yaml(&dirs::verge_path()?, &self, Some("# Clash Verge Config"))
|
||||
}
|
||||
|
||||
/// patch verge config
|
||||
|
@ -161,7 +157,7 @@ impl IVerge {
|
|||
#[cfg(feature = "verge-dev")]
|
||||
const SERVER_PORT: u16 = 11233;
|
||||
|
||||
match dirs::verge_path().and_then(|path| config::read_yaml::<IVerge>(&path)) {
|
||||
match dirs::verge_path().and_then(|path| help::read_yaml::<IVerge>(&path)) {
|
||||
Ok(config) => config.app_singleton_port.unwrap_or(SERVER_PORT),
|
||||
Err(_) => SERVER_PORT, // 这里就不log错误了
|
||||
}
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
use crate::{config::Config, utils::dirs};
|
||||
use crate::config::Config;
|
||||
use anyhow::{bail, Result};
|
||||
use reqwest::header::HeaderMap;
|
||||
use serde_yaml::Mapping;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// PUT /configs
|
||||
pub async fn put_configs() -> Result<()> {
|
||||
/// path 是绝对路径
|
||||
pub async fn put_configs(path: &str) -> Result<()> {
|
||||
let (url, headers) = clash_client_info()?;
|
||||
let url = format!("{url}/configs");
|
||||
|
||||
let runtime_yaml = dirs::clash_runtime_yaml()?;
|
||||
let runtime_yaml = dirs::path_to_str(&runtime_yaml)?;
|
||||
|
||||
let mut data = HashMap::new();
|
||||
data.insert("path", runtime_yaml);
|
||||
data.insert("path", path);
|
||||
|
||||
let client = reqwest::ClientBuilder::new().no_proxy().build()?;
|
||||
let builder = client.put(&url).headers(headers).json(&data);
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use super::{clash_api, logger::Logger};
|
||||
use crate::{
|
||||
config::*,
|
||||
enhance, log_err,
|
||||
utils::{self, dirs},
|
||||
};
|
||||
use crate::log_err;
|
||||
use crate::{config::*, utils::dirs};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
|
@ -18,8 +15,6 @@ pub struct CoreManager {
|
|||
|
||||
#[allow(unused)]
|
||||
use_service_mode: Arc<Mutex<bool>>,
|
||||
|
||||
pub runtime_config: Arc<Mutex<RuntimeResult>>,
|
||||
}
|
||||
|
||||
impl CoreManager {
|
||||
|
@ -28,7 +23,6 @@ impl CoreManager {
|
|||
|
||||
CORE_MANAGER.get_or_init(|| CoreManager {
|
||||
sidecar: Arc::new(Mutex::new(None)),
|
||||
runtime_config: Arc::new(Mutex::new(RuntimeResult::default())),
|
||||
use_service_mode: Arc::new(Mutex::new(false)),
|
||||
})
|
||||
}
|
||||
|
@ -50,11 +44,7 @@ impl CoreManager {
|
|||
|
||||
tauri::async_runtime::spawn(async {
|
||||
// 启动clash
|
||||
if Self::global().run_core().await.is_ok() {
|
||||
// 更新配置
|
||||
sleep(Duration::from_millis(100)).await;
|
||||
crate::log_err!(Self::global().activate_config().await);
|
||||
}
|
||||
log_err!(Self::global().run_core().await);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
|
@ -62,7 +52,7 @@ impl CoreManager {
|
|||
|
||||
/// 检查配置是否正确
|
||||
pub fn check_config(&self) -> Result<()> {
|
||||
let config_path = dirs::clash_runtime_yaml()?;
|
||||
let config_path = Config::generate_file(ConfigType::Check)?;
|
||||
let config_path = dirs::path_to_str(&config_path)?;
|
||||
|
||||
let clash_core = { Config::verge().latest().clash_core.clone() };
|
||||
|
@ -82,6 +72,8 @@ impl CoreManager {
|
|||
|
||||
/// 启动核心
|
||||
pub async fn run_core(&self) -> Result<()> {
|
||||
let config_path = Config::generate_file(ConfigType::Run)?;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
use super::win_service;
|
||||
|
@ -123,10 +115,12 @@ impl CoreManager {
|
|||
let clash_core = { Config::verge().latest().clash_core.clone() };
|
||||
let clash_core = clash_core.unwrap_or("clash".into());
|
||||
|
||||
let config_path = dirs::path_to_str(&config_path)?;
|
||||
|
||||
// fix #212
|
||||
let args = match clash_core.as_str() {
|
||||
"clash-meta" => vec!["-m", "-d", app_dir],
|
||||
_ => vec!["-d", app_dir],
|
||||
"clash-meta" => vec!["-m", "-d", app_dir, "-f", config_path],
|
||||
_ => vec!["-d", app_dir, "-f", config_path],
|
||||
};
|
||||
|
||||
let cmd = Command::new_sidecar(clash_core)?;
|
||||
|
@ -199,53 +193,42 @@ impl CoreManager {
|
|||
bail!("invalid clash core name \"{clash_core}\"");
|
||||
}
|
||||
|
||||
Config::verge().draft().clash_core = Some(clash_core);
|
||||
|
||||
// 清掉旧日志
|
||||
Logger::global().clear_log();
|
||||
|
||||
{
|
||||
Config::verge().draft().clash_core = Some(clash_core);
|
||||
}
|
||||
|
||||
match self.run_core().await {
|
||||
Ok(_) => {
|
||||
log_err!({
|
||||
Config::verge().apply();
|
||||
Config::verge().latest().save_file()
|
||||
});
|
||||
|
||||
sleep(Duration::from_millis(100)).await; // 等一会儿再更新配置
|
||||
self.activate_config().await?;
|
||||
Config::verge().apply();
|
||||
Config::runtime().apply();
|
||||
log_err!(Config::verge().latest().save_file());
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
Config::verge().discard();
|
||||
Config::runtime().discard();
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 激活一个配置
|
||||
pub async fn activate_config(&self) -> Result<()> {
|
||||
let clash_config = { Config::clash().latest().clone() };
|
||||
|
||||
let tun_mode = { Config::verge().latest().enable_tun_mode.clone() };
|
||||
let tun_mode = tun_mode.unwrap_or(false);
|
||||
|
||||
let pa = { Config::profiles().latest().gen_activate()? };
|
||||
|
||||
let (config, exists_keys, logs) =
|
||||
enhance::enhance_config(clash_config.0, pa.current, pa.chain, pa.valid, tun_mode);
|
||||
|
||||
// 保存到文件中
|
||||
let runtime_path = dirs::clash_runtime_yaml()?;
|
||||
utils::config::save_yaml(runtime_path, &config, Some("# Clash Verge Runtime Config"))?;
|
||||
/// 更新proxies那些
|
||||
/// 如果涉及端口和外部控制则需要重启
|
||||
pub async fn update_config(&self) -> Result<()> {
|
||||
// 更新配置
|
||||
Config::generate()?;
|
||||
|
||||
// 检查配置是否正常
|
||||
self.check_config()?;
|
||||
|
||||
// 更新运行时配置
|
||||
let path = Config::generate_file(ConfigType::Run)?;
|
||||
let path = dirs::path_to_str(&path)?;
|
||||
|
||||
// 发送请求 发送5次
|
||||
for i in 0..5 {
|
||||
match clash_api::put_configs().await {
|
||||
match clash_api::put_configs(path).await {
|
||||
Ok(_) => break,
|
||||
Err(err) => {
|
||||
if i < 4 {
|
||||
|
@ -258,16 +241,6 @@ impl CoreManager {
|
|||
sleep(Duration::from_millis(250)).await;
|
||||
}
|
||||
|
||||
// 保存结果
|
||||
let mut runtime = self.runtime_config.lock();
|
||||
let config_yaml = Some(serde_yaml::to_string(&config).unwrap_or("".into()));
|
||||
*runtime = RuntimeResult {
|
||||
config: Some(config),
|
||||
config_yaml,
|
||||
exists_keys,
|
||||
chain_logs: logs,
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,9 +43,6 @@ impl Timer {
|
|||
Config::profiles().latest().get_items().map(|items| {
|
||||
items
|
||||
.iter()
|
||||
// .filter_map(|item| {
|
||||
// item.uid.is_some() && item.updated.is_some() && item.option.is_some()
|
||||
// })
|
||||
.filter_map(|item| {
|
||||
// mins to seconds
|
||||
let interval = ((item.option.as_ref()?.update_interval?) as i64) * 60;
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
//!
|
||||
//! feat mod 里的函数主要用于
|
||||
//! - hotkey 快捷键
|
||||
//! - timer 定时器
|
||||
//! - cmds 页面调用
|
||||
//!
|
||||
use crate::config::*;
|
||||
use crate::core::*;
|
||||
use crate::log_err;
|
||||
|
@ -8,8 +14,14 @@ use serde_yaml::{Mapping, Value};
|
|||
pub fn restart_clash_core() {
|
||||
tauri::async_runtime::spawn(async {
|
||||
match CoreManager::global().run_core().await {
|
||||
Ok(_) => log_err!(handle_activate().await),
|
||||
Err(err) => log::error!(target: "app", "{err}"),
|
||||
Ok(_) => {
|
||||
handle::Handle::refresh_clash();
|
||||
handle::Handle::notice_message("set_config::ok", "ok");
|
||||
}
|
||||
Err(err) => {
|
||||
handle::Handle::notice_message("set_config::error", format!("{err}"));
|
||||
log::error!(target:"app", "{err}");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -157,7 +169,7 @@ pub async fn patch_clash(patch: Mapping) -> Result<()> {
|
|||
|| patch.get("secret").is_some()
|
||||
|| patch.get("external-controller").is_some()
|
||||
{
|
||||
handle_activate().await?;
|
||||
CoreManager::global().run_core().await?;
|
||||
}
|
||||
|
||||
// 更新系统代理
|
||||
|
@ -196,10 +208,12 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> {
|
|||
|
||||
match {
|
||||
#[cfg(target_os = "windows")]
|
||||
{}
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
if tun_mode.is_some() {
|
||||
handle_activate().await?;
|
||||
update_core_config().await?;
|
||||
}
|
||||
|
||||
if auto_launch.is_some() {
|
||||
|
@ -238,21 +252,6 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> {
|
|||
}
|
||||
}
|
||||
|
||||
/// 激活配置
|
||||
pub async fn handle_activate() -> Result<()> {
|
||||
match CoreManager::global().activate_config().await {
|
||||
Ok(_) => {
|
||||
handle::Handle::refresh_clash();
|
||||
handle::Handle::notice_message("set_config::ok", "ok");
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
handle::Handle::notice_message("set_config::error", format!("{err}"));
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 更新某个profile
|
||||
/// 如果更新当前配置就激活配置
|
||||
pub async fn update_profile(uid: String, option: Option<PrfOption>) -> Result<()> {
|
||||
|
@ -286,8 +285,23 @@ pub async fn update_profile(uid: String, option: Option<PrfOption>) -> Result<()
|
|||
};
|
||||
|
||||
if should_update {
|
||||
handle_activate().await?;
|
||||
update_core_config().await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 更新配置
|
||||
async fn update_core_config() -> Result<()> {
|
||||
match CoreManager::global().update_config().await {
|
||||
Ok(_) => {
|
||||
handle::Handle::refresh_clash();
|
||||
handle::Handle::notice_message("set_config::ok", "ok");
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
handle::Handle::notice_message("set_config::error", format!("{err}"));
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,17 +49,15 @@ fn main() -> std::io::Result<()> {
|
|||
cmds::patch_verge_config,
|
||||
// cmds::update_hotkeys,
|
||||
// profile
|
||||
cmds::get_profiles,
|
||||
cmds::enhance_profiles,
|
||||
cmds::patch_profiles_config,
|
||||
cmds::view_profile,
|
||||
cmds::patch_profile,
|
||||
cmds::create_profile,
|
||||
cmds::import_profile,
|
||||
cmds::update_profile,
|
||||
cmds::delete_profile,
|
||||
cmds::select_profile,
|
||||
cmds::get_profiles,
|
||||
cmds::enhance_profiles,
|
||||
cmds::change_profile_chain,
|
||||
cmds::change_profile_valid,
|
||||
cmds::read_profile_file,
|
||||
cmds::save_profile_file,
|
||||
// service mode
|
||||
|
@ -92,13 +90,6 @@ fn main() -> std::io::Result<()> {
|
|||
.build(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
// let app_handle = app.app_handle();
|
||||
// ctrlc::set_handler(move || {
|
||||
// resolve::resolve_reset();
|
||||
// app_handle.exit(0);
|
||||
// })
|
||||
// .expect("error while exiting.");
|
||||
|
||||
app.run(|app_handle, e| match e {
|
||||
tauri::RunEvent::ExitRequested { api, .. } => {
|
||||
api.prevent_exit();
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
/// read data from yaml as struct T
|
||||
pub fn read_yaml<T: DeserializeOwned>(path: &PathBuf) -> Result<T> {
|
||||
if !path.exists() {
|
||||
bail!("file not found \"{}\"", path.display());
|
||||
}
|
||||
|
||||
let yaml_str = fs::read_to_string(&path)
|
||||
.context(format!("failed to read the file \"{}\"", path.display()))?;
|
||||
|
||||
serde_yaml::from_str::<T>(&yaml_str).context(format!(
|
||||
"failed to read the file with yaml format \"{}\"",
|
||||
path.display()
|
||||
))
|
||||
}
|
||||
|
||||
/// read mapping from yaml fix #165
|
||||
pub fn read_merge_mapping(path: &PathBuf) -> Result<Mapping> {
|
||||
let mut val: Value = read_yaml(path)?;
|
||||
val.apply_merge()
|
||||
.context(format!("failed to apply merge \"{}\"", path.display()))?;
|
||||
|
||||
Ok(val
|
||||
.as_mapping()
|
||||
.ok_or(anyhow!(
|
||||
"failed to transform to yaml mapping \"{}\"",
|
||||
path.display()
|
||||
))?
|
||||
.to_owned())
|
||||
}
|
||||
|
||||
/// save the data to the file
|
||||
/// can set `prefix` string to add some comments
|
||||
pub fn save_yaml<T: Serialize>(path: PathBuf, data: &T, prefix: Option<&str>) -> Result<()> {
|
||||
let data_str = serde_yaml::to_string(data)?;
|
||||
|
||||
let yaml_str = match prefix {
|
||||
Some(prefix) => format!("{prefix}\n{data_str}"),
|
||||
None => data_str,
|
||||
};
|
||||
|
||||
let path_str = path.as_os_str().to_string_lossy().to_string();
|
||||
fs::write(path, yaml_str.as_bytes()).context(format!("failed to save file \"{path_str}\""))
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
use anyhow::Result;
|
||||
use std::{env::temp_dir, path::PathBuf};
|
||||
use std::path::PathBuf;
|
||||
use tauri::{
|
||||
api::path::{home_dir, resource_dir},
|
||||
Env, PackageInfo,
|
||||
|
@ -107,14 +107,6 @@ pub fn profiles_path() -> Result<PathBuf> {
|
|||
Ok(app_home_dir()?.join(PROFILE_YAML))
|
||||
}
|
||||
|
||||
pub fn clash_runtime_yaml() -> Result<PathBuf> {
|
||||
Ok(app_home_dir()?.join("clash-verge-runtime.yaml"))
|
||||
}
|
||||
|
||||
pub fn clash_check_yaml() -> Result<PathBuf> {
|
||||
Ok(temp_dir().join("clash-verge-check.yaml"))
|
||||
}
|
||||
|
||||
pub fn app_res_dir() -> Result<PathBuf> {
|
||||
unsafe {
|
||||
Ok(RESOURCE_DIR
|
||||
|
|
|
@ -1,8 +1,52 @@
|
|||
use anyhow::Result;
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use nanoid::nanoid;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use std::{fs, path::PathBuf, process::Command, str::FromStr};
|
||||
|
||||
/// read data from yaml as struct T
|
||||
pub fn read_yaml<T: DeserializeOwned>(path: &PathBuf) -> Result<T> {
|
||||
if !path.exists() {
|
||||
bail!("file not found \"{}\"", path.display());
|
||||
}
|
||||
|
||||
let yaml_str = fs::read_to_string(&path)
|
||||
.context(format!("failed to read the file \"{}\"", path.display()))?;
|
||||
|
||||
serde_yaml::from_str::<T>(&yaml_str).context(format!(
|
||||
"failed to read the file with yaml format \"{}\"",
|
||||
path.display()
|
||||
))
|
||||
}
|
||||
|
||||
/// read mapping from yaml fix #165
|
||||
pub fn read_merge_mapping(path: &PathBuf) -> Result<Mapping> {
|
||||
let mut val: Value = read_yaml(path)?;
|
||||
val.apply_merge()
|
||||
.context(format!("failed to apply merge \"{}\"", path.display()))?;
|
||||
|
||||
Ok(val
|
||||
.as_mapping()
|
||||
.ok_or(anyhow!(
|
||||
"failed to transform to yaml mapping \"{}\"",
|
||||
path.display()
|
||||
))?
|
||||
.to_owned())
|
||||
}
|
||||
|
||||
/// save the data to the file
|
||||
/// can set `prefix` string to add some comments
|
||||
pub fn save_yaml<T: Serialize>(path: &PathBuf, data: &T, prefix: Option<&str>) -> Result<()> {
|
||||
let data_str = serde_yaml::to_string(data)?;
|
||||
|
||||
let yaml_str = match prefix {
|
||||
Some(prefix) => format!("{prefix}\n\n{data_str}"),
|
||||
None => data_str,
|
||||
};
|
||||
|
||||
let path_str = path.as_os_str().to_string_lossy().to_string();
|
||||
fs::write(path, yaml_str.as_bytes()).context(format!("failed to save file \"{path_str}\""))
|
||||
}
|
||||
|
||||
const ALPHABET: [char; 62] = [
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
|
||||
|
@ -68,16 +112,6 @@ macro_rules! error {
|
|||
};
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[macro_export]
|
||||
macro_rules! log_if_err {
|
||||
($result: expr) => {
|
||||
if let Err(err) = $result {
|
||||
log::error!(target: "app", "{err}");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! log_err {
|
||||
($result: expr) => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::utils::{dirs, tmpl};
|
||||
use crate::utils::dirs;
|
||||
use anyhow::Result;
|
||||
use chrono::Local;
|
||||
use log::LevelFilter;
|
||||
|
@ -7,7 +7,6 @@ use log4rs::append::file::FileAppender;
|
|||
use log4rs::config::{Appender, Config, Logger, Root};
|
||||
use log4rs::encode::pattern::PatternEncoder;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use tauri::PackageInfo;
|
||||
|
||||
/// initialize this instance's log file
|
||||
|
@ -21,13 +20,20 @@ fn init_log() -> Result<()> {
|
|||
let log_file = format!("{}.log", local_time);
|
||||
let log_file = log_dir.join(log_file);
|
||||
|
||||
#[cfg(feature = "verge-dev")]
|
||||
let time_format = "{d(%Y-%m-%d %H:%M:%S)} {l} - {M} {m}{n}";
|
||||
#[cfg(not(feature = "verge-dev"))]
|
||||
let time_format = "{d(%Y-%m-%d %H:%M:%S)} {l} - {m}{n}";
|
||||
let stdout = ConsoleAppender::builder()
|
||||
.encoder(Box::new(PatternEncoder::new(time_format)))
|
||||
.build();
|
||||
let tofile = FileAppender::builder()
|
||||
.encoder(Box::new(PatternEncoder::new(time_format)))
|
||||
.build(log_file)?;
|
||||
|
||||
let encode = Box::new(PatternEncoder::new(time_format));
|
||||
|
||||
let stdout = ConsoleAppender::builder().encoder(encode.clone()).build();
|
||||
let tofile = FileAppender::builder().encoder(encode).build(log_file)?;
|
||||
|
||||
#[cfg(feature = "verge-dev")]
|
||||
let level = LevelFilter::Debug;
|
||||
#[cfg(not(feature = "verge-dev"))]
|
||||
let level = LevelFilter::Info;
|
||||
|
||||
let config = Config::builder()
|
||||
.appender(Appender::builder().build("stdout", Box::new(stdout)))
|
||||
|
@ -36,9 +42,9 @@ fn init_log() -> Result<()> {
|
|||
Logger::builder()
|
||||
.appenders(["file", "stdout"])
|
||||
.additive(false)
|
||||
.build("app", LevelFilter::Info),
|
||||
.build("app", level),
|
||||
)
|
||||
.build(Root::builder().appender("stdout").build(LevelFilter::Info))?;
|
||||
.build(Root::builder().appender("stdout").build(level))?;
|
||||
|
||||
log4rs::init_config(config)?;
|
||||
|
||||
|
@ -58,21 +64,6 @@ pub fn init_config() -> Result<()> {
|
|||
if !app_dir.exists() {
|
||||
let _ = fs::create_dir_all(&app_dir);
|
||||
}
|
||||
|
||||
// // target path
|
||||
// let clash_path = app_dir.join("config.yaml");
|
||||
// let verge_path = app_dir.join("verge.yaml");
|
||||
// let profile_path = app_dir.join("profiles.yaml");
|
||||
|
||||
// if !clash_path.exists() {
|
||||
// fs::File::create(clash_path)?.write(tmpl::CLASH_CONFIG)?;
|
||||
// }
|
||||
// if !verge_path.exists() {
|
||||
// fs::File::create(verge_path)?.write(tmpl::VERGE_CONFIG)?;
|
||||
// }
|
||||
// if !profile_path.exists() {
|
||||
// fs::File::create(profile_path)?.write(tmpl::PROFILES_CONFIG)?;
|
||||
// }
|
||||
});
|
||||
|
||||
let _ = dirs::app_profiles_dir().map(|profiles_dir| {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
pub mod config;
|
||||
pub mod dirs;
|
||||
pub mod help;
|
||||
pub mod init;
|
||||
|
|
|
@ -10,9 +10,10 @@ pub fn resolve_setup(app: &mut App) {
|
|||
|
||||
handle::Handle::global().init(app.app_handle());
|
||||
|
||||
init::init_resources(app.package_info());
|
||||
log_err!(init::init_resources(app.package_info()));
|
||||
|
||||
// 启动核心
|
||||
log_err!(Config::init_config());
|
||||
log_err!(CoreManager::global().init());
|
||||
|
||||
// setup a simple http server for singleton
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
getProfiles,
|
||||
deleteProfile,
|
||||
enhanceProfiles,
|
||||
changeProfileChain,
|
||||
patchProfilesConfig,
|
||||
getRuntimeLogs,
|
||||
} from "@/services/cmds";
|
||||
import ProfileMore from "./profile-more";
|
||||
|
@ -43,7 +43,7 @@ const EnhancedMode = (props: Props) => {
|
|||
if (chain.includes(uid)) return;
|
||||
|
||||
const newChain = [...chain, uid];
|
||||
await changeProfileChain(newChain);
|
||||
await patchProfilesConfig({ chain: newChain });
|
||||
mutateProfiles((conf = {}) => ({ ...conf, chain: newChain }), true);
|
||||
mutateLogs();
|
||||
});
|
||||
|
@ -52,7 +52,7 @@ const EnhancedMode = (props: Props) => {
|
|||
if (!chain.includes(uid)) return;
|
||||
|
||||
const newChain = chain.filter((i) => i !== uid);
|
||||
await changeProfileChain(newChain);
|
||||
await patchProfilesConfig({ chain: newChain });
|
||||
mutateProfiles((conf = {}) => ({ ...conf, chain: newChain }), true);
|
||||
mutateLogs();
|
||||
});
|
||||
|
@ -72,7 +72,7 @@ const EnhancedMode = (props: Props) => {
|
|||
if (!chain.includes(uid)) return;
|
||||
|
||||
const newChain = [uid].concat(chain.filter((i) => i !== uid));
|
||||
await changeProfileChain(newChain);
|
||||
await patchProfilesConfig({ chain: newChain });
|
||||
mutateProfiles((conf = {}) => ({ ...conf, chain: newChain }), true);
|
||||
mutateLogs();
|
||||
});
|
||||
|
@ -81,7 +81,7 @@ const EnhancedMode = (props: Props) => {
|
|||
if (!chain.includes(uid)) return;
|
||||
|
||||
const newChain = chain.filter((i) => i !== uid).concat([uid]);
|
||||
await changeProfileChain(newChain);
|
||||
await patchProfilesConfig({ chain: newChain });
|
||||
mutateProfiles((conf = {}) => ({ ...conf, chain: newChain }), true);
|
||||
mutateLogs();
|
||||
});
|
||||
|
|
|
@ -15,9 +15,9 @@ import {
|
|||
} from "@mui/material";
|
||||
import { InfoRounded } from "@mui/icons-material";
|
||||
import {
|
||||
changeProfileValid,
|
||||
getProfiles,
|
||||
getRuntimeExists,
|
||||
patchProfilesConfig,
|
||||
} from "@/services/cmds";
|
||||
import { ModalHandler } from "@/hooks/use-modal-handler";
|
||||
import {
|
||||
|
@ -91,7 +91,7 @@ const ClashFieldViewer = ({ handler }: Props) => {
|
|||
if (curSet.size === oldSet.size && curSet.size === joinSet.size) return;
|
||||
|
||||
try {
|
||||
await changeProfileValid([...curSet]);
|
||||
await patchProfilesConfig({ valid: [...curSet] });
|
||||
mutateProfile();
|
||||
// Notice.success("Refresh clash config", 1000);
|
||||
} catch (err: any) {
|
||||
|
|
|
@ -7,7 +7,7 @@ import { useTranslation } from "react-i18next";
|
|||
import {
|
||||
getProfiles,
|
||||
patchProfile,
|
||||
selectProfile,
|
||||
patchProfilesConfig,
|
||||
importProfile,
|
||||
} from "@/services/cmds";
|
||||
import { getProxies, updateProxy } from "@/services/api";
|
||||
|
@ -113,7 +113,7 @@ const ProfilePage = () => {
|
|||
|
||||
if (!newProfiles.current && remoteItem) {
|
||||
const current = remoteItem.uid;
|
||||
selectProfile(current);
|
||||
patchProfilesConfig({ current });
|
||||
mutate("getProfiles", { ...newProfiles, current }, true);
|
||||
mutate("getRuntimeLogs");
|
||||
}
|
||||
|
@ -125,13 +125,13 @@ const ProfilePage = () => {
|
|||
}
|
||||
};
|
||||
|
||||
const onSelect = useLockFn(async (uid: string, force: boolean) => {
|
||||
if (!force && uid === profiles.current) return;
|
||||
const onSelect = useLockFn(async (current: string, force: boolean) => {
|
||||
if (!force && current === profiles.current) return;
|
||||
|
||||
try {
|
||||
await selectProfile(uid);
|
||||
setCurrentProfile(uid);
|
||||
mutate("getProfiles", { ...profiles, current: uid }, true);
|
||||
await patchProfilesConfig({ current });
|
||||
setCurrentProfile(current);
|
||||
mutate("getProfiles", { ...profiles, current: current }, true);
|
||||
mutate("getRuntimeLogs");
|
||||
// if (force) Notice.success("Refresh clash config", 1000);
|
||||
} catch (err: any) {
|
||||
|
|
|
@ -32,6 +32,10 @@ export async function enhanceProfiles() {
|
|||
return invoke<void>("enhance_profiles");
|
||||
}
|
||||
|
||||
export async function patchProfilesConfig(profiles: CmdType.ProfilesConfig) {
|
||||
return invoke<void>("patch_profiles_config");
|
||||
}
|
||||
|
||||
export async function createProfile(
|
||||
item: Partial<CmdType.ProfileItem>,
|
||||
fileData?: string | null
|
||||
|
@ -76,18 +80,6 @@ export async function patchProfile(
|
|||
return invoke<void>("patch_profile", { index, profile });
|
||||
}
|
||||
|
||||
export async function selectProfile(index: string) {
|
||||
return invoke<void>("select_profile", { index });
|
||||
}
|
||||
|
||||
export async function changeProfileChain(chain?: string[]) {
|
||||
return invoke<void>("change_profile_chain", { chain });
|
||||
}
|
||||
|
||||
export async function changeProfileValid(valid?: string[]) {
|
||||
return invoke<void>("change_profile_valid", { valid });
|
||||
}
|
||||
|
||||
export async function getClashInfo() {
|
||||
return invoke<CmdType.ClashInfo | null>("get_clash_info");
|
||||
}
|
||||
|
@ -136,10 +128,6 @@ export async function restartSidecar() {
|
|||
return invoke<void>("restart_sidecar");
|
||||
}
|
||||
|
||||
// export async function killSidecar() {
|
||||
// return invoke<any>("kill_sidecar");
|
||||
// }
|
||||
|
||||
export async function openAppDir() {
|
||||
return invoke<void>("open_app_dir").catch((err) =>
|
||||
Notice.error(err?.message || err.toString(), 1500)
|
||||
|
|
Loading…
Reference in New Issue
Block a user