feat: system tray support zh language
This commit is contained in:
parent
b635e64803
commit
e11b4038a3
@ -1,7 +1,6 @@
|
|||||||
use crate::data::*;
|
use super::tray::Tray;
|
||||||
use crate::log_if_err;
|
use crate::log_if_err;
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use serde_yaml::Value;
|
|
||||||
use tauri::{AppHandle, Manager, Window};
|
use tauri::{AppHandle, Manager, Window};
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
@ -46,62 +45,22 @@ impl Handle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update system tray state (clash config)
|
|
||||||
pub fn update_systray_clash(&self) -> Result<()> {
|
|
||||||
if self.app_handle.is_none() {
|
|
||||||
bail!("update_systray_clash unhandle error");
|
|
||||||
}
|
|
||||||
|
|
||||||
let app_handle = self.app_handle.as_ref().unwrap();
|
|
||||||
|
|
||||||
let global = Data::global();
|
|
||||||
let clash = global.clash.lock();
|
|
||||||
let mode = clash
|
|
||||||
.config
|
|
||||||
.get(&Value::from("mode"))
|
|
||||||
.map(|val| val.as_str().unwrap_or("rule"))
|
|
||||||
.unwrap_or("rule");
|
|
||||||
|
|
||||||
let tray = app_handle.tray_handle();
|
|
||||||
|
|
||||||
tray.get_item("rule_mode").set_selected(mode == "rule")?;
|
|
||||||
tray
|
|
||||||
.get_item("global_mode")
|
|
||||||
.set_selected(mode == "global")?;
|
|
||||||
tray
|
|
||||||
.get_item("direct_mode")
|
|
||||||
.set_selected(mode == "direct")?;
|
|
||||||
tray
|
|
||||||
.get_item("script_mode")
|
|
||||||
.set_selected(mode == "script")?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// update the system tray state (verge config)
|
|
||||||
pub fn update_systray(&self) -> Result<()> {
|
pub fn update_systray(&self) -> Result<()> {
|
||||||
if self.app_handle.is_none() {
|
if self.app_handle.is_none() {
|
||||||
bail!("update_systray unhandle error");
|
bail!("update_systray unhandle error");
|
||||||
}
|
}
|
||||||
|
|
||||||
let app_handle = self.app_handle.as_ref().unwrap();
|
let app_handle = self.app_handle.as_ref().unwrap();
|
||||||
let tray = app_handle.tray_handle();
|
Tray::update_systray(app_handle)?;
|
||||||
|
Ok(())
|
||||||
let global = Data::global();
|
}
|
||||||
let verge = global.verge.lock();
|
|
||||||
let system_proxy = verge.enable_system_proxy.as_ref();
|
|
||||||
let tun_mode = verge.enable_tun_mode.as_ref();
|
|
||||||
|
|
||||||
tray
|
|
||||||
.get_item("system_proxy")
|
|
||||||
.set_selected(*system_proxy.unwrap_or(&false))?;
|
|
||||||
tray
|
|
||||||
.get_item("tun_mode")
|
|
||||||
.set_selected(*tun_mode.unwrap_or(&false))?;
|
|
||||||
|
|
||||||
// update verge config
|
|
||||||
self.refresh_verge();
|
|
||||||
|
|
||||||
|
/// update the system tray state
|
||||||
|
pub fn update_systray_part(&self) -> Result<()> {
|
||||||
|
if self.app_handle.is_none() {
|
||||||
|
bail!("update_systray unhandle error");
|
||||||
|
}
|
||||||
|
let app_handle = self.app_handle.as_ref().unwrap();
|
||||||
|
Tray::update_part(app_handle)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ mod hotkey;
|
|||||||
mod service;
|
mod service;
|
||||||
mod sysopt;
|
mod sysopt;
|
||||||
mod timer;
|
mod timer;
|
||||||
|
pub mod tray;
|
||||||
|
|
||||||
pub use self::service::*;
|
pub use self::service::*;
|
||||||
|
|
||||||
@ -64,8 +65,7 @@ impl Core {
|
|||||||
drop(sysopt);
|
drop(sysopt);
|
||||||
|
|
||||||
let handle = self.handle.lock();
|
let handle = self.handle.lock();
|
||||||
log_if_err!(handle.update_systray());
|
log_if_err!(handle.update_systray_part());
|
||||||
log_if_err!(handle.update_systray_clash());
|
|
||||||
drop(handle);
|
drop(handle);
|
||||||
|
|
||||||
let mut hotkey = self.hotkey.lock();
|
let mut hotkey = self.hotkey.lock();
|
||||||
@ -136,7 +136,7 @@ impl Core {
|
|||||||
|
|
||||||
if has_mode {
|
if has_mode {
|
||||||
let handle = self.handle.lock();
|
let handle = self.handle.lock();
|
||||||
handle.update_systray_clash()?;
|
handle.update_systray_part()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -155,6 +155,7 @@ impl Core {
|
|||||||
let system_proxy = patch.enable_system_proxy;
|
let system_proxy = patch.enable_system_proxy;
|
||||||
let proxy_bypass = patch.system_proxy_bypass;
|
let proxy_bypass = patch.system_proxy_bypass;
|
||||||
let proxy_guard = patch.enable_proxy_guard;
|
let proxy_guard = patch.enable_proxy_guard;
|
||||||
|
let language = patch.language;
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
@ -197,9 +198,13 @@ impl Core {
|
|||||||
sysopt.guard_proxy();
|
sysopt.guard_proxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
if system_proxy.is_some() || tun_mode.is_some() {
|
// 更新tray
|
||||||
|
if language.is_some() {
|
||||||
let handle = self.handle.lock();
|
let handle = self.handle.lock();
|
||||||
handle.update_systray()?;
|
handle.update_systray()?;
|
||||||
|
} else if system_proxy.is_some() || tun_mode.is_some() {
|
||||||
|
let handle = self.handle.lock();
|
||||||
|
handle.update_systray_part()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if patch.hotkeys.is_some() {
|
if patch.hotkeys.is_some() {
|
||||||
@ -232,7 +237,7 @@ impl Core {
|
|||||||
// update tray
|
// update tray
|
||||||
let handle = handle.lock();
|
let handle = handle.lock();
|
||||||
handle.refresh_clash();
|
handle.refresh_clash();
|
||||||
log_if_err!(handle.update_systray_clash());
|
log_if_err!(handle.update_systray_part());
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
109
src-tauri/src/core/tray.rs
Normal file
109
src-tauri/src/core/tray.rs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
use crate::{data::Data, feat, utils::resolve};
|
||||||
|
use anyhow::{Ok, Result};
|
||||||
|
use tauri::{
|
||||||
|
api, AppHandle, CustomMenuItem, Manager, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Tray {}
|
||||||
|
|
||||||
|
impl Tray {
|
||||||
|
pub fn tray_menu() -> SystemTrayMenu {
|
||||||
|
let data = Data::global();
|
||||||
|
let zh = {
|
||||||
|
let verge = data.verge.lock();
|
||||||
|
verge.language == Some("zh".into())
|
||||||
|
};
|
||||||
|
|
||||||
|
if zh {
|
||||||
|
SystemTrayMenu::new()
|
||||||
|
.add_item(CustomMenuItem::new("open_window", "打开面板"))
|
||||||
|
.add_native_item(SystemTrayMenuItem::Separator)
|
||||||
|
.add_item(CustomMenuItem::new("rule_mode", "规则模式"))
|
||||||
|
.add_item(CustomMenuItem::new("global_mode", "全局模式"))
|
||||||
|
.add_item(CustomMenuItem::new("direct_mode", "直连模式"))
|
||||||
|
.add_item(CustomMenuItem::new("script_mode", "脚本模式"))
|
||||||
|
.add_native_item(SystemTrayMenuItem::Separator)
|
||||||
|
.add_item(CustomMenuItem::new("system_proxy", "系统代理"))
|
||||||
|
.add_item(CustomMenuItem::new("tun_mode", "TUN 模式"))
|
||||||
|
.add_item(CustomMenuItem::new("restart_clash", "重启 Clash"))
|
||||||
|
.add_item(CustomMenuItem::new("restart_app", "重启应用"))
|
||||||
|
.add_native_item(SystemTrayMenuItem::Separator)
|
||||||
|
.add_item(CustomMenuItem::new("quit", "退出").accelerator("CmdOrControl+Q"))
|
||||||
|
} else {
|
||||||
|
SystemTrayMenu::new()
|
||||||
|
.add_item(CustomMenuItem::new("open_window", "Dashboard"))
|
||||||
|
.add_native_item(SystemTrayMenuItem::Separator)
|
||||||
|
.add_item(CustomMenuItem::new("rule_mode", "Rule Mode"))
|
||||||
|
.add_item(CustomMenuItem::new("global_mode", "Global Mode"))
|
||||||
|
.add_item(CustomMenuItem::new("direct_mode", "Direct Mode"))
|
||||||
|
.add_item(CustomMenuItem::new("script_mode", "Script Mode"))
|
||||||
|
.add_native_item(SystemTrayMenuItem::Separator)
|
||||||
|
.add_item(CustomMenuItem::new("system_proxy", "System Proxy"))
|
||||||
|
.add_item(CustomMenuItem::new("tun_mode", "Tun Mode"))
|
||||||
|
.add_item(CustomMenuItem::new("restart_clash", "Restart Clash"))
|
||||||
|
.add_item(CustomMenuItem::new("restart_app", "Restart App"))
|
||||||
|
.add_native_item(SystemTrayMenuItem::Separator)
|
||||||
|
.add_item(CustomMenuItem::new("quit", "Quit").accelerator("CmdOrControl+Q"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_systray(app_handle: &AppHandle) -> Result<()> {
|
||||||
|
app_handle.tray_handle().set_menu(Tray::tray_menu())?;
|
||||||
|
Tray::update_part(app_handle)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_part(app_handle: &AppHandle) -> Result<()> {
|
||||||
|
let global = Data::global();
|
||||||
|
let clash = global.clash.lock();
|
||||||
|
let mode = clash
|
||||||
|
.config
|
||||||
|
.get(&serde_yaml::Value::from("mode"))
|
||||||
|
.map(|val| val.as_str().unwrap_or("rule"))
|
||||||
|
.unwrap_or("rule");
|
||||||
|
|
||||||
|
let tray = app_handle.tray_handle();
|
||||||
|
|
||||||
|
let _ = tray.get_item("rule_mode").set_selected(mode == "rule");
|
||||||
|
let _ = tray.get_item("global_mode").set_selected(mode == "global");
|
||||||
|
let _ = tray.get_item("direct_mode").set_selected(mode == "direct");
|
||||||
|
let _ = tray.get_item("script_mode").set_selected(mode == "script");
|
||||||
|
|
||||||
|
let verge = global.verge.lock();
|
||||||
|
let system_proxy = verge.enable_system_proxy.as_ref().unwrap_or(&false);
|
||||||
|
let tun_mode = verge.enable_tun_mode.as_ref().unwrap_or(&false);
|
||||||
|
|
||||||
|
let _ = tray.get_item("system_proxy").set_selected(*system_proxy);
|
||||||
|
let _ = tray.get_item("tun_mode").set_selected(*tun_mode);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_system_tray_event(app_handle: &AppHandle, event: SystemTrayEvent) {
|
||||||
|
match event {
|
||||||
|
SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
|
||||||
|
mode @ ("rule_mode" | "global_mode" | "direct_mode" | "script_mode") => {
|
||||||
|
let mode = &mode[0..mode.len() - 5];
|
||||||
|
feat::change_clash_mode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
"open_window" => resolve::create_window(app_handle),
|
||||||
|
"system_proxy" => feat::toggle_system_proxy(),
|
||||||
|
"tun_mode" => feat::toggle_tun_mode(),
|
||||||
|
"restart_clash" => feat::restart_clash_core(),
|
||||||
|
"restart_app" => api::process::restart(&app_handle.env()),
|
||||||
|
"quit" => {
|
||||||
|
resolve::resolve_reset();
|
||||||
|
api::process::kill_children();
|
||||||
|
app_handle.exit(0);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
SystemTrayEvent::LeftClick { .. } => {
|
||||||
|
resolve::create_window(app_handle);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,15 @@ use crate::core::*;
|
|||||||
use crate::data::*;
|
use crate::data::*;
|
||||||
use crate::log_if_err;
|
use crate::log_if_err;
|
||||||
|
|
||||||
|
// 重启clash
|
||||||
|
pub fn restart_clash_core() {
|
||||||
|
let core = Core::global();
|
||||||
|
let mut service = core.service.lock();
|
||||||
|
log_if_err!(service.restart());
|
||||||
|
drop(service);
|
||||||
|
log_if_err!(core.activate());
|
||||||
|
}
|
||||||
|
|
||||||
// 切换模式
|
// 切换模式
|
||||||
pub fn change_clash_mode(mode: &str) {
|
pub fn change_clash_mode(mode: &str) {
|
||||||
let core = Core::global();
|
let core = Core::global();
|
||||||
|
@ -14,9 +14,7 @@ use crate::{
|
|||||||
data::Verge,
|
data::Verge,
|
||||||
utils::{resolve, server},
|
utils::{resolve, server},
|
||||||
};
|
};
|
||||||
use tauri::{
|
use tauri::{api, Manager, SystemTray};
|
||||||
api, CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn main() -> std::io::Result<()> {
|
fn main() -> std::io::Result<()> {
|
||||||
{
|
{
|
||||||
@ -34,51 +32,11 @@ fn main() -> std::io::Result<()> {
|
|||||||
dirs::init_portable_flag();
|
dirs::init_portable_flag();
|
||||||
}
|
}
|
||||||
|
|
||||||
let tray_menu = SystemTrayMenu::new()
|
|
||||||
.add_item(CustomMenuItem::new("open_window", "Show"))
|
|
||||||
.add_native_item(SystemTrayMenuItem::Separator)
|
|
||||||
.add_item(CustomMenuItem::new("rule_mode", "Rule Mode"))
|
|
||||||
.add_item(CustomMenuItem::new("global_mode", "Global Mode"))
|
|
||||||
.add_item(CustomMenuItem::new("direct_mode", "Direct Mode"))
|
|
||||||
.add_item(CustomMenuItem::new("script_mode", "Script Mode"))
|
|
||||||
.add_native_item(SystemTrayMenuItem::Separator)
|
|
||||||
.add_item(CustomMenuItem::new("system_proxy", "System Proxy"))
|
|
||||||
.add_item(CustomMenuItem::new("tun_mode", "Tun Mode"))
|
|
||||||
.add_item(CustomMenuItem::new("restart_clash", "Restart Clash"))
|
|
||||||
.add_item(CustomMenuItem::new("restart_app", "Restart App"))
|
|
||||||
.add_native_item(SystemTrayMenuItem::Separator)
|
|
||||||
.add_item(CustomMenuItem::new("quit", "Quit").accelerator("CmdOrControl+Q"));
|
|
||||||
|
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut builder = tauri::Builder::default()
|
let mut builder = tauri::Builder::default()
|
||||||
.setup(|app| Ok(resolve::resolve_setup(app)))
|
.setup(|app| Ok(resolve::resolve_setup(app)))
|
||||||
.system_tray(SystemTray::new().with_menu(tray_menu))
|
.system_tray(SystemTray::new().with_menu(core::tray::Tray::tray_menu()))
|
||||||
.on_system_tray_event(move |app_handle, event| match event {
|
.on_system_tray_event(core::tray::Tray::on_system_tray_event)
|
||||||
SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
|
|
||||||
"open_window" => {
|
|
||||||
resolve::create_window(app_handle);
|
|
||||||
}
|
|
||||||
mode @ ("rule_mode" | "global_mode" | "direct_mode" | "script_mode") => {
|
|
||||||
let mode = &mode[0..mode.len() - 5];
|
|
||||||
feat::change_clash_mode(mode);
|
|
||||||
}
|
|
||||||
"system_proxy" => feat::toggle_system_proxy(),
|
|
||||||
"tun_mode" => feat::toggle_tun_mode(),
|
|
||||||
"restart_app" => {
|
|
||||||
api::process::restart(&app_handle.env());
|
|
||||||
}
|
|
||||||
"quit" => {
|
|
||||||
resolve::resolve_reset();
|
|
||||||
app_handle.exit(0);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
},
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
SystemTrayEvent::LeftClick { .. } => {
|
|
||||||
resolve::create_window(app_handle);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
})
|
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
// common
|
// common
|
||||||
cmds::get_sys_proxy,
|
cmds::get_sys_proxy,
|
||||||
@ -126,17 +84,18 @@ fn main() -> std::io::Result<()> {
|
|||||||
{
|
{
|
||||||
use tauri::{Menu, MenuItem, Submenu};
|
use tauri::{Menu, MenuItem, Submenu};
|
||||||
|
|
||||||
let submenu_file = Submenu::new(
|
builder = builder.menu(
|
||||||
"File",
|
Menu::new().add_submenu(Submenu::new(
|
||||||
Menu::new()
|
"File",
|
||||||
.add_native_item(MenuItem::Undo)
|
Menu::new()
|
||||||
.add_native_item(MenuItem::Redo)
|
.add_native_item(MenuItem::Undo)
|
||||||
.add_native_item(MenuItem::Copy)
|
.add_native_item(MenuItem::Redo)
|
||||||
.add_native_item(MenuItem::Paste)
|
.add_native_item(MenuItem::Copy)
|
||||||
.add_native_item(MenuItem::Cut)
|
.add_native_item(MenuItem::Paste)
|
||||||
.add_native_item(MenuItem::SelectAll),
|
.add_native_item(MenuItem::Cut)
|
||||||
|
.add_native_item(MenuItem::SelectAll),
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
builder = builder.menu(Menu::new().add_submenu(submenu_file));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
@ -162,6 +121,7 @@ fn main() -> std::io::Result<()> {
|
|||||||
tauri::RunEvent::Exit => {
|
tauri::RunEvent::Exit => {
|
||||||
resolve::resolve_reset();
|
resolve::resolve_reset();
|
||||||
api::process::kill_children();
|
api::process::kill_children();
|
||||||
|
app_handle.exit(0);
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
tauri::RunEvent::WindowEvent { label, event, .. } => {
|
tauri::RunEvent::WindowEvent { label, event, .. } => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user