feat: support restart sidecar tray event

This commit is contained in:
GyDi 2021-12-31 18:24:50 +08:00
parent 6b3e7cbc08
commit cb816e9653
5 changed files with 64 additions and 22 deletions

View File

@ -2,7 +2,7 @@ use crate::{
config::VergeConfig,
events::{
emit::ClashInfoPayload,
state::{ClashInfoState, VergeConfLock},
state::{ClashInfoState, ClashSidecarState, VergeConfLock},
},
utils::{
clash::run_clash_bin,
@ -11,13 +11,25 @@ use crate::{
},
};
use serde_yaml::Mapping;
use tauri::{api::process::kill_children, AppHandle, State};
use tauri::{AppHandle, State};
/// restart the sidecar
#[tauri::command]
pub fn restart_sidecar(app_handle: AppHandle, clash_info: State<'_, ClashInfoState>) {
kill_children();
let payload = run_clash_bin(&app_handle, |_| {});
pub fn restart_sidecar(
app_handle: AppHandle,
clash_info: State<'_, ClashInfoState>,
clash_sidecar: State<'_, ClashSidecarState>,
) {
{
let mut guard = clash_sidecar.0.lock().unwrap();
let sidecar = guard.take();
if sidecar.is_some() {
if let Err(err) = sidecar.unwrap().kill() {
log::error!("failed to restart clash for \"{}\"", err);
}
}
}
let payload = run_clash_bin(&app_handle);
if let Ok(mut arc) = clash_info.0.lock() {
*arc = payload;

View File

@ -1,7 +1,7 @@
use std::sync::{Arc, Mutex};
use super::emit::ClashInfoPayload;
use crate::{config::VergeConfig, utils::sysopt::SysProxyConfig};
use std::sync::{Arc, Mutex};
use tauri::api::process::CommandChild;
#[derive(Default)]
pub struct ClashInfoState(pub Arc<Mutex<ClashInfoPayload>>);
@ -14,3 +14,6 @@ pub struct VergeConfLock(pub Arc<Mutex<VergeConfig>>);
#[derive(Default)]
pub struct SomthingState(pub Arc<Mutex<Option<SysProxyConfig>>>);
#[derive(Default)]
pub struct ClashSidecarState(pub Arc<Mutex<Option<CommandChild>>>);

View File

@ -12,7 +12,7 @@ mod utils;
use crate::{
events::state,
utils::{resolve, server},
utils::{clash, resolve, server},
};
use tauri::{
api, CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
@ -26,10 +26,12 @@ fn main() -> std::io::Result<()> {
let menu = SystemTrayMenu::new()
.add_item(CustomMenuItem::new("open_window", "显示应用"))
.add_item(CustomMenuItem::new("restart_clash", "重启clash"))
.add_native_item(SystemTrayMenuItem::Separator)
.add_item(CustomMenuItem::new("quit", "退出").accelerator("CmdOrControl+Q"));
tauri::Builder::default()
.manage(state::ClashSidecarState::default())
.manage(state::VergeConfLock::default())
.manage(state::ClashInfoState::default())
.manage(state::SomthingState::default())
@ -43,6 +45,24 @@ fn main() -> std::io::Result<()> {
window.show().unwrap();
window.set_focus().unwrap();
}
"restart_clash" => {
{
let state = app_handle.state::<state::ClashSidecarState>();
let mut guard = state.0.lock().unwrap();
let sidecar = guard.take();
if sidecar.is_some() {
if let Err(err) = sidecar.unwrap().kill() {
log::error!("failed to restart clash for \"{}\"", err);
}
}
}
let payload = clash::run_clash_bin(&app_handle);
let state = app_handle.state::<state::ClashInfoState>();
if let Ok(mut arc) = state.0.lock() {
*arc = payload;
};
}
"quit" => {
api::process::kill_children();
resolve::resolve_reset(app_handle);

View File

@ -1,9 +1,12 @@
extern crate log;
use crate::{
events::emit::{clash_start, ClashInfoPayload},
events::{
emit::{clash_start, ClashInfoPayload},
state,
},
utils::{
app_home_dir,
app_home_dir, clash,
config::{read_clash_controller, read_profiles, read_yaml, save_yaml},
},
};
@ -12,11 +15,11 @@ use serde_yaml::{Mapping, Value};
use std::{collections::HashMap, env::temp_dir};
use tauri::{
api::process::{Command, CommandEvent},
AppHandle,
AppHandle, Manager,
};
/// Run the clash bin
pub fn run_clash_bin(app_handle: &AppHandle, cb: fn(info: ClashInfoPayload)) -> ClashInfoPayload {
pub fn run_clash_bin(app_handle: &AppHandle) -> ClashInfoPayload {
let app_dir = app_home_dir();
let app_dir = app_dir.as_os_str().to_str().unwrap();
@ -35,10 +38,21 @@ pub fn run_clash_bin(app_handle: &AppHandle, cb: fn(info: ClashInfoPayload)) ->
};
match result {
Ok((mut rx, _)) => {
Ok((mut rx, cmd_child)) => {
log::info!("Successfully execute clash sidecar");
payload.controller = Some(read_clash_controller());
cb(payload.clone()); // callback when run sidecar successfully
// update the profile
let payload_ = payload.clone();
tauri::async_runtime::spawn(async move {
if let Err(err) = clash::put_clash_profile(&payload_).await {
log::error!("failed to put config for `{}`", err);
};
});
if let Ok(mut state) = app_handle.state::<state::ClashSidecarState>().0.lock() {
*state = Some(cmd_child);
};
tauri::async_runtime::spawn(async move {
while let Some(event) = rx.recv().await {

View File

@ -11,14 +11,7 @@ pub fn resolve_setup(app: &App) {
init::init_app(app.package_info());
// run clash sidecar
let info = clash::run_clash_bin(&app.handle(), |info_| {
// update the profile
tauri::async_runtime::spawn(async move {
if let Err(err) = clash::put_clash_profile(&info_).await {
log::error!("failed to put config for `{}`", err);
};
});
});
let info = clash::run_clash_bin(&app.handle());
// resolve the verge config - enable system proxy
let mut original: Option<sysopt::SysProxyConfig> = None;