feat: enhanced profile (wip)

This commit is contained in:
GyDi 2022-03-03 01:52:02 +08:00
parent 808b861dd1
commit f260d5df49
No known key found for this signature in database
GPG Key ID: 1C95E0D3467B3084
3 changed files with 119 additions and 13 deletions

View File

@ -1,12 +1,12 @@
use std::collections::HashMap;
use super::{Profiles, Verge};
use crate::utils::{config, dirs};
use crate::utils::{config, dirs, help};
use anyhow::{bail, Result};
use reqwest::header::HeaderMap;
use serde::{Deserialize, Serialize};
use serde_yaml::{Mapping, Value};
use std::{collections::HashMap, time::Duration};
use tauri::api::process::{Command, CommandChild, CommandEvent};
use tokio::time::sleep;
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct ClashInfo {
@ -241,17 +241,8 @@ impl Clash {
self.save_config()
}
/// activate the profile
pub fn activate(&self, profiles: &Profiles) -> Result<()> {
fn _activate(info: ClashInfo, config: Mapping) -> Result<()> {
let temp_path = dirs::profiles_temp_path();
let info = self.info.clone();
let mut config = self.config.clone();
let gen_config = profiles.gen_activate()?;
for (key, value) in gen_config.into_iter() {
config.insert(key, value);
}
config::save_yaml(temp_path.clone(), &config, Some("# Clash Verge Temp File"))?;
tauri::async_runtime::spawn(async move {
@ -288,6 +279,49 @@ impl Clash {
Ok(())
}
/// activate the profile
pub fn activate(&self, profiles: &Profiles) -> Result<()> {
let info = self.info.clone();
let mut config = self.config.clone();
let gen_map = profiles.gen_activate()?;
for (key, value) in gen_map.into_iter() {
config.insert(key, value);
}
Self::_activate(info, config)
}
/// enhanced profiles mode
pub fn activate_enhanced(&self, profiles: &Profiles, win: tauri::Window) -> Result<()> {
let event_name = help::get_uid("e");
let event_name = format!("script-cb-{event_name}");
let info = self.info.clone();
let mut config = self.config.clone();
win.once(&event_name, move |event| {
if let Some(result) = event.payload() {
let gen_map: Mapping = serde_json::from_str(result).unwrap();
for (key, value) in gen_map.into_iter() {
config.insert(key, value);
}
Self::_activate(info, config).unwrap();
}
});
// generate the payload
let payload = profiles.gen_enhanced();
tauri::async_runtime::spawn(async move {
sleep(Duration::from_secs(5)).await;
win.emit("script-handler", payload).unwrap();
});
Ok(())
}
}
impl Default for Clash {

View File

@ -436,4 +436,72 @@ impl Profiles {
bail!("failed to found the uid \"{current}\"");
}
/// gen the enhanced profiles
pub fn gen_enhanced(&self) -> PrfEnhanced {
let current = self.gen_activate().unwrap();
let chain = match self.chain.as_ref() {
Some(chain) => chain
.iter()
.map(|uid| self.get_item(uid))
.filter(|item| item.is_ok())
.map(|item| item.unwrap())
.map(|item| PrfData::from_item(item))
.filter(|o| o.is_some())
.map(|o| o.unwrap())
.collect::<Vec<PrfData>>(),
None => vec![],
};
PrfEnhanced { current, chain }
}
}
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct PrfEnhanced {
current: Mapping,
chain: Vec<PrfData>,
}
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct PrfData {
item: PrfItem,
#[serde(skip_serializing_if = "Option::is_none")]
merge: Option<Mapping>,
#[serde(skip_serializing_if = "Option::is_none")]
script: Option<String>,
}
impl PrfData {
pub fn from_item(item: &PrfItem) -> Option<PrfData> {
match item.itype.as_ref() {
Some(itype) => {
let file = item.file.clone()?;
let path = dirs::app_profiles_dir().join(file);
if !path.exists() {
return None;
}
match itype.as_str() {
"script" => Some(PrfData {
item: item.clone(),
script: Some(fs::read_to_string(path).unwrap_or("".into())),
merge: None,
}),
"merge" => Some(PrfData {
item: item.clone(),
merge: Some(config::read_yaml::<Mapping>(path)),
script: None,
}),
_ => None,
}
}
None => None,
}
}
}

View File

@ -26,6 +26,10 @@ pub fn resolve_setup(app: &App) {
*profiles = Profiles::read_file();
log_if_err!(clash.activate(&profiles));
app
.get_window("main")
.map(|win| log_if_err!(clash.activate_enhanced(&profiles, win)));
verge.init_sysproxy(clash.info.port.clone());
// enable tun mode
if verge.config.enable_tun_mode.clone().unwrap_or(false)