feat: tray menu enhance (#5412)

* feat(tray): move outbound modes into a dedicated submenu

* refactor: Enable 'Show Proxy Groups Inline' by default

* refactor(tray): move `copyEnv` to `more` submenu
This commit is contained in:
Sline
2025-11-12 14:10:20 +08:00
committed by GitHub
parent 2ea22feb95
commit 2a2de29224
17 changed files with 78 additions and 13 deletions

View File

@@ -28,6 +28,10 @@ tray:
ruleMode: Rule Mode ruleMode: Rule Mode
globalMode: Global Mode globalMode: Global Mode
directMode: Direct Mode directMode: Direct Mode
outboundModes: Outbound Modes
rule: Rule
direct: Direct
global: Global
profiles: Profiles profiles: Profiles
proxies: Proxies proxies: Proxies
systemProxy: System Proxy systemProxy: System Proxy

View File

@@ -28,6 +28,10 @@ tray:
ruleMode: Rule Mode ruleMode: Rule Mode
globalMode: Global Mode globalMode: Global Mode
directMode: Direct Mode directMode: Direct Mode
outboundModes: Outbound Modes
rule: Regel
direct: Direkt
global: Global
profiles: Profiles profiles: Profiles
proxies: Proxies proxies: Proxies
systemProxy: System Proxy systemProxy: System Proxy

View File

@@ -28,6 +28,10 @@ tray:
ruleMode: Rule Mode ruleMode: Rule Mode
globalMode: Global Mode globalMode: Global Mode
directMode: Direct Mode directMode: Direct Mode
outboundModes: Outbound Modes
rule: Rule
direct: Direct
global: Global
profiles: Profiles profiles: Profiles
proxies: Proxies proxies: Proxies
systemProxy: System Proxy systemProxy: System Proxy

View File

@@ -28,6 +28,10 @@ tray:
ruleMode: Rule Mode ruleMode: Rule Mode
globalMode: Global Mode globalMode: Global Mode
directMode: Direct Mode directMode: Direct Mode
outboundModes: Outbound Modes
rule: Regla
direct: Directo
global: Global
profiles: Profiles profiles: Profiles
proxies: Proxies proxies: Proxies
systemProxy: System Proxy systemProxy: System Proxy

View File

@@ -28,6 +28,10 @@ tray:
ruleMode: Rule Mode ruleMode: Rule Mode
globalMode: Global Mode globalMode: Global Mode
directMode: Direct Mode directMode: Direct Mode
outboundModes: Outbound Modes
rule: Rule
direct: Direct
global: Global
profiles: Profiles profiles: Profiles
proxies: Proxies proxies: Proxies
systemProxy: System Proxy systemProxy: System Proxy

View File

@@ -28,6 +28,10 @@ tray:
ruleMode: Rule Mode ruleMode: Rule Mode
globalMode: Global Mode globalMode: Global Mode
directMode: Direct Mode directMode: Direct Mode
outboundModes: Outbound Modes
rule: Aturan
direct: Langsung
global: Global
profiles: Profiles profiles: Profiles
proxies: Proxies proxies: Proxies
systemProxy: System Proxy systemProxy: System Proxy

View File

@@ -28,6 +28,10 @@ tray:
ruleMode: Rule Mode ruleMode: Rule Mode
globalMode: Global Mode globalMode: Global Mode
directMode: Direct Mode directMode: Direct Mode
outboundModes: Outbound Modes
rule: ルール
direct: ダイレクト
global: グローバル
profiles: Profiles profiles: Profiles
proxies: Proxies proxies: Proxies
systemProxy: System Proxy systemProxy: System Proxy

View File

@@ -28,6 +28,10 @@ tray:
ruleMode: 규칙 모드 ruleMode: 규칙 모드
globalMode: 전역 모드 globalMode: 전역 모드
directMode: 직접 모드 directMode: 직접 모드
outboundModes: Outbound Modes
rule: 규칙
direct: 직접
global: 글로벌
profiles: 프로필 profiles: 프로필
proxies: 프록시 proxies: 프록시
systemProxy: 시스템 프록시 systemProxy: 시스템 프록시

View File

@@ -28,6 +28,10 @@ tray:
ruleMode: Rule Mode ruleMode: Rule Mode
globalMode: Global Mode globalMode: Global Mode
directMode: Direct Mode directMode: Direct Mode
outboundModes: Outbound Modes
rule: Правило
direct: Прямой
global: Глобальный
profiles: Profiles profiles: Profiles
proxies: Proxies proxies: Proxies
systemProxy: System Proxy systemProxy: System Proxy

View File

@@ -28,6 +28,10 @@ tray:
ruleMode: Rule Mode ruleMode: Rule Mode
globalMode: Global Mode globalMode: Global Mode
directMode: Direct Mode directMode: Direct Mode
outboundModes: Outbound Modes
rule: Kural
direct: Doğrudan
global: Küresel
profiles: Profiles profiles: Profiles
proxies: Proxies proxies: Proxies
systemProxy: System Proxy systemProxy: System Proxy

View File

@@ -28,6 +28,10 @@ tray:
ruleMode: Rule Mode ruleMode: Rule Mode
globalMode: Global Mode globalMode: Global Mode
directMode: Direct Mode directMode: Direct Mode
outboundModes: Outbound Modes
rule: Rule
direct: Direct
global: Global
profiles: Profiles profiles: Profiles
proxies: Proxies proxies: Proxies
systemProxy: System Proxy systemProxy: System Proxy

View File

@@ -28,6 +28,10 @@ tray:
ruleMode: 规则模式 ruleMode: 规则模式
globalMode: 全局模式 globalMode: 全局模式
directMode: 直连模式 directMode: 直连模式
outboundModes: 出站模式
rule: 规则
direct: 直连
global: 全局
profiles: 订阅 profiles: 订阅
proxies: 代理 proxies: 代理
systemProxy: 系统代理 systemProxy: 系统代理

View File

@@ -28,6 +28,10 @@ tray:
ruleMode: 規則模式 ruleMode: 規則模式
globalMode: 全域模式 globalMode: 全域模式
directMode: 直連模式 directMode: 直連模式
outboundModes: 出站模式
rule: 規則
direct: 直連
global: 全域
profiles: 訂閱 profiles: 訂閱
proxies: 代理 proxies: 代理
systemProxy: 系統代理 systemProxy: 系統代理

View File

@@ -439,7 +439,7 @@ impl IVerge {
webdav_password: None, webdav_password: None,
enable_tray_speed: Some(false), enable_tray_speed: Some(false),
// enable_tray_icon: Some(true), // enable_tray_icon: Some(true),
tray_inline_proxy_groups: Some(false), tray_inline_proxy_groups: Some(true),
enable_global_hotkey: Some(true), enable_global_hotkey: Some(true),
enable_auto_light_weight_mode: Some(false), enable_auto_light_weight_mode: Some(false),
auto_light_weight_minutes: Some(10), auto_light_weight_minutes: Some(10),

View File

@@ -36,6 +36,7 @@ define_menu! {
rule_mode => RULE_MODE, "tray_rule_mode", "tray.ruleMode", rule_mode => RULE_MODE, "tray_rule_mode", "tray.ruleMode",
global_mode => GLOBAL_MODE, "tray_global_mode", "tray.globalMode", global_mode => GLOBAL_MODE, "tray_global_mode", "tray.globalMode",
direct_mode => DIRECT_MODE, "tray_direct_mode", "tray.directMode", direct_mode => DIRECT_MODE, "tray_direct_mode", "tray.directMode",
outbound_modes => OUTBOUND_MODES, "tray_outbound_modes", "tray.outboundModes",
profiles => PROFILES, "tray_profiles", "tray.profiles", profiles => PROFILES, "tray_profiles", "tray.profiles",
proxies => PROXIES, "tray_proxies", "tray.proxies", proxies => PROXIES, "tray_proxies", "tray.proxies",
system_proxy => SYSTEM_PROXY, "tray_system_proxy", "tray.systemProxy", system_proxy => SYSTEM_PROXY, "tray_system_proxy", "tray.systemProxy",

View File

@@ -870,7 +870,7 @@ async fn create_tray_menu(
}); });
let verge_settings = Config::verge().await.latest_arc(); let verge_settings = Config::verge().await.latest_arc();
let show_proxy_groups_inline = verge_settings.tray_inline_proxy_groups.unwrap_or(false); let show_proxy_groups_inline = verge_settings.tray_inline_proxy_groups.unwrap_or(true);
let version = env!("CARGO_PKG_VERSION"); let version = env!("CARGO_PKG_VERSION");
@@ -895,6 +895,13 @@ async fn create_tray_menu(
hotkeys.get("open_or_close_dashboard").map(|s| s.as_str()), hotkeys.get("open_or_close_dashboard").map(|s| s.as_str()),
)?; )?;
let current_mode_text = match current_proxy_mode {
"global" => rust_i18n::t!("tray.global"),
"direct" => rust_i18n::t!("tray.direct"),
_ => rust_i18n::t!("tray.rule"),
};
let outbound_modes_label = format!("{} ({})", texts.outbound_modes, current_mode_text);
let rule_mode = &CheckMenuItem::with_id( let rule_mode = &CheckMenuItem::with_id(
app_handle, app_handle,
MenuIds::RULE_MODE, MenuIds::RULE_MODE,
@@ -922,6 +929,18 @@ async fn create_tray_menu(
hotkeys.get("clash_mode_direct").map(|s| s.as_str()), hotkeys.get("clash_mode_direct").map(|s| s.as_str()),
)?; )?;
let outbound_modes = &Submenu::with_id_and_items(
app_handle,
MenuIds::OUTBOUND_MODES,
outbound_modes_label.as_str(),
true,
&[
rule_mode as &dyn IsMenuItem<Wry>,
global_mode as &dyn IsMenuItem<Wry>,
direct_mode as &dyn IsMenuItem<Wry>,
],
)?;
let profiles = &Submenu::with_id_and_items( let profiles = &Submenu::with_id_and_items(
app_handle, app_handle,
MenuIds::PROFILES, MenuIds::PROFILES,
@@ -1072,6 +1091,7 @@ async fn create_tray_menu(
&texts.more, &texts.more,
true, true,
&[ &[
copy_env as &dyn IsMenuItem<Wry>,
close_all_connections, close_all_connections,
restart_clash, restart_clash,
restart_app, restart_app,
@@ -1090,15 +1110,8 @@ async fn create_tray_menu(
let separator = &PredefinedMenuItem::separator(app_handle)?; let separator = &PredefinedMenuItem::separator(app_handle)?;
// 动态构建菜单项 // 动态构建菜单项
let mut menu_items: Vec<&dyn IsMenuItem<Wry>> = vec![ let mut menu_items: Vec<&dyn IsMenuItem<Wry>> =
open_window, vec![open_window, outbound_modes, separator, profiles];
separator,
rule_mode,
global_mode,
direct_mode,
separator,
profiles,
];
// 如果有代理节点,添加代理节点菜单 // 如果有代理节点,添加代理节点菜单
if show_proxy_groups_inline { if show_proxy_groups_inline {
@@ -1115,7 +1128,6 @@ async fn create_tray_menu(
tun_mode as &dyn IsMenuItem<Wry>, tun_mode as &dyn IsMenuItem<Wry>,
separator, separator,
lightweight_mode as &dyn IsMenuItem<Wry>, lightweight_mode as &dyn IsMenuItem<Wry>,
copy_env as &dyn IsMenuItem<Wry>,
open_dir as &dyn IsMenuItem<Wry>, open_dir as &dyn IsMenuItem<Wry>,
more as &dyn IsMenuItem<Wry>, more as &dyn IsMenuItem<Wry>,
separator, separator,

View File

@@ -372,7 +372,7 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
)} )}
/> />
<GuardState <GuardState
value={verge?.tray_inline_proxy_groups ?? false} value={verge?.tray_inline_proxy_groups ?? true}
valueProps="checked" valueProps="checked"
onCatch={onError} onCatch={onError}
onFormat={onSwitchFormat} onFormat={onSwitchFormat}