feat: system tray support zh language

This commit is contained in:
GyDi 2022-10-28 00:40:29 +08:00
parent b635e64803
commit e11b4038a3
No known key found for this signature in database
GPG Key ID: 58B15242BA8277A6
5 changed files with 154 additions and 112 deletions

View File

@ -1,7 +1,6 @@
use crate::data::*;
use super::tray::Tray;
use crate::log_if_err;
use anyhow::{bail, Result};
use serde_yaml::Value;
use tauri::{AppHandle, Manager, Window};
#[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<()> {
if self.app_handle.is_none() {
bail!("update_systray unhandle error");
}
let app_handle = self.app_handle.as_ref().unwrap();
let tray = app_handle.tray_handle();
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();
Tray::update_systray(app_handle)?;
Ok(())
}
/// 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(())
}
}

View File

@ -16,6 +16,7 @@ mod hotkey;
mod service;
mod sysopt;
mod timer;
pub mod tray;
pub use self::service::*;
@ -64,8 +65,7 @@ impl Core {
drop(sysopt);
let handle = self.handle.lock();
log_if_err!(handle.update_systray());
log_if_err!(handle.update_systray_clash());
log_if_err!(handle.update_systray_part());
drop(handle);
let mut hotkey = self.hotkey.lock();
@ -136,7 +136,7 @@ impl Core {
if has_mode {
let handle = self.handle.lock();
handle.update_systray_clash()?;
handle.update_systray_part()?;
}
Ok(())
@ -155,6 +155,7 @@ impl Core {
let system_proxy = patch.enable_system_proxy;
let proxy_bypass = patch.system_proxy_bypass;
let proxy_guard = patch.enable_proxy_guard;
let language = patch.language;
#[cfg(target_os = "windows")]
{
@ -197,9 +198,13 @@ impl Core {
sysopt.guard_proxy();
}
if system_proxy.is_some() || tun_mode.is_some() {
// 更新tray
if language.is_some() {
let handle = self.handle.lock();
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() {
@ -232,7 +237,7 @@ impl Core {
// update tray
let handle = handle.lock();
handle.refresh_clash();
log_if_err!(handle.update_systray_clash());
log_if_err!(handle.update_systray_part());
});
Ok(())

109
src-tauri/src/core/tray.rs Normal file
View 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);
}
_ => {}
}
}
}

View File

@ -2,6 +2,15 @@ use crate::core::*;
use crate::data::*;
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) {
let core = Core::global();

View File

@ -14,9 +14,7 @@ use crate::{
data::Verge,
utils::{resolve, server},
};
use tauri::{
api, CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
};
use tauri::{api, Manager, SystemTray};
fn main() -> std::io::Result<()> {
{
@ -34,51 +32,11 @@ fn main() -> std::io::Result<()> {
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)]
let mut builder = tauri::Builder::default()
.setup(|app| Ok(resolve::resolve_setup(app)))
.system_tray(SystemTray::new().with_menu(tray_menu))
.on_system_tray_event(move |app_handle, event| match 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);
}
_ => {}
})
.system_tray(SystemTray::new().with_menu(core::tray::Tray::tray_menu()))
.on_system_tray_event(core::tray::Tray::on_system_tray_event)
.invoke_handler(tauri::generate_handler![
// common
cmds::get_sys_proxy,
@ -126,7 +84,8 @@ fn main() -> std::io::Result<()> {
{
use tauri::{Menu, MenuItem, Submenu};
let submenu_file = Submenu::new(
builder = builder.menu(
Menu::new().add_submenu(Submenu::new(
"File",
Menu::new()
.add_native_item(MenuItem::Undo)
@ -135,8 +94,8 @@ fn main() -> std::io::Result<()> {
.add_native_item(MenuItem::Paste)
.add_native_item(MenuItem::Cut)
.add_native_item(MenuItem::SelectAll),
)),
);
builder = builder.menu(Menu::new().add_submenu(submenu_file));
}
#[allow(unused_mut)]
@ -162,6 +121,7 @@ fn main() -> std::io::Result<()> {
tauri::RunEvent::Exit => {
resolve::resolve_reset();
api::process::kill_children();
app_handle.exit(0);
}
#[cfg(target_os = "macos")]
tauri::RunEvent::WindowEvent { label, event, .. } => {