mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-08 02:52:07 +08:00
crate(i18n): add clash-verge-i18n crate and integrate localization support (#5961)
* crate(i18n): add clash-verge-i18n crate and integrate localization support * refactor(service): remove redundant reinstall_service functions for Windows, Linux, and macOS * chore(i18n): align i18n key * feat(i18n): unify scan roots and add backend Rust/YAML support to cleanup script * chore(i18n): add scripts to package.json * fix(tray): initialize i18n locale before setup * refactor(i18n): move locale initialization into Config::init_config * fix(i18n): refresh systray tooltip on language change and correct docs reference * fix(tray): remove unnecessary locale synchronization to improve performance --------- Co-authored-by: Tunglies <77394545+Tunglies@users.noreply.github.com>
This commit is contained in:
@@ -30,9 +30,8 @@ pub enum ServiceStatus {
|
||||
#[derive(Clone)]
|
||||
pub struct ServiceManager(ServiceStatus);
|
||||
|
||||
#[allow(clippy::unused_async)]
|
||||
#[cfg(target_os = "windows")]
|
||||
async fn uninstall_service() -> Result<()> {
|
||||
fn uninstall_service() -> Result<()> {
|
||||
logging!(info, Type::Service, "uninstall service");
|
||||
|
||||
use deelevate::{PrivilegeLevel, Token};
|
||||
@@ -63,9 +62,8 @@ async fn uninstall_service() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::unused_async)]
|
||||
#[cfg(target_os = "windows")]
|
||||
async fn install_service() -> Result<()> {
|
||||
fn install_service() -> Result<()> {
|
||||
logging!(info, Type::Service, "install service");
|
||||
|
||||
use deelevate::{PrivilegeLevel, Token};
|
||||
@@ -93,27 +91,8 @@ async fn install_service() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
async fn reinstall_service() -> Result<()> {
|
||||
logging!(info, Type::Service, "reinstall service");
|
||||
|
||||
// 先卸载服务
|
||||
if let Err(err) = uninstall_service().await {
|
||||
logging!(warn, Type::Service, "failed to uninstall service: {}", err);
|
||||
}
|
||||
|
||||
// 再安装服务
|
||||
match install_service().await {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
bail!(format!("failed to install service: {err}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::unused_async)]
|
||||
#[cfg(target_os = "linux")]
|
||||
async fn uninstall_service() -> Result<()> {
|
||||
fn uninstall_service() -> Result<()> {
|
||||
logging!(info, Type::Service, "uninstall service");
|
||||
|
||||
let uninstall_path = tauri::utils::platform::current_exe()?.with_file_name("clash-verge-service-uninstall");
|
||||
@@ -169,8 +148,7 @@ async fn uninstall_service() -> Result<()> {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[allow(clippy::unused_async)]
|
||||
async fn install_service() -> Result<()> {
|
||||
fn install_service() -> Result<()> {
|
||||
logging!(info, Type::Service, "install service");
|
||||
|
||||
let install_path = tauri::utils::platform::current_exe()?.with_file_name("clash-verge-service-install");
|
||||
@@ -222,24 +200,6 @@ async fn install_service() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
async fn reinstall_service() -> Result<()> {
|
||||
logging!(info, Type::Service, "reinstall service");
|
||||
|
||||
// 先卸载服务
|
||||
if let Err(err) = uninstall_service().await {
|
||||
logging!(warn, Type::Service, "failed to uninstall service: {}", err);
|
||||
}
|
||||
|
||||
// 再安装服务
|
||||
match install_service().await {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
bail!(format!("failed to install service: {err}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn linux_running_as_root() -> bool {
|
||||
use crate::core::handle;
|
||||
@@ -249,7 +209,7 @@ fn linux_running_as_root() -> bool {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
async fn uninstall_service() -> Result<()> {
|
||||
fn uninstall_service() -> Result<()> {
|
||||
logging!(info, Type::Service, "uninstall service");
|
||||
|
||||
let binary_path = dirs::service_path()?;
|
||||
@@ -261,9 +221,9 @@ async fn uninstall_service() -> Result<()> {
|
||||
|
||||
let uninstall_shell: String = uninstall_path.to_string_lossy().into_owned();
|
||||
|
||||
crate::utils::i18n::sync_locale().await;
|
||||
// clash_verge_i18n::sync_locale(Config::verge().await.latest_arc().language.as_deref());
|
||||
|
||||
let prompt = rust_i18n::t!("service.adminUninstallPrompt").to_string();
|
||||
let prompt = clash_verge_i18n::t!("service.adminUninstallPrompt");
|
||||
let command =
|
||||
format!(r#"do shell script "sudo '{uninstall_shell}'" with administrator privileges with prompt "{prompt}""#);
|
||||
|
||||
@@ -282,7 +242,7 @@ async fn uninstall_service() -> Result<()> {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
async fn install_service() -> Result<()> {
|
||||
fn install_service() -> Result<()> {
|
||||
logging!(info, Type::Service, "install service");
|
||||
|
||||
let binary_path = dirs::service_path()?;
|
||||
@@ -294,9 +254,9 @@ async fn install_service() -> Result<()> {
|
||||
|
||||
let install_shell: String = install_path.to_string_lossy().into_owned();
|
||||
|
||||
crate::utils::i18n::sync_locale().await;
|
||||
// clash_verge_i18n::sync_locale(Config::verge().await.latest_arc().language.as_deref());
|
||||
|
||||
let prompt = rust_i18n::t!("service.adminInstallPrompt").to_string();
|
||||
let prompt = clash_verge_i18n::t!("service.adminInstallPrompt");
|
||||
let command =
|
||||
format!(r#"do shell script "sudo '{install_shell}'" with administrator privileges with prompt "{prompt}""#);
|
||||
|
||||
@@ -309,17 +269,16 @@ async fn install_service() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
async fn reinstall_service() -> Result<()> {
|
||||
fn reinstall_service() -> Result<()> {
|
||||
logging!(info, Type::Service, "reinstall service");
|
||||
|
||||
// 先卸载服务
|
||||
if let Err(err) = uninstall_service().await {
|
||||
if let Err(err) = uninstall_service() {
|
||||
logging!(warn, Type::Service, "failed to uninstall service: {}", err);
|
||||
}
|
||||
|
||||
// 再安装服务
|
||||
match install_service().await {
|
||||
match install_service() {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
bail!(format!("failed to install service: {err}"))
|
||||
@@ -328,9 +287,9 @@ async fn reinstall_service() -> Result<()> {
|
||||
}
|
||||
|
||||
/// 强制重装服务(UI修复按钮)
|
||||
async fn force_reinstall_service() -> Result<()> {
|
||||
fn force_reinstall_service() -> Result<()> {
|
||||
logging!(info, Type::Service, "用户请求强制重装服务");
|
||||
reinstall_service().await.map_err(|err| {
|
||||
reinstall_service().map_err(|err| {
|
||||
logging!(error, Type::Service, "强制重装服务失败: {}", err);
|
||||
err
|
||||
})
|
||||
@@ -550,22 +509,22 @@ impl ServiceManager {
|
||||
}
|
||||
ServiceStatus::NeedsReinstall | ServiceStatus::ReinstallRequired => {
|
||||
logging!(info, Type::Service, "服务需要重装,执行重装流程");
|
||||
reinstall_service().await?;
|
||||
reinstall_service()?;
|
||||
wait_and_check_service_available(self).await?;
|
||||
}
|
||||
ServiceStatus::ForceReinstallRequired => {
|
||||
logging!(info, Type::Service, "服务需要强制重装,执行强制重装流程");
|
||||
force_reinstall_service().await?;
|
||||
force_reinstall_service()?;
|
||||
wait_and_check_service_available(self).await?;
|
||||
}
|
||||
ServiceStatus::InstallRequired => {
|
||||
logging!(info, Type::Service, "需要安装服务,执行安装流程");
|
||||
install_service().await?;
|
||||
install_service()?;
|
||||
wait_and_check_service_available(self).await?;
|
||||
}
|
||||
ServiceStatus::UninstallRequired => {
|
||||
logging!(info, Type::Service, "服务需要卸载,执行卸载流程");
|
||||
uninstall_service().await?;
|
||||
uninstall_service()?;
|
||||
self.0 = ServiceStatus::Unavailable("Service Uninstalled".into());
|
||||
}
|
||||
ServiceStatus::Unavailable(reason) => {
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
use rust_i18n::t;
|
||||
use clash_verge_i18n::t;
|
||||
use std::{borrow::Cow, sync::Arc};
|
||||
|
||||
fn to_arc_str(value: Cow<'static, str>) -> Arc<str> {
|
||||
match value {
|
||||
fn to_arc_str<S>(value: S) -> Arc<str>
|
||||
where
|
||||
S: Into<Cow<'static, str>>,
|
||||
{
|
||||
match value.into() {
|
||||
Cow::Borrowed(s) => Arc::from(s),
|
||||
Cow::Owned(s) => Arc::from(s.into_boxed_str()),
|
||||
}
|
||||
|
||||
@@ -12,11 +12,8 @@ use crate::process::AsyncHandler;
|
||||
use crate::singleton;
|
||||
use crate::utils::window_manager::WindowManager;
|
||||
use crate::{
|
||||
Type, cmd,
|
||||
config::Config,
|
||||
feat, logging,
|
||||
module::lightweight::is_in_lightweight_mode,
|
||||
utils::{dirs::find_target_icons, i18n},
|
||||
Type, cmd, config::Config, feat, logging, module::lightweight::is_in_lightweight_mode,
|
||||
utils::dirs::find_target_icons,
|
||||
};
|
||||
|
||||
use super::handle;
|
||||
@@ -389,8 +386,6 @@ impl Tray {
|
||||
|
||||
let app_handle = handle::Handle::app_handle();
|
||||
|
||||
i18n::sync_locale().await;
|
||||
|
||||
let verge = Config::verge().await.latest_arc();
|
||||
let system_proxy = verge.enable_system_proxy.as_ref().unwrap_or(&false);
|
||||
let tun_mode = verge.enable_tun_mode.as_ref().unwrap_or(&false);
|
||||
@@ -417,9 +412,9 @@ impl Tray {
|
||||
}
|
||||
|
||||
// Get localized strings before using them
|
||||
let sys_proxy_text = rust_i18n::t!("tray.tooltip.systemProxy");
|
||||
let tun_text = rust_i18n::t!("tray.tooltip.tun");
|
||||
let profile_text = rust_i18n::t!("tray.tooltip.profile");
|
||||
let sys_proxy_text = clash_verge_i18n::t!("tray.tooltip.systemProxy");
|
||||
let tun_text = clash_verge_i18n::t!("tray.tooltip.tun");
|
||||
let profile_text = clash_verge_i18n::t!("tray.tooltip.profile");
|
||||
|
||||
let v = env!("CARGO_PKG_VERSION");
|
||||
let reassembled_version = v.split_once('+').map_or_else(
|
||||
@@ -724,8 +719,6 @@ async fn create_tray_menu(
|
||||
) -> Result<tauri::menu::Menu<Wry>> {
|
||||
let current_proxy_mode = mode.unwrap_or("");
|
||||
|
||||
i18n::sync_locale().await;
|
||||
|
||||
// TODO: should update tray menu again when it was timeout error
|
||||
let proxy_nodes_data = tokio::time::timeout(
|
||||
Duration::from_millis(1000),
|
||||
@@ -829,9 +822,9 @@ async fn create_tray_menu(
|
||||
None
|
||||
} else {
|
||||
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"),
|
||||
"global" => clash_verge_i18n::t!("tray.global"),
|
||||
"direct" => clash_verge_i18n::t!("tray.direct"),
|
||||
_ => clash_verge_i18n::t!("tray.rule"),
|
||||
};
|
||||
let outbound_modes_label = format!("{} ({})", texts.outbound_modes, current_mode_text);
|
||||
Some(Submenu::with_id_and_items(
|
||||
|
||||
Reference in New Issue
Block a user