rust format
This commit is contained in:
@@ -1,7 +1,13 @@
|
|||||||
use tauri::Emitter;
|
use tauri::Emitter;
|
||||||
|
|
||||||
use super::CmdResult;
|
use super::CmdResult;
|
||||||
use crate::{core::{handle::Handle, tray::Tray}, ipc::IpcManager, logging, state::proxy::ProxyRequestCache, utils::logging::Type};
|
use crate::{
|
||||||
|
core::{handle::Handle, tray::Tray},
|
||||||
|
ipc::IpcManager,
|
||||||
|
logging,
|
||||||
|
state::proxy::ProxyRequestCache,
|
||||||
|
utils::logging::Type,
|
||||||
|
};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
const PROXIES_REFRESH_INTERVAL: Duration = Duration::from_secs(60);
|
const PROXIES_REFRESH_INTERVAL: Duration = Duration::from_secs(60);
|
||||||
@@ -52,7 +58,7 @@ pub async fn get_providers_proxies() -> CmdResult<serde_json::Value> {
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn sync_tray_proxy_selection() -> CmdResult<()> {
|
pub async fn sync_tray_proxy_selection() -> CmdResult<()> {
|
||||||
use crate::core::tray::Tray;
|
use crate::core::tray::Tray;
|
||||||
|
|
||||||
match Tray::global().update_menu().await {
|
match Tray::global().update_menu().await {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
logging!(info, Type::Cmd, "Tray proxy selection synced successfully");
|
logging!(info, Type::Cmd, "Tray proxy selection synced successfully");
|
||||||
@@ -68,30 +74,47 @@ pub async fn sync_tray_proxy_selection() -> CmdResult<()> {
|
|||||||
/// 更新代理选择并同步托盘和GUI状态
|
/// 更新代理选择并同步托盘和GUI状态
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn update_proxy_and_sync(group: String, proxy: String) -> CmdResult<()> {
|
pub async fn update_proxy_and_sync(group: String, proxy: String) -> CmdResult<()> {
|
||||||
|
|
||||||
|
|
||||||
match IpcManager::global().update_proxy(&group, &proxy).await {
|
match IpcManager::global().update_proxy(&group, &proxy).await {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
logging!(info, Type::Cmd, "Proxy updated successfully: {} -> {}", group, proxy);
|
logging!(
|
||||||
|
info,
|
||||||
|
Type::Cmd,
|
||||||
|
"Proxy updated successfully: {} -> {}",
|
||||||
|
group,
|
||||||
|
proxy
|
||||||
|
);
|
||||||
|
|
||||||
let cache = crate::state::proxy::ProxyRequestCache::global();
|
let cache = crate::state::proxy::ProxyRequestCache::global();
|
||||||
let key = crate::state::proxy::ProxyRequestCache::make_key("proxies", "default");
|
let key = crate::state::proxy::ProxyRequestCache::make_key("proxies", "default");
|
||||||
cache.map.remove(&key);
|
cache.map.remove(&key);
|
||||||
|
|
||||||
if let Err(e) = Tray::global().update_menu().await {
|
if let Err(e) = Tray::global().update_menu().await {
|
||||||
logging!(error, Type::Cmd, "Failed to sync tray menu: {}", e);
|
logging!(error, Type::Cmd, "Failed to sync tray menu: {}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(app_handle) = Handle::global().app_handle() {
|
if let Some(app_handle) = Handle::global().app_handle() {
|
||||||
let _ = app_handle.emit("verge://force-refresh-proxies", ());
|
let _ = app_handle.emit("verge://force-refresh-proxies", ());
|
||||||
let _ = app_handle.emit("verge://refresh-proxy-config", ());
|
let _ = app_handle.emit("verge://refresh-proxy-config", ());
|
||||||
}
|
}
|
||||||
|
|
||||||
logging!(info, Type::Cmd, "Proxy and sync completed successfully: {} -> {}", group, proxy);
|
logging!(
|
||||||
|
info,
|
||||||
|
Type::Cmd,
|
||||||
|
"Proxy and sync completed successfully: {} -> {}",
|
||||||
|
group,
|
||||||
|
proxy
|
||||||
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
logging!(error, Type::Cmd, "Failed to update proxy: {} -> {}, error: {}", group, proxy, e);
|
logging!(
|
||||||
|
error,
|
||||||
|
Type::Cmd,
|
||||||
|
"Failed to update proxy: {} -> {}, error: {}",
|
||||||
|
group,
|
||||||
|
proxy,
|
||||||
|
e
|
||||||
|
);
|
||||||
Err(e.to_string())
|
Err(e.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ use crate::process::AsyncHandler;
|
|||||||
use crate::{
|
use crate::{
|
||||||
cmd,
|
cmd,
|
||||||
config::Config,
|
config::Config,
|
||||||
feat, logging,
|
feat,
|
||||||
ipc::IpcManager,
|
ipc::IpcManager,
|
||||||
|
logging,
|
||||||
module::lightweight::is_in_lightweight_mode,
|
module::lightweight::is_in_lightweight_mode,
|
||||||
singleton_lazy,
|
singleton_lazy,
|
||||||
utils::{dirs::find_target_icons, i18n::t, resolve::VERSION},
|
utils::{dirs::find_target_icons, i18n::t, resolve::VERSION},
|
||||||
@@ -70,7 +71,6 @@ pub struct Tray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TrayState {
|
impl TrayState {
|
||||||
|
|
||||||
pub async fn get_common_tray_icon() -> (bool, Vec<u8>) {
|
pub async fn get_common_tray_icon() -> (bool, Vec<u8>) {
|
||||||
let verge = Config::verge().await.latest_ref().clone();
|
let verge = Config::verge().await.latest_ref().clone();
|
||||||
let is_common_tray_icon = verge.common_tray_icon.unwrap_or(false);
|
let is_common_tray_icon = verge.common_tray_icon.unwrap_or(false);
|
||||||
@@ -139,7 +139,6 @@ impl TrayState {
|
|||||||
include_bytes!("../../../icons/tray-icon-sys.ico").to_vec(),
|
include_bytes!("../../../icons/tray-icon-sys.ico").to_vec(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_tun_tray_icon() -> (bool, Vec<u8>) {
|
pub async fn get_tun_tray_icon() -> (bool, Vec<u8>) {
|
||||||
@@ -175,10 +174,8 @@ impl TrayState {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Default for Tray {
|
impl Default for Tray {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Tray {
|
Tray {
|
||||||
@@ -263,7 +260,6 @@ impl Tray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn update_menu_internal(&self, app_handle: &AppHandle) -> Result<()> {
|
async fn update_menu_internal(&self, app_handle: &AppHandle) -> Result<()> {
|
||||||
|
|
||||||
let verge = Config::verge().await.latest_ref().clone();
|
let verge = Config::verge().await.latest_ref().clone();
|
||||||
let system_proxy = verge.enable_system_proxy.as_ref().unwrap_or(&false);
|
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 tun_mode = verge.enable_tun_mode.as_ref().unwrap_or(&false);
|
||||||
@@ -315,7 +311,6 @@ impl Tray {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 更新托盘图标
|
/// 更新托盘图标
|
||||||
@@ -573,7 +568,6 @@ impl Tray {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_tray_menu(
|
async fn create_tray_menu(
|
||||||
@@ -586,7 +580,7 @@ async fn create_tray_menu(
|
|||||||
proxy_nodes_data: serde_json::Value,
|
proxy_nodes_data: serde_json::Value,
|
||||||
) -> Result<tauri::menu::Menu<Wry>> {
|
) -> Result<tauri::menu::Menu<Wry>> {
|
||||||
let mode = mode.unwrap_or("");
|
let mode = mode.unwrap_or("");
|
||||||
|
|
||||||
// 获取当前配置文件的选中代理组信息
|
// 获取当前配置文件的选中代理组信息
|
||||||
let current_profile_selected = {
|
let current_profile_selected = {
|
||||||
let profiles = Config::profiles().await;
|
let profiles = Config::profiles().await;
|
||||||
@@ -652,36 +646,38 @@ async fn create_tray_menu(
|
|||||||
// 创建代理组子菜单结构
|
// 创建代理组子菜单结构
|
||||||
let proxy_submenus: Vec<Submenu<Wry>> = {
|
let proxy_submenus: Vec<Submenu<Wry>> = {
|
||||||
let mut submenus = Vec::new();
|
let mut submenus = Vec::new();
|
||||||
|
|
||||||
// 解析代理组数据,创建分层菜单结构
|
// 解析代理组数据,创建分层菜单结构
|
||||||
if let Some(proxies) = proxy_nodes_data.get("proxies").and_then(|v| v.as_object()) {
|
if let Some(proxies) = proxy_nodes_data.get("proxies").and_then(|v| v.as_object()) {
|
||||||
|
|
||||||
for (group_name, group_data) in proxies.iter() {
|
for (group_name, group_data) in proxies.iter() {
|
||||||
if let (Some(group_type),Some(all_proxies)) = (group_data.get("type").and_then(|v| v.as_str()),group_data.get("all").and_then(|v| v.as_array())) {
|
if let (Some(group_type), Some(all_proxies)) = (
|
||||||
|
group_data.get("type").and_then(|v| v.as_str()),
|
||||||
|
group_data.get("all").and_then(|v| v.as_array()),
|
||||||
|
) {
|
||||||
// 在全局模式下只显示GLOBAL组,在规则模式下显示所有Selector类型的代理组
|
// 在全局模式下只显示GLOBAL组,在规则模式下显示所有Selector类型的代理组
|
||||||
let should_show_group = if mode == "global" {
|
let should_show_group = if mode == "global" {
|
||||||
group_name == "GLOBAL"
|
group_name == "GLOBAL"
|
||||||
} else {
|
} else {
|
||||||
group_type == "Selector" && group_name != "GLOBAL"
|
group_type == "Selector" && group_name != "GLOBAL"
|
||||||
};
|
};
|
||||||
|
|
||||||
if !should_show_group {
|
if !should_show_group {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let now_proxy = group_data.get("now").and_then(|v| v.as_str()).unwrap_or("");
|
let now_proxy = group_data.get("now").and_then(|v| v.as_str()).unwrap_or("");
|
||||||
|
|
||||||
// 为每个代理组创建子菜单项
|
// 为每个代理组创建子菜单项
|
||||||
let mut group_items = Vec::new();
|
let mut group_items = Vec::new();
|
||||||
for proxy_name in all_proxies.iter() {
|
for proxy_name in all_proxies.iter() {
|
||||||
if let Some(proxy_str) = proxy_name.as_str() {
|
if let Some(proxy_str) = proxy_name.as_str() {
|
||||||
let is_selected = proxy_str == now_proxy;
|
let is_selected = proxy_str == now_proxy;
|
||||||
let item_id = format!("proxy_{}_{}", group_name, proxy_str);
|
let item_id = format!("proxy_{}_{}", group_name, proxy_str);
|
||||||
|
|
||||||
match CheckMenuItem::with_id(
|
match CheckMenuItem::with_id(
|
||||||
app_handle,
|
app_handle,
|
||||||
item_id,
|
item_id,
|
||||||
proxy_str, // 只显示节点名,不显示组名前缀
|
proxy_str, // 只显示节点名,不显示组名前缀
|
||||||
true,
|
true,
|
||||||
is_selected,
|
is_selected,
|
||||||
None::<&str>,
|
None::<&str>,
|
||||||
@@ -691,14 +687,14 @@ async fn create_tray_menu(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建代理组子菜单
|
// 创建代理组子菜单
|
||||||
if !group_items.is_empty() {
|
if !group_items.is_empty() {
|
||||||
let group_items_refs: Vec<&dyn IsMenuItem<Wry>> = group_items
|
let group_items_refs: Vec<&dyn IsMenuItem<Wry>> = group_items
|
||||||
.iter()
|
.iter()
|
||||||
.map(|item| item as &dyn IsMenuItem<Wry>)
|
.map(|item| item as &dyn IsMenuItem<Wry>)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// 判断当前代理组是否为真正在使用中的组
|
// 判断当前代理组是否为真正在使用中的组
|
||||||
let is_group_active = if mode == "global" {
|
let is_group_active = if mode == "global" {
|
||||||
// 全局模式下,只有GLOBAL组才能显示勾选
|
// 全局模式下,只有GLOBAL组才能显示勾选
|
||||||
@@ -709,23 +705,23 @@ async fn create_tray_menu(
|
|||||||
} else {
|
} else {
|
||||||
// 规则模式下:只对用户在当前配置中手动选择过的代理组显示勾选
|
// 规则模式下:只对用户在当前配置中手动选择过的代理组显示勾选
|
||||||
// 这些组表示用户真正关心和使用的代理组
|
// 这些组表示用户真正关心和使用的代理组
|
||||||
let is_user_selected = current_profile_selected.iter().any(|selected| {
|
let is_user_selected = current_profile_selected
|
||||||
selected.name.as_deref() == Some(group_name)
|
.iter()
|
||||||
});
|
.any(|selected| selected.name.as_deref() == Some(group_name));
|
||||||
is_user_selected && !now_proxy.is_empty()
|
is_user_selected && !now_proxy.is_empty()
|
||||||
};
|
};
|
||||||
|
|
||||||
// 如果组处于活动状态,在组名前添加勾选标记
|
// 如果组处于活动状态,在组名前添加勾选标记
|
||||||
let group_display_name = if is_group_active {
|
let group_display_name = if is_group_active {
|
||||||
format!("✓ {}", group_name)
|
format!("✓ {}", group_name)
|
||||||
} else {
|
} else {
|
||||||
group_name.to_string()
|
group_name.to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
match Submenu::with_id_and_items(
|
match Submenu::with_id_and_items(
|
||||||
app_handle,
|
app_handle,
|
||||||
format!("proxy_group_{}", group_name),
|
format!("proxy_group_{}", group_name),
|
||||||
group_display_name, // 使用带勾选标记的组名
|
group_display_name, // 使用带勾选标记的组名
|
||||||
true,
|
true,
|
||||||
&group_items_refs,
|
&group_items_refs,
|
||||||
) {
|
) {
|
||||||
@@ -736,11 +732,10 @@ async fn create_tray_menu(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
submenus
|
submenus
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Pre-fetch all localized strings
|
// Pre-fetch all localized strings
|
||||||
let dashboard_text = t("Dashboard").await;
|
let dashboard_text = t("Dashboard").await;
|
||||||
let rule_mode_text = t("Rule Mode").await;
|
let rule_mode_text = t("Rule Mode").await;
|
||||||
@@ -817,7 +812,7 @@ async fn create_tray_menu(
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|submenu| submenu as &dyn IsMenuItem<Wry>)
|
.map(|submenu| submenu as &dyn IsMenuItem<Wry>)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Some(Submenu::with_id_and_items(
|
Some(Submenu::with_id_and_items(
|
||||||
app_handle,
|
app_handle,
|
||||||
"proxies",
|
"proxies",
|
||||||
@@ -1033,11 +1028,11 @@ fn on_menu_event(_: &AppHandle, event: MenuEvent) {
|
|||||||
id if id.starts_with("proxy_") => {
|
id if id.starts_with("proxy_") => {
|
||||||
// proxy_{group_name}_{proxy_name}
|
// proxy_{group_name}_{proxy_name}
|
||||||
let parts: Vec<&str> = id.splitn(3, '_').collect();
|
let parts: Vec<&str> = id.splitn(3, '_').collect();
|
||||||
|
|
||||||
if parts.len() == 3 && parts[0] == "proxy" {
|
if parts.len() == 3 && parts[0] == "proxy" {
|
||||||
let group_name = parts[1];
|
let group_name = parts[1];
|
||||||
let proxy_name = parts[2];
|
let proxy_name = parts[2];
|
||||||
|
|
||||||
let current_mode = {
|
let current_mode = {
|
||||||
Config::clash()
|
Config::clash()
|
||||||
.await
|
.await
|
||||||
@@ -1048,24 +1043,34 @@ fn on_menu_event(_: &AppHandle, event: MenuEvent) {
|
|||||||
.unwrap_or("rule")
|
.unwrap_or("rule")
|
||||||
.to_owned()
|
.to_owned()
|
||||||
};
|
};
|
||||||
|
|
||||||
match cmd::proxy::update_proxy_and_sync(group_name.to_string(), proxy_name.to_string()).await {
|
match cmd::proxy::update_proxy_and_sync(
|
||||||
|
group_name.to_string(),
|
||||||
|
proxy_name.to_string(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
log::info!(target: "app", " {} -> {} (模式: {})", group_name, proxy_name, current_mode);
|
log::info!(target: "app", " {} -> {} (模式: {})", group_name, proxy_name, current_mode);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!(target: "app", " {} -> {}, 错误: {:?}", group_name, proxy_name, e);
|
log::error!(target: "app", " {} -> {}, 错误: {:?}", group_name, proxy_name, e);
|
||||||
|
|
||||||
match IpcManager::global().update_proxy(group_name, proxy_name).await {
|
match IpcManager::global()
|
||||||
|
.update_proxy(group_name, proxy_name)
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
log::info!(target: "app", " {} -> {}", group_name, proxy_name);
|
log::info!(target: "app", " {} -> {}", group_name, proxy_name);
|
||||||
|
|
||||||
if let Err(e) = Tray::global().update_menu().await {
|
if let Err(e) = Tray::global().update_menu().await {
|
||||||
log::warn!(target: "app", "托盘菜单更新失败: {e}");
|
log::warn!(target: "app", "托盘菜单更新失败: {e}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(app_handle) = handle::Handle::global().app_handle() {
|
if let Some(app_handle) = handle::Handle::global().app_handle()
|
||||||
let _ = app_handle.emit("verge://force-refresh-proxies", ());
|
{
|
||||||
|
let _ =
|
||||||
|
app_handle.emit("verge://force-refresh-proxies", ());
|
||||||
let _ = app_handle.emit("verge://refresh-proxy-config", ());
|
let _ = app_handle.emit("verge://refresh-proxy-config", ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user