feat: windows support startup

This commit is contained in:
GyDi 2022-01-11 02:24:43 +08:00
parent 79aad6b5c2
commit 6113898b69
6 changed files with 111 additions and 56 deletions

View File

@ -193,24 +193,7 @@ pub fn patch_clash_config(payload: Mapping) -> Result<(), String> {
save_clash(&config) save_clash(&config)
} }
/// set the system proxy
/// Tips: only support windows now
#[tauri::command]
pub fn set_sys_proxy(enable: bool, verge_state: State<'_, VergeState>) -> Result<(), String> {
let mut verge = verge_state.0.lock().unwrap();
if let Some(mut sysproxy) = verge.cur_sysproxy.take() {
sysproxy.enable = enable;
if sysproxy.set_sys().is_err() {
log::error!("failed to set system proxy");
}
verge.cur_sysproxy = Some(sysproxy);
}
Ok(())
}
/// get the system proxy /// get the system proxy
/// Tips: only support windows now
#[tauri::command] #[tauri::command]
pub fn get_sys_proxy() -> Result<SysProxyConfig, String> { pub fn get_sys_proxy() -> Result<SysProxyConfig, String> {
match SysProxyConfig::get_sys() { match SysProxyConfig::get_sys() {
@ -219,6 +202,8 @@ pub fn get_sys_proxy() -> Result<SysProxyConfig, String> {
} }
} }
/// get the current proxy config
/// which may not the same as system proxy
#[tauri::command] #[tauri::command]
pub fn get_cur_proxy(verge_state: State<'_, VergeState>) -> Result<Option<SysProxyConfig>, String> { pub fn get_cur_proxy(verge_state: State<'_, VergeState>) -> Result<Option<SysProxyConfig>, String> {
match verge_state.0.lock() { match verge_state.0.lock() {
@ -244,24 +229,7 @@ pub async fn patch_verge_config(
verge_state: State<'_, VergeState>, verge_state: State<'_, VergeState>,
) -> Result<(), String> { ) -> Result<(), String> {
let mut verge = verge_state.0.lock().unwrap(); let mut verge = verge_state.0.lock().unwrap();
verge.patch_config(payload)
if payload.theme_mode.is_some() {
verge.config.theme_mode = payload.theme_mode;
}
if payload.enable_self_startup.is_some() {
verge.config.enable_self_startup = payload.enable_self_startup;
}
if payload.enable_system_proxy.is_some() {
verge.config.enable_system_proxy = payload.enable_system_proxy;
}
if payload.system_proxy_bypass.is_some() {
verge.config.system_proxy_bypass = payload.system_proxy_bypass;
}
verge.config.save_file()
} }
/// start dragging window /// start dragging window

View File

@ -1,5 +1,7 @@
use crate::utils::{config, dirs, sysopt::SysProxyConfig}; use crate::utils::{config, dirs, startup, sysopt::SysProxyConfig};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use tauri::api::path::resource_dir;
/// ### `verge.yaml` schema /// ### `verge.yaml` schema
#[derive(Default, Debug, Clone, Deserialize, Serialize)] #[derive(Default, Debug, Clone, Deserialize, Serialize)]
@ -34,6 +36,7 @@ impl VergeConfig {
} }
} }
/// Verge App abilities
#[derive(Debug)] #[derive(Debug)]
pub struct Verge { pub struct Verge {
pub config: VergeConfig, pub config: VergeConfig,
@ -41,6 +44,8 @@ pub struct Verge {
pub old_sysproxy: Option<SysProxyConfig>, pub old_sysproxy: Option<SysProxyConfig>,
pub cur_sysproxy: Option<SysProxyConfig>, pub cur_sysproxy: Option<SysProxyConfig>,
pub exe_path: Option<PathBuf>,
} }
impl Default for Verge { impl Default for Verge {
@ -55,6 +60,7 @@ impl Verge {
config: VergeConfig::new(), config: VergeConfig::new(),
old_sysproxy: None, old_sysproxy: None,
cur_sysproxy: None, cur_sysproxy: None,
exe_path: None,
} }
} }
@ -90,4 +96,95 @@ impl Verge {
} }
} }
} }
/// set the exe_path
pub fn set_exe_path(&mut self, package_info: &tauri::PackageInfo) {
let exe = if cfg!(target_os = "windows") {
"clash-verge.exe"
} else {
"clash-verge"
};
let path = resource_dir(package_info).unwrap().join(exe);
self.exe_path = Some(path);
}
/// sync the startup when run the app
pub fn sync_startup(&self) -> Result<(), String> {
let enable = self.config.enable_self_startup.clone().unwrap_or(false);
if !enable {
return Ok(());
}
if self.exe_path.is_none() {
return Err("should init the exe_path first".into());
}
let exe_path = self.exe_path.clone().unwrap();
match startup::get_startup(&exe_path) {
Ok(sys_enable) => {
if sys_enable || (!sys_enable && startup::set_startup(true, &exe_path).is_ok()) {
Ok(())
} else {
Err("failed to sync startup".into())
}
}
Err(_) => Err("failed to get system startup info".into()),
}
}
/// update the startup
fn update_startup(&mut self, enable: bool) -> Result<(), String> {
let conf_enable = self.config.enable_self_startup.clone().unwrap_or(false);
if enable == conf_enable {
return Ok(());
}
if self.exe_path.is_none() {
return Err("should init the exe_path first".into());
}
let exe_path = self.exe_path.clone().unwrap();
match startup::set_startup(enable, &exe_path) {
Ok(_) => Ok(()),
Err(_) => Err("failed to set system startup info".into()),
}
}
/// patch verge config
/// There should be only one update at a time here
/// so call the save_file at the end is savely
pub fn patch_config(&mut self, patch: VergeConfig) -> Result<(), String> {
// only change it
if patch.theme_mode.is_some() {
self.config.theme_mode = patch.theme_mode;
}
// should update system startup
if patch.enable_self_startup.is_some() {
let enable = patch.enable_self_startup.unwrap();
self.update_startup(enable)?;
self.config.enable_self_startup = Some(enable);
}
// should update system proxy
if patch.enable_system_proxy.is_some() {
let enable = patch.enable_system_proxy.unwrap();
if let Some(mut sysproxy) = self.cur_sysproxy.take() {
sysproxy.enable = enable;
if sysproxy.set_sys().is_err() {
log::error!("failed to set system proxy");
return Err("failed to set system proxy".into());
}
self.cur_sysproxy = Some(sysproxy);
}
self.config.enable_system_proxy = Some(enable);
}
// todo
// should update system proxt too
if patch.system_proxy_bypass.is_some() {
self.config.system_proxy_bypass = patch.system_proxy_bypass;
}
self.config.save_file()
}
} }

