From 3493580236b6462f73c6a730b5bb431fe574df47 Mon Sep 17 00:00:00 2001 From: "Junkai W." <129588175+Be-Forever223@users.noreply.github.com> Date: Sun, 21 Sep 2025 09:45:26 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dwin=E4=B8=8B=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E6=89=98=E7=9B=98=E4=BB=A3=E7=90=86=E7=BB=84=E4=B8=8E?= =?UTF-8?q?gui=E9=A1=BA=E5=BA=8F=E4=B8=8D=E4=B8=80=E8=87=B4=20(#4815)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/core/tray/mod.rs | 75 ++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 22 deletions(-) diff --git a/src-tauri/src/core/tray/mod.rs b/src-tauri/src/core/tray/mod.rs index 45f0248ae..68b24e643 100644 --- a/src-tauri/src/core/tray/mod.rs +++ b/src-tauri/src/core/tray/mod.rs @@ -22,6 +22,7 @@ use super::handle; use anyhow::Result; use futures::future::join_all; use parking_lot::Mutex; +use std::collections::HashMap; use std::{ fs, sync::atomic::{AtomicBool, Ordering}, @@ -282,16 +283,6 @@ impl Tray { .unwrap_or_default(); let is_lightweight_mode = is_in_lightweight_mode(); - // 获取代理节点 - let proxy_nodes_data = cmd::get_proxies().await.unwrap_or_else(|e| { - logging!( - error, - Type::Cmd, - "Failed to fetch proxies for tray menu: {e}" - ); - serde_json::Value::Object(serde_json::Map::new()) - }); - match app_handle.tray_by_id("main") { Some(tray) => { let _ = tray.set_menu(Some( @@ -302,7 +293,6 @@ impl Tray { *tun_mode, profile_uid_and_name, is_lightweight_mode, - proxy_nodes_data, ) .await?, )); @@ -564,7 +554,6 @@ async fn create_tray_menu( tun_mode_enabled: bool, profile_uid_and_name: Vec<(String, String)>, is_lightweight_mode: bool, - proxy_nodes_data: serde_json::Value, ) -> Result> { let mode = mode.unwrap_or(""); @@ -579,6 +568,15 @@ async fn create_tray_menu( .unwrap_or_default() }; + let proxy_nodes_data = cmd::get_proxies().await.unwrap_or_else(|e| { + logging!( + error, + Type::Cmd, + "Failed to fetch proxies for tray menu: {e}" + ); + serde_json::Value::Object(serde_json::Map::new()) + }); + let version = env!("CARGO_PKG_VERSION"); let hotkeys = Config::verge() @@ -628,6 +626,7 @@ async fn create_tray_menu( // 代理组子菜单 let proxy_submenus: Vec> = { let mut submenus = Vec::new(); + let mut group_name_submenus_hash = HashMap::new(); if let Some(proxies) = proxy_nodes_data.get("proxies").and_then(|v| v.as_object()) { for (group_name, group_data) in proxies.iter() { @@ -635,9 +634,7 @@ async fn create_tray_menu( let should_show = match mode { "global" => group_name == "GLOBAL", _ => group_name != "GLOBAL", - } && - // Check if the group is hidden - !group_data.get("hidden").and_then(|v| v.as_bool( )).unwrap_or(false); + }; if !should_show { continue; @@ -721,13 +718,52 @@ async fn create_tray_menu( true, &group_items_refs, ) { - submenus.push(submenu); + group_name_submenus_hash.insert(group_name.to_string(), submenu); } else { log::warn!(target: "app", "创建代理组子菜单失败: {}", group_name); } } } + // 获取运行时代理组配置 + let runtime_proxy_groups_config = cmd::get_runtime_config() + .await + .map_err(|e| { + logging!( + error, + Type::Cmd, + "Failed to fetch runtime proxy groups for tray menu: {e}" + ); + }) + .ok() + .flatten() + .map(|config| { + config + .get("proxy-groups") + .and_then(|groups| groups.as_sequence()) + .map(|groups| { + groups + .iter() + .filter_map(|group| group.get("name")) + .filter_map(|name| name.as_str()) + .map(|name| name.to_string()) + .collect::>() + }) + .unwrap_or_default() + }); + + if let Some(runtime_proxy_groups_config) = runtime_proxy_groups_config { + for group_name in runtime_proxy_groups_config { + if let Some(submenu) = group_name_submenus_hash.get(&group_name) { + submenus.push(submenu.clone()); + } + } + } else { + for (_, submenu) in group_name_submenus_hash { + submenus.push(submenu); + } + } + submenus }; @@ -997,12 +1033,7 @@ fn on_menu_event(_: &AppHandle, event: MenuEvent) { if !should_handle_tray_click() { return; } - - if !is_in_lightweight_mode() { - lightweight::entry_lightweight_mode().await; // Await async function - } else { - lightweight::exit_lightweight_mode().await; // Await async function - } + lightweight::entry_lightweight_mode().await; // Await async function } "quit" => { feat::quit().await; // Await async function