refactor: when updating the tray, the logic is split to improve performance.

This commit is contained in:
huzibaca 2024-12-24 04:52:14 +08:00
parent cca2f1ce61
commit ba195c41b6
4 changed files with 143 additions and 80 deletions

View File

@ -73,7 +73,7 @@ pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult {
match CoreManager::global().update_config().await { match CoreManager::global().update_config().await {
Ok(_) => { Ok(_) => {
handle::Handle::refresh_clash(); handle::Handle::refresh_clash();
let _ = handle::Handle::update_systray_part(); let _ = handle::Handle::update_systray_tooltip();
Config::profiles().apply(); Config::profiles().apply();
wrap_err!(Config::profiles().data().save_file())?; wrap_err!(Config::profiles().data().save_file())?;
Ok(()) Ok(())

View File

@ -71,6 +71,21 @@ impl Handle {
Ok(()) Ok(())
} }
pub fn update_systray_menu() -> Result<()> {
Tray::update_menu()?;
Ok(())
}
pub fn update_systray_icon() -> Result<()> {
Tray::update_icon()?;
Ok(())
}
pub fn update_systray_tooltip() -> Result<()> {
Tray::update_tooltip()?;
Ok(())
}
pub fn set_is_exiting(&self) { pub fn set_is_exiting(&self) {
let mut is_exiting = self.is_exiting.write(); let mut is_exiting = self.is_exiting.write();
*is_exiting = true; *is_exiting = true;

View File

@ -1,11 +1,10 @@
#[cfg(not(target_os = "macos"))]
use crate::utils::dirs;
use crate::{ use crate::{
cmds, cmds,
config::Config, config::Config,
feat, t, feat, t,
utils::{ utils::resolve::{self, VERSION},
dirs,
resolve::{self, VERSION},
},
}; };
use anyhow::Result; use anyhow::Result;
use tauri::AppHandle; use tauri::AppHandle;
@ -65,10 +64,13 @@ impl Tray {
Ok(()) Ok(())
} }
pub fn update_part() -> Result<()> { /// 更新托盘菜单
pub fn update_menu() -> Result<()> {
let app_handle = handle::Handle::global().app_handle().unwrap(); let app_handle = handle::Handle::global().app_handle().unwrap();
let use_zh = { Config::verge().latest().language == Some("zh".into()) }; let verge = Config::verge().latest().clone();
let version = VERSION.get().unwrap(); 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 mode = { let mode = {
Config::clash() Config::clash()
.latest() .latest()
@ -79,96 +81,130 @@ impl Tray {
.to_owned() .to_owned()
}; };
let verge = Config::verge().latest().clone();
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 common_tray_icon = verge.common_tray_icon.as_ref().unwrap_or(&false);
let sysproxy_tray_icon = verge.sysproxy_tray_icon.as_ref().unwrap_or(&false);
let tun_tray_icon = verge.tun_tray_icon.as_ref().unwrap_or(&false);
let tray = app_handle.tray_by_id("main").unwrap(); let tray = app_handle.tray_by_id("main").unwrap();
#[cfg(target_os = "macos")]
let tray_icon = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
let _ = tray.set_menu(Some(create_tray_menu( let _ = tray.set_menu(Some(create_tray_menu(
&app_handle, &app_handle,
Some(mode.as_str()), Some(mode.as_str()),
*system_proxy, *system_proxy,
*tun_mode, *tun_mode,
)?)); )?));
Ok(())
}
#[allow(unused)] /// 更新托盘图标
let mut indication_icon = if *system_proxy && !*tun_mode { pub fn update_icon() -> Result<()> {
let app_handle = handle::Handle::global().app_handle().unwrap();
let verge = Config::verge().latest().clone();
let system_proxy = verge.enable_system_proxy.as_ref().unwrap_or(&false);
let tun_mode = verge.enable_tun_mode.as_ref().unwrap_or(&false);
#[cfg(not(target_os = "macos"))]
{
let common_tray_icon = verge.common_tray_icon.as_ref().unwrap_or(&false);
let sysproxy_tray_icon = verge.sysproxy_tray_icon.as_ref().unwrap_or(&false);
let tun_tray_icon = verge.tun_tray_icon.as_ref().unwrap_or(&false);
}
let tray = app_handle.tray_by_id("main").unwrap();
#[cfg(target_os = "macos")]
let tray_icon = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
let icon_bytes = if *system_proxy && !*tun_mode {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
let mut icon = match tray_icon.as_str() { {
"colorful" => include_bytes!("../../icons/tray-icon-sys.ico").to_vec(), let icon = match tray_icon.as_str() {
_ => include_bytes!("../../icons/tray-icon-sys-mono.ico").to_vec(), "colorful" => include_bytes!("../../icons/tray-icon-sys.ico").to_vec(),
}; _ => include_bytes!("../../icons/tray-icon-sys-mono.ico").to_vec(),
};
#[cfg(not(target_os = "macos"))] icon
let mut icon = include_bytes!("../../icons/tray-icon-sys.ico").to_vec(); }
if *sysproxy_tray_icon { #[cfg(not(target_os = "macos"))]
let icon_dir_path = dirs::app_home_dir()?.join("icons"); {
let png_path = icon_dir_path.join("sysproxy.png"); let mut icon = include_bytes!("../../icons/tray-icon-sys.ico").to_vec();
let ico_path = icon_dir_path.join("sysproxy.ico"); if *sysproxy_tray_icon {
if ico_path.exists() { let icon_dir_path = dirs::app_home_dir()?.join("icons");
icon = std::fs::read(ico_path).unwrap(); let png_path = icon_dir_path.join("sysproxy.png");
} else if png_path.exists() { let ico_path = icon_dir_path.join("sysproxy.ico");
icon = std::fs::read(png_path).unwrap(); if ico_path.exists() {
} icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
icon
} }
icon
} else if *tun_mode { } else if *tun_mode {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
let mut icon = match tray_icon.as_str() { {
"colorful" => include_bytes!("../../icons/tray-icon-tun.ico").to_vec(), let icon = match tray_icon.as_str() {
_ => include_bytes!("../../icons/tray-icon-tun-mono.ico").to_vec(), "colorful" => include_bytes!("../../icons/tray-icon-tun.ico").to_vec(),
}; _ => include_bytes!("../../icons/tray-icon-tun-mono.ico").to_vec(),
};
#[cfg(not(target_os = "macos"))] icon
let mut icon = include_bytes!("../../icons/tray-icon-tun.ico").to_vec(); }
if *tun_tray_icon { #[cfg(not(target_os = "macos"))]
let icon_dir_path = dirs::app_home_dir()?.join("icons"); {
let png_path = icon_dir_path.join("tun.png"); let mut icon = include_bytes!("../../icons/tray-icon-tun.ico").to_vec();
let ico_path = icon_dir_path.join("tun.ico"); if *tun_tray_icon {
if ico_path.exists() { let icon_dir_path = dirs::app_home_dir()?.join("icons");
icon = std::fs::read(ico_path).unwrap(); let png_path = icon_dir_path.join("tun.png");
} else if png_path.exists() { let ico_path = icon_dir_path.join("tun.ico");
icon = std::fs::read(png_path).unwrap(); if ico_path.exists() {
} icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
icon
} }
icon
} else { } else {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
let mut icon = match tray_icon.as_str() { {
"colorful" => include_bytes!("../../icons/tray-icon.ico").to_vec(), let icon = match tray_icon.as_str() {
_ => include_bytes!("../../icons/tray-icon-mono.ico").to_vec(), "colorful" => include_bytes!("../../icons/tray-icon.ico").to_vec(),
}; _ => include_bytes!("../../icons/tray-icon-mono.ico").to_vec(),
};
#[cfg(not(target_os = "macos"))] icon
let mut icon = include_bytes!("../../icons/tray-icon.ico").to_vec(); }
if *common_tray_icon { #[cfg(not(target_os = "macos"))]
let icon_dir_path = dirs::app_home_dir()?.join("icons"); {
let png_path = icon_dir_path.join("common.png"); let mut icon = include_bytes!("../../icons/tray-icon.ico").to_vec();
let ico_path = icon_dir_path.join("common.ico"); if *common_tray_icon {
if ico_path.exists() { let icon_dir_path = dirs::app_home_dir()?.join("icons");
icon = std::fs::read(ico_path).unwrap(); let png_path = icon_dir_path.join("common.png");
} else if png_path.exists() { let ico_path = icon_dir_path.join("common.ico");
icon = std::fs::read(png_path).unwrap(); if ico_path.exists() {
} icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
icon
} }
icon
}; };
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
{ {
let is_template = crate::utils::help::is_monochrome_image_from_bytes(&indication_icon) let is_template =
.unwrap_or(false); crate::utils::help::is_monochrome_image_from_bytes(&icon_bytes).unwrap_or(false);
let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(&indication_icon)?)); let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(&icon_bytes)?));
let _ = tray.set_icon_as_template(is_template); let _ = tray.set_icon_as_template(is_template);
} }
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(&indication_icon)?)); let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(&icon_bytes)?));
Ok(())
}
/// 更新托盘提示
pub fn update_tooltip() -> Result<()> {
let app_handle = handle::Handle::global().app_handle().unwrap();
let use_zh = { Config::verge().latest().language == Some("zh".into()) };
let version = VERSION.get().unwrap();
let verge = Config::verge().latest().clone();
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 switch_map = { let switch_map = {
let mut map = std::collections::HashMap::new(); let mut map = std::collections::HashMap::new();
@ -188,6 +224,7 @@ impl Tray {
}; };
}; };
let tray = app_handle.tray_by_id("main").unwrap();
let _ = tray.set_tooltip(Some(&format!( let _ = tray.set_tooltip(Some(&format!(
"Clash Verge {version}\n{}: {}\n{}: {}\n{}: {}", "Clash Verge {version}\n{}: {}\n{}: {}\n{}: {}",
t!("SysProxy", "系统代理", use_zh), t!("SysProxy", "系统代理", use_zh),
@ -199,6 +236,13 @@ impl Tray {
))); )));
Ok(()) Ok(())
} }
pub fn update_part() -> Result<()> {
Self::update_menu()?;
Self::update_icon()?;
Self::update_tooltip()?;
Ok(())
}
} }
fn create_tray_menu( fn create_tray_menu(

View File

@ -76,7 +76,9 @@ pub fn change_clash_mode(mode: String) {
if Config::clash().data().save_config().is_ok() { if Config::clash().data().save_config().is_ok() {
handle::Handle::refresh_clash(); handle::Handle::refresh_clash();
log_err!(handle::Handle::update_systray_part()); log_err!(handle::Handle::update_systray_menu());
#[cfg(target_os = "macos")]
log_err!(handle::Handle::update_systray_icon());
} }
} }
Err(err) => log::error!(target: "app", "{err}"), Err(err) => log::error!(target: "app", "{err}"),
@ -139,7 +141,9 @@ pub async fn patch_clash(patch: Mapping) -> Result<()> {
CoreManager::global().restart_core().await?; CoreManager::global().restart_core().await?;
} else { } else {
if patch.get("mode").is_some() { if patch.get("mode").is_some() {
log_err!(handle::Handle::update_systray_part()); log_err!(handle::Handle::update_systray_menu());
#[cfg(target_os = "macos")]
log_err!(handle::Handle::update_systray_icon());
} }
Config::runtime().latest().patch_config(patch); Config::runtime().latest().patch_config(patch);
CoreManager::global().update_config().await?; CoreManager::global().update_config().await?;
@ -198,7 +202,7 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> {
let mut should_update_clash_config = false; let mut should_update_clash_config = false;
let mut should_update_launch = false; let mut should_update_launch = false;
let mut should_update_sysproxy = false; let mut should_update_sysproxy = false;
let mut should_update_systray_part = false; let mut should_update_systray_icon = false;
if tun_mode.is_some() { if tun_mode.is_some() {
should_update_clash_config = true; should_update_clash_config = true;
@ -241,7 +245,7 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> {
|| tun_tray_icon.is_some() || tun_tray_icon.is_some()
|| tray_icon.is_some() || tray_icon.is_some()
{ {
should_update_systray_part = true; should_update_systray_icon = true;
} }
if should_restart_core { if should_restart_core {
CoreManager::global().restart_core().await?; CoreManager::global().restart_core().await?;
@ -262,8 +266,8 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> {
hotkey::Hotkey::global().update(hotkeys)?; hotkey::Hotkey::global().update(hotkeys)?;
} }
if should_update_systray_part { if should_update_systray_icon {
handle::Handle::update_systray_part()?; handle::Handle::update_systray_icon()?;
} }
<Result<()>>::Ok(()) <Result<()>>::Ok(())