Update On Thu Mar 27 19:36:13 CET 2025

This commit is contained in:
github-action[bot]
2025-03-27 19:36:13 +01:00
parent d67f57743a
commit a4eec905b6
117 changed files with 1460 additions and 913 deletions

View File

@@ -8,7 +8,7 @@ use crate::{
feat,
module::{lightweight::entry_lightweight_mode, mihomo::Rate},
resolve,
utils::{dirs, i18n::t, resolve::VERSION},
utils::{dirs::find_target_icons, i18n::t, resolve::VERSION},
};
use anyhow::Result;
@@ -20,10 +20,7 @@ use parking_lot::Mutex;
use parking_lot::RwLock;
#[cfg(target_os = "macos")]
pub use speed_rate::{SpeedRate, Traffic};
#[cfg(target_os = "macos")]
use std::collections::hash_map::DefaultHasher;
#[cfg(target_os = "macos")]
use std::hash::{Hash, Hasher};
use std::fs;
#[cfg(target_os = "macos")]
use std::sync::Arc;
use tauri::{
@@ -35,19 +32,124 @@ use tauri::{
use tokio::sync::broadcast;
use super::handle;
#[derive(Clone)]
struct TrayState {}
#[cfg(target_os = "macos")]
pub struct Tray {
pub speed_rate: Arc<Mutex<Option<SpeedRate>>>,
shutdown_tx: Arc<RwLock<Option<broadcast::Sender<()>>>>,
is_subscribed: Arc<RwLock<bool>>,
pub icon_hash: Arc<Mutex<Option<u64>>>,
pub icon_cache: Arc<Mutex<Option<Vec<u8>>>>,
pub rate_cache: Arc<Mutex<Option<Rate>>>,
}
#[cfg(not(target_os = "macos"))]
pub struct Tray {}
impl TrayState {
pub fn get_common_tray_icon() -> (bool, Vec<u8>) {
let verge = Config::verge().latest().clone();
let is_common_tray_icon = verge.common_tray_icon.clone().unwrap_or(false);
if is_common_tray_icon {
if let Some(common_icon_path) = find_target_icons("common").unwrap() {
let icon_data = fs::read(common_icon_path).unwrap();
return (true, icon_data);
}
}
#[cfg(target_os = "macos")]
{
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
if tray_icon_colorful == "monochrome" {
(
false,
include_bytes!("../../../icons/tray-icon-mono.ico").to_vec(),
)
} else {
(
false,
include_bytes!("../../../icons/tray-icon.ico").to_vec(),
)
}
}
#[cfg(not(target_os = "macos"))]
{
(
false,
include_bytes!("../../../icons/tray-icon.ico").to_vec(),
)
}
}
pub fn get_sysproxy_tray_icon() -> (bool, Vec<u8>) {
let verge = Config::verge().latest().clone();
let is_sysproxy_tray_icon = verge.sysproxy_tray_icon.clone().unwrap_or(false);
if is_sysproxy_tray_icon {
if let Some(sysproxy_icon_path) = find_target_icons("sysproxy").unwrap() {
let icon_data = fs::read(sysproxy_icon_path).unwrap();
return (true, icon_data);
}
}
#[cfg(target_os = "macos")]
{
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
if tray_icon_colorful == "monochrome" {
(
false,
include_bytes!("../../../icons/tray-icon-sys-mono.ico").to_vec(),
)
} else {
(
false,
include_bytes!("../../../icons/tray-icon-sys.ico").to_vec(),
)
}
}
#[cfg(not(target_os = "macos"))]
{
(
false,
include_bytes!("../../../icons/tray-icon-sys.ico").to_vec(),
)
}
}
pub fn get_tun_tray_icon() -> (bool, Vec<u8>) {
let verge = Config::verge().latest().clone();
let is_tun_tray_icon = verge.tun_tray_icon.clone().unwrap_or(false);
if is_tun_tray_icon {
if let Some(tun_icon_path) = find_target_icons("tun").unwrap() {
let icon_data = fs::read(tun_icon_path).unwrap();
return (true, icon_data);
}
}
#[cfg(target_os = "macos")]
{
let tray_icon_colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
if tray_icon_colorful == "monochrome" {
(
false,
include_bytes!("../../../icons/tray-icon-tun-mono.ico").to_vec(),
)
} else {
(
false,
include_bytes!("../../../icons/tray-icon-tun.ico").to_vec(),
)
}
}
#[cfg(not(target_os = "macos"))]
{
(
false,
include_bytes!("../../../icons/tray-icon-tun.ico").to_vec(),
)
}
}
}
impl Tray {
pub fn global() -> &'static Tray {
static TRAY: OnceCell<Tray> = OnceCell::new();
@@ -57,8 +159,6 @@ impl Tray {
speed_rate: Arc::new(Mutex::new(None)),
shutdown_tx: Arc::new(RwLock::new(None)),
is_subscribed: Arc::new(RwLock::new(false)),
icon_hash: Arc::new(Mutex::new(None)),
icon_cache: Arc::new(Mutex::new(None)),
rate_cache: Arc::new(Mutex::new(None)),
});
@@ -159,107 +259,29 @@ impl Tray {
}
/// 更新托盘图标
#[allow(unused_variables)]
pub fn update_icon(&self, rate: Option<Rate>) -> 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 system_mode = 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 app_handle = handle::Handle::global().app_handle().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 icon_bytes = if *system_proxy && !*tun_mode {
#[cfg(target_os = "macos")]
let mut icon = match tray_icon.as_str() {
"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"))]
let mut icon = include_bytes!("../../../icons/tray-icon-sys.ico").to_vec();
if *sysproxy_tray_icon {
let icon_dir_path = dirs::app_home_dir()?.join("icons");
let png_path = icon_dir_path.join("sysproxy.png");
let ico_path = icon_dir_path.join("sysproxy.ico");
if ico_path.exists() {
icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
icon
} else if *tun_mode {
#[cfg(target_os = "macos")]
let mut icon = match tray_icon.as_str() {
"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"))]
let mut icon = include_bytes!("../../../icons/tray-icon-tun.ico").to_vec();
if *tun_tray_icon {
let icon_dir_path = dirs::app_home_dir()?.join("icons");
let png_path = icon_dir_path.join("tun.png");
let ico_path = icon_dir_path.join("tun.ico");
if ico_path.exists() {
icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
icon
} else {
#[cfg(target_os = "macos")]
let mut icon = match tray_icon.as_str() {
"colorful" => include_bytes!("../../../icons/tray-icon.ico").to_vec(),
_ => include_bytes!("../../../icons/tray-icon-mono.ico").to_vec(),
};
#[cfg(not(target_os = "macos"))]
let mut icon = include_bytes!("../../../icons/tray-icon.ico").to_vec();
if *common_tray_icon {
let icon_dir_path = dirs::app_home_dir()?.join("icons");
let png_path = icon_dir_path.join("common.png");
let ico_path = icon_dir_path.join("common.ico");
if ico_path.exists() {
icon = std::fs::read(ico_path).unwrap();
} else if png_path.exists() {
icon = std::fs::read(png_path).unwrap();
}
}
icon
let (is_custom_icon, icon_bytes) = match (*system_mode, *tun_mode) {
(true, true) => TrayState::get_tun_tray_icon(),
(true, false) => TrayState::get_sysproxy_tray_icon(),
(false, true) => TrayState::get_tun_tray_icon(),
(false, false) => TrayState::get_common_tray_icon(),
};
#[cfg(target_os = "macos")]
{
let enable_tray_speed = verge.enable_tray_speed.unwrap_or(true);
let enable_tray_icon = verge.enable_tray_icon.unwrap_or(true);
let is_colorful = tray_icon == "colorful";
let icon_hash = {
let mut hasher = DefaultHasher::new();
icon_bytes.clone().hash(&mut hasher);
hasher.finish()
};
let mut icon_hash_guard = self.icon_hash.lock();
let mut icon_bytes_guard = self.icon_cache.lock();
if *icon_hash_guard != Some(icon_hash) {
*icon_hash_guard = Some(icon_hash);
*icon_bytes_guard = Some(icon_bytes.clone());
}
let colorful = verge.tray_icon.clone().unwrap_or("monochrome".to_string());
let is_colorful = colorful == "colorful";
if !enable_tray_speed {
let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(
&(*icon_bytes_guard).clone().unwrap(),
)?));
let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(&icon_bytes)?));
let _ = tray.set_icon_as_template(!is_colorful);
return Ok(());
}
@@ -280,16 +302,20 @@ impl Tray {
*rate_guard = rate;
let bytes = if enable_tray_icon {
Some(icon_bytes_guard.as_ref().unwrap())
Some(icon_bytes)
} else {
None
};
let rate = rate_guard.as_ref();
let rate_bytes = SpeedRate::add_speed_text(bytes, rate).unwrap();
let rate_bytes = SpeedRate::add_speed_text(is_custom_icon, bytes, rate).unwrap();
let _ = tray.set_icon(Some(tauri::image::Image::from_bytes(&rate_bytes)?));
let _ = tray.set_icon_as_template(!is_colorful);
if !is_custom_icon {
let _ = tray.set_icon_as_template(!is_colorful);
} else {
let _ = tray.set_icon_as_template(false);
}
}
Ok(())
}