mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 00:35:38 +08:00
refactor: unify log output format
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
## v2.3.1
|
## v2.3.1
|
||||||
|
|
||||||
### 🐞 修复问题
|
### 🐞 修复问题
|
||||||
- 增加配置文件校验,修复从古老版本升级上来的"No such file or directory (os error 2)"错误
|
|
||||||
|
- 增加配置文件校验,修复从古老版本升级上来的"No such file or directory (os error 2)"错误
|
||||||
|
|
||||||
## v2.3.0
|
## v2.3.0
|
||||||
|
|
||||||
@@ -14,6 +15,7 @@
|
|||||||
|
|
||||||
- 仅在 Ubuntu 22.04/24.04、Fedora 41 的 **GNOME 桌面环境** 做过简单测试,不保证其他 Linux 发行版兼容,后续将逐步适配和优化。
|
- 仅在 Ubuntu 22.04/24.04、Fedora 41 的 **GNOME 桌面环境** 做过简单测试,不保证其他 Linux 发行版兼容,后续将逐步适配和优化。
|
||||||
- macOS:
|
- macOS:
|
||||||
|
|
||||||
- MacOS 下自动升级成功后请关闭程序等待 30 秒重启,因为 MacOS 的端口释放特性,卸载服务后需重启应用等 30 秒才能恢复内核通信。立即启动可能无法正常启动内核。
|
- MacOS 下自动升级成功后请关闭程序等待 30 秒重启,因为 MacOS 的端口释放特性,卸载服务后需重启应用等 30 秒才能恢复内核通信。立即启动可能无法正常启动内核。
|
||||||
- 墙贴主要为浅色,深色 Tray 图标存在闪烁问题;
|
- 墙贴主要为浅色,深色 Tray 图标存在闪烁问题;
|
||||||
- 彩色 Tray 图标颜色偏淡;
|
- 彩色 Tray 图标颜色偏淡;
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
use super::CmdResult;
|
use super::CmdResult;
|
||||||
use crate::{config::*, core::*, utils::dirs, wrap_err};
|
use crate::{
|
||||||
|
config::*,
|
||||||
|
core::*,
|
||||||
|
logging,
|
||||||
|
utils::{dirs, logging::Type},
|
||||||
|
wrap_err,
|
||||||
|
};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
/// 保存profiles的配置
|
/// 保存profiles的配置
|
||||||
@@ -26,29 +32,54 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
|
|||||||
wrap_err!(fs::write(&file_path, file_data.clone().unwrap()))?;
|
wrap_err!(fs::write(&file_path, file_data.clone().unwrap()))?;
|
||||||
|
|
||||||
let file_path_str = file_path.to_string_lossy().to_string();
|
let file_path_str = file_path.to_string_lossy().to_string();
|
||||||
println!(
|
logging!(
|
||||||
|
info,
|
||||||
|
Type::Config,
|
||||||
|
true,
|
||||||
"[cmd配置save] 开始验证配置文件: {}, 是否为merge文件: {}",
|
"[cmd配置save] 开始验证配置文件: {}, 是否为merge文件: {}",
|
||||||
file_path_str, is_merge_file
|
file_path_str,
|
||||||
|
is_merge_file
|
||||||
);
|
);
|
||||||
|
|
||||||
// 对于 merge 文件,只进行语法验证,不进行后续内核验证
|
// 对于 merge 文件,只进行语法验证,不进行后续内核验证
|
||||||
if is_merge_file {
|
if is_merge_file {
|
||||||
println!("[cmd配置save] 检测到merge文件,只进行语法验证");
|
logging!(
|
||||||
|
info,
|
||||||
|
Type::Config,
|
||||||
|
true,
|
||||||
|
"[cmd配置save] 检测到merge文件,只进行语法验证"
|
||||||
|
);
|
||||||
match CoreManager::global()
|
match CoreManager::global()
|
||||||
.validate_config_file(&file_path_str, Some(true))
|
.validate_config_file(&file_path_str, Some(true))
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok((true, _)) => {
|
Ok((true, _)) => {
|
||||||
println!("[cmd配置save] merge文件语法验证通过");
|
logging!(
|
||||||
|
info,
|
||||||
|
Type::Config,
|
||||||
|
true,
|
||||||
|
"[cmd配置save] merge文件语法验证通过"
|
||||||
|
);
|
||||||
// 成功后尝试更新整体配置
|
// 成功后尝试更新整体配置
|
||||||
if let Err(e) = CoreManager::global().update_config().await {
|
if let Err(e) = CoreManager::global().update_config().await {
|
||||||
println!("[cmd配置save] 更新整体配置时发生错误: {}", e);
|
logging!(
|
||||||
log::warn!(target: "app", "更新整体配置时发生错误: {}", e);
|
warn,
|
||||||
|
Type::Config,
|
||||||
|
true,
|
||||||
|
"[cmd配置save] 更新整体配置时发生错误: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Ok((false, error_msg)) => {
|
Ok((false, error_msg)) => {
|
||||||
println!("[cmd配置save] merge文件语法验证失败: {}", error_msg);
|
logging!(
|
||||||
|
warn,
|
||||||
|
Type::Config,
|
||||||
|
true,
|
||||||
|
"[cmd配置save] merge文件语法验证失败: {}",
|
||||||
|
error_msg
|
||||||
|
);
|
||||||
// 恢复原始配置文件
|
// 恢复原始配置文件
|
||||||
wrap_err!(fs::write(&file_path, original_content))?;
|
wrap_err!(fs::write(&file_path, original_content))?;
|
||||||
// 发送合并文件专用错误通知
|
// 发送合并文件专用错误通知
|
||||||
@@ -57,7 +88,13 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("[cmd配置save] 验证过程发生错误: {}", e);
|
logging!(
|
||||||
|
error,
|
||||||
|
Type::Config,
|
||||||
|
true,
|
||||||
|
"[cmd配置save] 验证过程发生错误: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
// 恢复原始配置文件
|
// 恢复原始配置文件
|
||||||
wrap_err!(fs::write(&file_path, original_content))?;
|
wrap_err!(fs::write(&file_path, original_content))?;
|
||||||
return Err(e.to_string());
|
return Err(e.to_string());
|
||||||
@@ -71,11 +108,17 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
|
|||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok((true, _)) => {
|
Ok((true, _)) => {
|
||||||
println!("[cmd配置save] 验证成功");
|
logging!(info, Type::Config, true, "[cmd配置save] 验证成功");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Ok((false, error_msg)) => {
|
Ok((false, error_msg)) => {
|
||||||
println!("[cmd配置save] 验证失败: {}", error_msg);
|
logging!(
|
||||||
|
warn,
|
||||||
|
Type::Config,
|
||||||
|
true,
|
||||||
|
"[cmd配置save] 验证失败: {}",
|
||||||
|
error_msg
|
||||||
|
);
|
||||||
// 恢复原始配置文件
|
// 恢复原始配置文件
|
||||||
wrap_err!(fs::write(&file_path, original_content))?;
|
wrap_err!(fs::write(&file_path, original_content))?;
|
||||||
|
|
||||||
@@ -90,24 +133,30 @@ pub async fn save_profile_file(index: String, file_data: Option<String>) -> CmdR
|
|||||||
|| (!file_path_str.ends_with(".js") && !is_script_error)
|
|| (!file_path_str.ends_with(".js") && !is_script_error)
|
||||||
{
|
{
|
||||||
// 普通YAML错误使用YAML通知处理
|
// 普通YAML错误使用YAML通知处理
|
||||||
println!("[cmd配置save] YAML配置文件验证失败,发送通知");
|
log::info!(target: "app", "[cmd配置save] YAML配置文件验证失败,发送通知");
|
||||||
let result = (false, error_msg.clone());
|
let result = (false, error_msg.clone());
|
||||||
crate::cmd::validate::handle_yaml_validation_notice(&result, "YAML配置文件");
|
crate::cmd::validate::handle_yaml_validation_notice(&result, "YAML配置文件");
|
||||||
} else if is_script_error {
|
} else if is_script_error {
|
||||||
// 脚本错误使用专门的通知处理
|
// 脚本错误使用专门的通知处理
|
||||||
println!("[cmd配置save] 脚本文件验证失败,发送通知");
|
log::info!(target: "app", "[cmd配置save] 脚本文件验证失败,发送通知");
|
||||||
let result = (false, error_msg.clone());
|
let result = (false, error_msg.clone());
|
||||||
crate::cmd::validate::handle_script_validation_notice(&result, "脚本文件");
|
crate::cmd::validate::handle_script_validation_notice(&result, "脚本文件");
|
||||||
} else {
|
} else {
|
||||||
// 普通配置错误使用一般通知
|
// 普通配置错误使用一般通知
|
||||||
println!("[cmd配置save] 其他类型验证失败,发送一般通知");
|
log::info!(target: "app", "[cmd配置save] 其他类型验证失败,发送一般通知");
|
||||||
handle::Handle::notice_message("config_validate::error", &error_msg);
|
handle::Handle::notice_message("config_validate::error", &error_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("[cmd配置save] 验证过程发生错误: {}", e);
|
logging!(
|
||||||
|
error,
|
||||||
|
Type::Config,
|
||||||
|
true,
|
||||||
|
"[cmd配置save] 验证过程发生错误: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
// 恢复原始配置文件
|
// 恢复原始配置文件
|
||||||
wrap_err!(fs::write(&file_path, original_content))?;
|
wrap_err!(fs::write(&file_path, original_content))?;
|
||||||
Err(e.to_string())
|
Err(e.to_string())
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use super::CmdResult;
|
use super::CmdResult;
|
||||||
use crate::core::*;
|
use crate::{core::*, logging, utils::logging::Type};
|
||||||
|
|
||||||
/// 发送脚本验证通知消息
|
/// 发送脚本验证通知消息
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -28,7 +28,14 @@ pub fn handle_script_validation_notice(result: &(bool, String), file_type: &str)
|
|||||||
"config_validate::script_error"
|
"config_validate::script_error"
|
||||||
};
|
};
|
||||||
|
|
||||||
log::warn!(target: "app", "{} 验证失败: {}", file_type, error_msg);
|
logging!(
|
||||||
|
warn,
|
||||||
|
Type::Config,
|
||||||
|
true,
|
||||||
|
"{} 验证失败: {}",
|
||||||
|
file_type,
|
||||||
|
error_msg
|
||||||
|
);
|
||||||
handle::Handle::notice_message(status, error_msg);
|
handle::Handle::notice_message(status, error_msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,7 +43,7 @@ pub fn handle_script_validation_notice(result: &(bool, String), file_type: &str)
|
|||||||
/// 验证指定脚本文件
|
/// 验证指定脚本文件
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn validate_script_file(file_path: String) -> CmdResult<bool> {
|
pub async fn validate_script_file(file_path: String) -> CmdResult<bool> {
|
||||||
log::info!(target: "app", "验证脚本文件: {}", file_path);
|
logging!(info, Type::Config, true, "验证脚本文件: {}", file_path);
|
||||||
|
|
||||||
match CoreManager::global()
|
match CoreManager::global()
|
||||||
.validate_config_file(&file_path, None)
|
.validate_config_file(&file_path, None)
|
||||||
@@ -48,7 +55,13 @@ pub async fn validate_script_file(file_path: String) -> CmdResult<bool> {
|
|||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let error_msg = e.to_string();
|
let error_msg = e.to_string();
|
||||||
log::error!(target: "app", "验证脚本文件过程发生错误: {}", error_msg);
|
logging!(
|
||||||
|
error,
|
||||||
|
Type::Config,
|
||||||
|
true,
|
||||||
|
"验证脚本文件过程发生错误: {}",
|
||||||
|
error_msg
|
||||||
|
);
|
||||||
handle::Handle::notice_message("config_validate::process_terminated", &error_msg);
|
handle::Handle::notice_message("config_validate::process_terminated", &error_msg);
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
@@ -60,7 +73,14 @@ pub async fn validate_script_file(file_path: String) -> CmdResult<bool> {
|
|||||||
pub fn handle_yaml_validation_notice(result: &(bool, String), file_type: &str) {
|
pub fn handle_yaml_validation_notice(result: &(bool, String), file_type: &str) {
|
||||||
if !result.0 {
|
if !result.0 {
|
||||||
let error_msg = &result.1;
|
let error_msg = &result.1;
|
||||||
println!("[通知] 处理{}验证错误: {}", file_type, error_msg);
|
logging!(
|
||||||
|
info,
|
||||||
|
Type::Config,
|
||||||
|
true,
|
||||||
|
"[通知] 处理{}验证错误: {}",
|
||||||
|
file_type,
|
||||||
|
error_msg
|
||||||
|
);
|
||||||
|
|
||||||
// 检查是否为merge文件
|
// 检查是否为merge文件
|
||||||
let is_merge_file = file_type.contains("合并");
|
let is_merge_file = file_type.contains("合并");
|
||||||
@@ -97,8 +117,22 @@ pub fn handle_yaml_validation_notice(result: &(bool, String), file_type: &str) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
log::warn!(target: "app", "{} 验证失败: {}", file_type, error_msg);
|
logging!(
|
||||||
println!("[通知] 发送通知: status={}, msg={}", status, error_msg);
|
warn,
|
||||||
|
Type::Config,
|
||||||
|
true,
|
||||||
|
"{} 验证失败: {}",
|
||||||
|
file_type,
|
||||||
|
error_msg
|
||||||
|
);
|
||||||
|
logging!(
|
||||||
|
info,
|
||||||
|
Type::Config,
|
||||||
|
true,
|
||||||
|
"[通知] 发送通知: status={}, msg={}",
|
||||||
|
status,
|
||||||
|
error_msg
|
||||||
|
);
|
||||||
handle::Handle::notice_message(status, error_msg);
|
handle::Handle::notice_message(status, error_msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ pub fn change_clash_mode(mode: String) {
|
|||||||
after_change_clash_mode();
|
after_change_clash_mode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => println!("{err}"),
|
Err(err) => log::error!(target: "app", "{err}"),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ use crate::{
|
|||||||
cmd,
|
cmd,
|
||||||
config::{Config, PrfItem, PrfOption},
|
config::{Config, PrfItem, PrfOption},
|
||||||
core::{handle, CoreManager, *},
|
core::{handle, CoreManager, *},
|
||||||
|
logging,
|
||||||
process::AsyncHandler,
|
process::AsyncHandler,
|
||||||
|
utils::logging::Type,
|
||||||
};
|
};
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
|
|
||||||
@@ -29,7 +31,7 @@ pub async fn update_profile(
|
|||||||
option: Option<PrfOption>,
|
option: Option<PrfOption>,
|
||||||
auto_refresh: Option<bool>,
|
auto_refresh: Option<bool>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
println!("[订阅更新] 开始更新订阅 {}", uid);
|
logging!(info, Type::Config, true, "[订阅更新] 开始更新订阅 {}", uid);
|
||||||
let auto_refresh = auto_refresh.unwrap_or(true); // 默认为true,保持兼容性
|
let auto_refresh = auto_refresh.unwrap_or(true); // 默认为true,保持兼容性
|
||||||
|
|
||||||
let url_opt = {
|
let url_opt = {
|
||||||
@@ -39,13 +41,13 @@ pub async fn update_profile(
|
|||||||
let is_remote = item.itype.as_ref().is_some_and(|s| s == "remote");
|
let is_remote = item.itype.as_ref().is_some_and(|s| s == "remote");
|
||||||
|
|
||||||
if !is_remote {
|
if !is_remote {
|
||||||
println!("[订阅更新] {} 不是远程订阅,跳过更新", uid);
|
log::info!(target: "app", "[订阅更新] {} 不是远程订阅,跳过更新", uid);
|
||||||
None // 非远程订阅直接更新
|
None // 非远程订阅直接更新
|
||||||
} else if item.url.is_none() {
|
} else if item.url.is_none() {
|
||||||
println!("[订阅更新] {} 缺少URL,无法更新", uid);
|
log::warn!(target: "app", "[订阅更新] {} 缺少URL,无法更新", uid);
|
||||||
bail!("failed to get the profile item url");
|
bail!("failed to get the profile item url");
|
||||||
} else {
|
} else {
|
||||||
println!(
|
log::info!(target: "app",
|
||||||
"[订阅更新] {} 是远程订阅,URL: {}",
|
"[订阅更新] {} 是远程订阅,URL: {}",
|
||||||
uid,
|
uid,
|
||||||
item.url.clone().unwrap()
|
item.url.clone().unwrap()
|
||||||
@@ -56,24 +58,24 @@ pub async fn update_profile(
|
|||||||
|
|
||||||
let should_update = match url_opt {
|
let should_update = match url_opt {
|
||||||
Some((url, opt)) => {
|
Some((url, opt)) => {
|
||||||
println!("[订阅更新] 开始下载新的订阅内容");
|
log::info!(target: "app", "[订阅更新] 开始下载新的订阅内容");
|
||||||
let merged_opt = PrfOption::merge(opt.clone(), option.clone());
|
let merged_opt = PrfOption::merge(opt.clone(), option.clone());
|
||||||
|
|
||||||
// 尝试使用正常设置更新
|
// 尝试使用正常设置更新
|
||||||
match PrfItem::from_url(&url, None, None, merged_opt.clone()).await {
|
match PrfItem::from_url(&url, None, None, merged_opt.clone()).await {
|
||||||
Ok(item) => {
|
Ok(item) => {
|
||||||
println!("[订阅更新] 更新订阅配置成功");
|
log::info!(target: "app", "[订阅更新] 更新订阅配置成功");
|
||||||
let profiles = Config::profiles();
|
let profiles = Config::profiles();
|
||||||
let mut profiles = profiles.latest();
|
let mut profiles = profiles.latest();
|
||||||
profiles.update_item(uid.clone(), item)?;
|
profiles.update_item(uid.clone(), item)?;
|
||||||
|
|
||||||
let is_current = Some(uid.clone()) == profiles.get_current();
|
let is_current = Some(uid.clone()) == profiles.get_current();
|
||||||
println!("[订阅更新] 是否为当前使用的订阅: {}", is_current);
|
log::info!(target: "app", "[订阅更新] 是否为当前使用的订阅: {}", is_current);
|
||||||
is_current && auto_refresh
|
is_current && auto_refresh
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
// 首次更新失败,尝试使用Clash代理
|
// 首次更新失败,尝试使用Clash代理
|
||||||
println!("[订阅更新] 正常更新失败: {},尝试使用Clash代理更新", err);
|
log::warn!(target: "app", "[订阅更新] 正常更新失败: {},尝试使用Clash代理更新", err);
|
||||||
|
|
||||||
// 发送通知
|
// 发送通知
|
||||||
handle::Handle::notice_message("update_retry_with_clash", uid.clone());
|
handle::Handle::notice_message("update_retry_with_clash", uid.clone());
|
||||||
@@ -90,7 +92,7 @@ pub async fn update_profile(
|
|||||||
// 使用Clash代理重试
|
// 使用Clash代理重试
|
||||||
match PrfItem::from_url(&url, None, None, Some(fallback_opt)).await {
|
match PrfItem::from_url(&url, None, None, Some(fallback_opt)).await {
|
||||||
Ok(mut item) => {
|
Ok(mut item) => {
|
||||||
println!("[订阅更新] 使用Clash代理更新成功");
|
log::info!(target: "app", "[订阅更新] 使用Clash代理更新成功");
|
||||||
|
|
||||||
// 恢复原始代理设置到item
|
// 恢复原始代理设置到item
|
||||||
if let Some(option) = item.option.as_mut() {
|
if let Some(option) = item.option.as_mut() {
|
||||||
@@ -110,11 +112,11 @@ pub async fn update_profile(
|
|||||||
handle::Handle::notice_message("update_with_clash_proxy", profile_name);
|
handle::Handle::notice_message("update_with_clash_proxy", profile_name);
|
||||||
|
|
||||||
let is_current = Some(uid.clone()) == profiles.get_current();
|
let is_current = Some(uid.clone()) == profiles.get_current();
|
||||||
println!("[订阅更新] 是否为当前使用的订阅: {}", is_current);
|
log::info!(target: "app", "[订阅更新] 是否为当前使用的订阅: {}", is_current);
|
||||||
is_current && auto_refresh
|
is_current && auto_refresh
|
||||||
}
|
}
|
||||||
Err(retry_err) => {
|
Err(retry_err) => {
|
||||||
println!("[订阅更新] 使用Clash代理更新仍然失败: {}", retry_err);
|
log::error!(target: "app", "[订阅更新] 使用Clash代理更新仍然失败: {}", retry_err);
|
||||||
handle::Handle::notice_message(
|
handle::Handle::notice_message(
|
||||||
"update_failed_even_with_clash",
|
"update_failed_even_with_clash",
|
||||||
format!("{}", retry_err),
|
format!("{}", retry_err),
|
||||||
@@ -129,14 +131,14 @@ pub async fn update_profile(
|
|||||||
};
|
};
|
||||||
|
|
||||||
if should_update {
|
if should_update {
|
||||||
println!("[订阅更新] 更新内核配置");
|
logging!(info, Type::Config, true, "[订阅更新] 更新内核配置");
|
||||||
match CoreManager::global().update_config().await {
|
match CoreManager::global().update_config().await {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
println!("[订阅更新] 更新成功");
|
logging!(info, Type::Config, true, "[订阅更新] 更新成功");
|
||||||
handle::Handle::refresh_clash();
|
handle::Handle::refresh_clash();
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
println!("[订阅更新] 更新失败: {}", err);
|
logging!(error, Type::Config, true, "[订阅更新] 更新失败: {}", err);
|
||||||
handle::Handle::notice_message("update_failed", format!("{err}"));
|
handle::Handle::notice_message("update_failed", format!("{err}"));
|
||||||
log::error!(target: "app", "{err}");
|
log::error!(target: "app", "{err}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,45 +3,39 @@ use crate::AppHandleManager;
|
|||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
core::{handle, sysopt, CoreManager},
|
core::{handle, sysopt, CoreManager},
|
||||||
|
logging,
|
||||||
module::mihomo::MihomoManager,
|
module::mihomo::MihomoManager,
|
||||||
utils::resolve,
|
utils::{logging::Type, resolve},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Open or close the dashboard window
|
/// Open or close the dashboard window
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn open_or_close_dashboard() {
|
pub fn open_or_close_dashboard() {
|
||||||
println!("Attempting to open/close dashboard");
|
|
||||||
log::info!(target: "app", "Attempting to open/close dashboard");
|
log::info!(target: "app", "Attempting to open/close dashboard");
|
||||||
|
|
||||||
// 检查是否在轻量模式下
|
// 检查是否在轻量模式下
|
||||||
if crate::module::lightweight::is_in_lightweight_mode() {
|
if crate::module::lightweight::is_in_lightweight_mode() {
|
||||||
println!("Currently in lightweight mode, exiting lightweight mode");
|
|
||||||
log::info!(target: "app", "Currently in lightweight mode, exiting lightweight mode");
|
log::info!(target: "app", "Currently in lightweight mode, exiting lightweight mode");
|
||||||
|
|
||||||
crate::module::lightweight::exit_lightweight_mode();
|
crate::module::lightweight::exit_lightweight_mode();
|
||||||
|
|
||||||
println!("Creating new window after exiting lightweight mode");
|
|
||||||
log::info!(target: "app", "Creating new window after exiting lightweight mode");
|
log::info!(target: "app", "Creating new window after exiting lightweight mode");
|
||||||
resolve::create_window(true);
|
resolve::create_window(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(window) = handle::Handle::global().get_window() {
|
if let Some(window) = handle::Handle::global().get_window() {
|
||||||
println!("Found existing window");
|
|
||||||
log::info!(target: "app", "Found existing window");
|
log::info!(target: "app", "Found existing window");
|
||||||
|
|
||||||
// 如果窗口存在,则切换其显示状态
|
// 如果窗口存在,则切换其显示状态
|
||||||
match window.is_visible() {
|
match window.is_visible() {
|
||||||
Ok(visible) => {
|
Ok(visible) => {
|
||||||
println!("Window visibility status: {}", visible);
|
|
||||||
log::info!(target: "app", "Window visibility status: {}", visible);
|
log::info!(target: "app", "Window visibility status: {}", visible);
|
||||||
|
|
||||||
if visible {
|
if visible {
|
||||||
println!("Attempting to hide window");
|
|
||||||
log::info!(target: "app", "Attempting to hide window");
|
log::info!(target: "app", "Attempting to hide window");
|
||||||
let _ = window.hide();
|
let _ = window.hide();
|
||||||
} else {
|
} else {
|
||||||
println!("Attempting to show and focus window");
|
|
||||||
log::info!(target: "app", "Attempting to show and focus window");
|
log::info!(target: "app", "Attempting to show and focus window");
|
||||||
if window.is_minimized().unwrap_or(false) {
|
if window.is_minimized().unwrap_or(false) {
|
||||||
let _ = window.unminimize();
|
let _ = window.unminimize();
|
||||||
@@ -51,12 +45,10 @@ pub fn open_or_close_dashboard() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Failed to get window visibility: {:?}", e);
|
|
||||||
log::error!(target: "app", "Failed to get window visibility: {:?}", e);
|
log::error!(target: "app", "Failed to get window visibility: {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
println!("No existing window found, creating new window");
|
|
||||||
log::info!(target: "app", "No existing window found, creating new window");
|
log::info!(target: "app", "No existing window found, creating new window");
|
||||||
resolve::create_window(true);
|
resolve::create_window(true);
|
||||||
}
|
}
|
||||||
@@ -65,7 +57,7 @@ pub fn open_or_close_dashboard() {
|
|||||||
/// 异步优化的应用退出函数
|
/// 异步优化的应用退出函数
|
||||||
pub fn quit() {
|
pub fn quit() {
|
||||||
use crate::process::AsyncHandler;
|
use crate::process::AsyncHandler;
|
||||||
log::debug!(target: "app", "启动退出流程");
|
logging!(debug, Type::System, true, "启动退出流程");
|
||||||
|
|
||||||
// 获取应用句柄并设置退出标志
|
// 获取应用句柄并设置退出标志
|
||||||
let app_handle = handle::Handle::global().app_handle().unwrap();
|
let app_handle = handle::Handle::global().app_handle().unwrap();
|
||||||
@@ -79,10 +71,16 @@ pub fn quit() {
|
|||||||
|
|
||||||
// 使用异步任务处理资源清理,避免阻塞
|
// 使用异步任务处理资源清理,避免阻塞
|
||||||
AsyncHandler::spawn(move || async move {
|
AsyncHandler::spawn(move || async move {
|
||||||
log::info!(target: "app", "开始异步清理资源");
|
logging!(info, Type::System, true, "开始异步清理资源");
|
||||||
let cleanup_result = clean_async().await;
|
let cleanup_result = clean_async().await;
|
||||||
|
|
||||||
log::info!(target: "app", "资源清理完成,退出代码: {}", if cleanup_result { 0 } else { 1 });
|
logging!(
|
||||||
|
info,
|
||||||
|
Type::System,
|
||||||
|
true,
|
||||||
|
"资源清理完成,退出代码: {}",
|
||||||
|
if cleanup_result { 0 } else { 1 }
|
||||||
|
);
|
||||||
app_handle.exit(if cleanup_result { 0 } else { 1 });
|
app_handle.exit(if cleanup_result { 0 } else { 1 });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -90,7 +88,7 @@ pub fn quit() {
|
|||||||
async fn clean_async() -> bool {
|
async fn clean_async() -> bool {
|
||||||
use tokio::time::{timeout, Duration};
|
use tokio::time::{timeout, Duration};
|
||||||
|
|
||||||
log::info!(target: "app", "开始执行异步清理操作...");
|
logging!(info, Type::System, true, "开始执行异步清理操作...");
|
||||||
|
|
||||||
// 1. 处理TUN模式
|
// 1. 处理TUN模式
|
||||||
let tun_task = async {
|
let tun_task = async {
|
||||||
@@ -178,10 +176,16 @@ async fn clean_async() -> bool {
|
|||||||
|
|
||||||
let all_success = tun_success && proxy_success && core_success && dns_success;
|
let all_success = tun_success && proxy_success && core_success && dns_success;
|
||||||
|
|
||||||
log::info!(
|
logging!(
|
||||||
target: "app",
|
info,
|
||||||
|
Type::System,
|
||||||
|
true,
|
||||||
"异步清理操作完成 - TUN: {}, 代理: {}, 核心: {}, DNS: {}, 总体: {}",
|
"异步清理操作完成 - TUN: {}, 代理: {}, 核心: {}, DNS: {}, 总体: {}",
|
||||||
tun_success, proxy_success, core_success, dns_success, all_success
|
tun_success,
|
||||||
|
proxy_success,
|
||||||
|
core_success,
|
||||||
|
dns_success,
|
||||||
|
all_success
|
||||||
);
|
);
|
||||||
|
|
||||||
all_success
|
all_success
|
||||||
@@ -193,7 +197,7 @@ pub fn clean() -> bool {
|
|||||||
let (tx, rx) = std::sync::mpsc::channel();
|
let (tx, rx) = std::sync::mpsc::channel();
|
||||||
|
|
||||||
AsyncHandler::spawn(move || async move {
|
AsyncHandler::spawn(move || async move {
|
||||||
log::info!(target: "app", "开始执行清理操作...");
|
logging!(info, Type::System, true, "开始执行清理操作...");
|
||||||
|
|
||||||
// 使用已有的异步清理函数
|
// 使用已有的异步清理函数
|
||||||
let cleanup_result = clean_async().await;
|
let cleanup_result = clean_async().await;
|
||||||
@@ -204,11 +208,16 @@ pub fn clean() -> bool {
|
|||||||
|
|
||||||
match rx.recv_timeout(std::time::Duration::from_secs(8)) {
|
match rx.recv_timeout(std::time::Duration::from_secs(8)) {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
log::info!(target: "app", "清理操作完成,结果: {}", result);
|
logging!(info, Type::System, true, "清理操作完成,结果: {}", result);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
log::warn!(target: "app", "清理操作超时,返回成功状态避免阻塞");
|
logging!(
|
||||||
|
warn,
|
||||||
|
Type::System,
|
||||||
|
true,
|
||||||
|
"清理操作超时,返回成功状态避免阻塞"
|
||||||
|
);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ pub fn run() {
|
|||||||
if core::handle::Handle::global().is_exiting() {
|
if core::handle::Handle::global().is_exiting() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
println!("closing window...");
|
log::info!(target: "app", "closing window...");
|
||||||
api.prevent_close();
|
api.prevent_close();
|
||||||
if let Some(window) = core::handle::Handle::global().get_window() {
|
if let Some(window) = core::handle::Handle::global().get_window() {
|
||||||
let _ = window.hide();
|
let _ = window.hide();
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { BaseDialog, DialogRef } from "@/components/base";
|
import { BaseDialog, DialogRef } from "@/components/base";
|
||||||
import { useClashInfo } from "@/hooks/use-clash";
|
import { useClashInfo } from "@/hooks/use-clash";
|
||||||
import { patchClashConfig } from "@/services/cmds";
|
|
||||||
import { showNotice } from "@/services/noticeService";
|
import { showNotice } from "@/services/noticeService";
|
||||||
import { ContentCopy } from "@mui/icons-material";
|
import { ContentCopy } from "@mui/icons-material";
|
||||||
import {
|
import {
|
||||||
@@ -42,19 +41,19 @@ export const ControllerViewer = forwardRef<DialogRef>((props, ref) => {
|
|||||||
// 保存配置
|
// 保存配置
|
||||||
const onSave = useLockFn(async () => {
|
const onSave = useLockFn(async () => {
|
||||||
if (!controller.trim()) {
|
if (!controller.trim()) {
|
||||||
showNotice("error", t("Controller address cannot be empty"), 3000);
|
showNotice("error", t("Controller address cannot be empty"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!secret.trim()) {
|
if (!secret.trim()) {
|
||||||
showNotice("error", t("Secret cannot be empty"), 3000);
|
showNotice("error", t("Secret cannot be empty"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setIsSaving(true);
|
setIsSaving(true);
|
||||||
await patchInfo({ "external-controller": controller, secret });
|
await patchInfo({ "external-controller": controller, secret });
|
||||||
showNotice("success", t("Configuration saved successfully"), 2000);
|
showNotice("success", t("Configuration saved successfully"));
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
showNotice(
|
showNotice(
|
||||||
@@ -73,9 +72,9 @@ export const ControllerViewer = forwardRef<DialogRef>((props, ref) => {
|
|||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(text);
|
await navigator.clipboard.writeText(text);
|
||||||
setCopySuccess(type);
|
setCopySuccess(type);
|
||||||
setTimeout(() => setCopySuccess(null), 2000);
|
setTimeout(() => setCopySuccess(null));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showNotice("error", t("Failed to copy"), 2000);
|
showNotice("error", t("Failed to copy"));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user