View File

@ -71,7 +71,6 @@ fn main() -> std::io::Result<()> {
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
// common // common
cmds::restart_sidecar, cmds::restart_sidecar,
cmds::set_sys_proxy,
cmds::get_sys_proxy, cmds::get_sys_proxy,
cmds::get_cur_proxy, cmds::get_cur_proxy,
cmds::win_drag, cmds::win_drag,

View File

@ -33,7 +33,11 @@ pub fn resolve_setup(app: &App) {
log::error!("{}", err); log::error!("{}", err);
} }
verge.set_exe_path(app.package_info());
verge.init_sysproxy(clash.info.port.clone()); verge.init_sysproxy(clash.info.port.clone());
if let Err(err) = verge.sync_startup() {
log::error!("{}", err);
}
} }
/// reset system proxy /// reset system proxy

View File

@ -6,11 +6,7 @@ import {
Switch, Switch,
Typography, Typography,
} from "@mui/material"; } from "@mui/material";
import { import { getVergeConfig, patchVergeConfig } from "../services/cmds";
setSysProxy,
getVergeConfig,
patchVergeConfig,
} from "../services/cmds";
import { CmdType } from "../services/types"; import { CmdType } from "../services/types";
import { version } from "../../package.json"; import { version } from "../../package.json";
import GuardState from "./guard-state"; import GuardState from "./guard-state";
@ -50,9 +46,9 @@ const SettingVerge = ({ onError }: Props) => {
onCatch={onError} onCatch={onError}
onFormat={onSwitchFormat} onFormat={onSwitchFormat}
onChange={(e) => onChangeData({ theme_mode: e ? "dark" : "light" })} onChange={(e) => onChangeData({ theme_mode: e ? "dark" : "light" })}
onGuard={async (c) => { onGuard={(c) =>
await patchVergeConfig({ theme_mode: c ? "dark" : "light" }); patchVergeConfig({ theme_mode: c ? "dark" : "light" })
}} }
> >
<PaletteSwitch edge="end" /> <PaletteSwitch edge="end" />
</GuardState> </GuardState>
@ -66,9 +62,7 @@ const SettingVerge = ({ onError }: Props) => {
onCatch={onError} onCatch={onError}
onFormat={onSwitchFormat} onFormat={onSwitchFormat}
onChange={(e) => onChangeData({ enable_self_startup: e })} onChange={(e) => onChangeData({ enable_self_startup: e })}
onGuard={async (e) => { onGuard={(e) => patchVergeConfig({ enable_self_startup: e })}
await patchVergeConfig({ enable_self_startup: e });
}}
> >
<Switch edge="end" /> <Switch edge="end" />
</GuardState> </GuardState>
@ -82,10 +76,7 @@ const SettingVerge = ({ onError }: Props) => {
onCatch={onError} onCatch={onError}
onFormat={onSwitchFormat} onFormat={onSwitchFormat}
onChange={(e) => onChangeData({ enable_system_proxy: e })} onChange={(e) => onChangeData({ enable_system_proxy: e })}
onGuard={async (e) => { onGuard={(e) => patchVergeConfig({ enable_system_proxy: e })}
await setSysProxy(e);
await patchVergeConfig({ enable_system_proxy: e });
}}
> >
<Switch edge="end" /> <Switch edge="end" />
</GuardState> </GuardState>

View File

@ -56,10 +56,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 setSysProxy(enable: boolean) {
return invoke<void>("set_sys_proxy", { enable });
}
export async function getVergeConfig() { export async function getVergeConfig() {
return invoke<CmdType.VergeConfig>("get_verge_config"); return invoke<CmdType.VergeConfig>("get_verge_config");
} }