mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 17:15:38 +08:00
chore: i18n (#5276)
* chore: notice i18n * feat: add script to clean up unused i18n keys * chore: cleanup i18n keys * refactor(i18n/proxies): migrate proxies UI to structured locale keys * chore: i18n for rule module * chore: i18n for profile module * chore: i18n for connections module * chore: i18n for settings module * chore: i18n for verge settings * chore: i18n for theme settings * chore: i18n for theme * chore(i18n): components.home.* * chore(i18n): remove unused i18n keys * chore(i18n): components.profile.* * chore(i18n): components.connection * chore(i18n): pages.logs.* * chore(i18n): pages.*.provider * chore(i18n): components.settings.externalCors.* * chore(i18n): components.settings.clash.* * chore(i18n): components.settings.liteMode.* * chore(i18n): components.settings.backup.* * chore(i18n): components.settings.clash.port.* * chore(i18n): components.settings.misc.* * chore(i18n): components.settings.update.* * chore(i18n): components.settings.sysproxy.* * chore(i18n): components.settings.sysproxy.* * chore(i18n): pages.profiles.notices/components.providers.notices * refactor(notice): unify showNotice usage * refactor(notice): add typed showNotice shortcuts, centralize defaults, and simplify subscriptions * refactor: unify showNotice usage * refactor(notice): unify showNotice API * refactor(notice): unify showNotice usage * chore(i18n): components.test.* * chore(i18n): components.settings.dns.* * chore(i18n): components.home.clashInfo.* * chore(i18n): components.home.systemInfo.* * chore(i18n): components.home.ipInfo/traffic.* * chore(i18n): navigation.* * refactor(i18n): remove pages.* namespace and migrate route texts under module-level page keys * chore(i18n): common.* * chore(i18n): common.* * fix: change error handling in patch_profiles_config to return false when a switch is in progress * fix: improve error handling in patch_profiles_config to prevent requests during profile switching * fix: change error handling in patch_profiles_config to return false when a switch is in progress fix: ensure CURRENT_SWITCHING_PROFILE is reset after config updates in perform_config_update and patch_profiles_config * chore(i18n): restructure root-level locale keys into namespaces * chore(i18n): add missing i18n keys * docs: i18n guide * chore: adjust i18n * refactor(i18n): align UI actions and status labels with common keys * refactor(i18n): unify two-name locale namespaces * refactor(i18n/components): unify locale keys and update component references * chore(i18n): add shared and entities namespaces to all locale files * refactor(i18n): consolidate shared and entity namespaces across features * chore(deps): update npm dependencies to ^7.3.5 (#5310) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * refactor(i18n): migrate shared editor modes and consolidate entities namespaces * tmp * refactor(i18n): flatten locales and move theme/validation strings * docs: CONTRIBUTING_i18n.md * refactor(i18n): restructure feedback and profile namespaces for better organization * refactor(i18n): unify settings locale structure and update references * refactor(i18n): reorganize locale keys for home, proxies, rules, connections, logs, unlock, and tests * refactor(i18n/feedback/layout): unify shared toasts & normalize layout namespace * refactor(i18n): centralize common UI strings in shared * refactor(i18n): flatten headers and unify locale schema * refactor(i18n): consolidate duplicate per-feature translations into shared namespace * refactor(i18n): split locales into per-namespace files * style: lint * refactor(i18n): unify unlock UI translations under tests namespace * feat(i18n): add type-checked translation keys * style: eslint import order * feat(i18n): replace ad-hoc loader with rust-i18n backend bundles * chore(prebuild): remove locale-copy step * fix(i18n, notice): propagate runtime params and update cleanup script path * fix(i18n,notice): make locale formatting idempotent and guard early notice translations * fix(i18n): resolve locale aliases and match OS codes correctly * fix(unlock): use i18next-compatible double-brace interpolation in failure notice * fix(i18n): route unlock error notices through translation keys * fix(i18n): i18n types * feat(i18n): localize upgrade notice for Clash core viewer * fix(notice): ensure runtime overrides apply to prefix translations * chore(i18n): replace literal notices with translation keys * chore(i18n): types * chore(i18n): regen typings before formatting to keep keys in sync * chore(i18n): simply labels * chore(i18n): adjust translation * chore: remove eslint-plugin-i18next * chore(i18n): add/refine Korean translations across frontend scopes and Rust backend (#5341) * chore(i18n): translate settings.json (missed in previous pass) (#5343) * chore(i18n): add/refine Korean translations across frontend scopes and Rust backend * chore(i18n): add/refine Korean translations across frontend scopes and Rust backend * fix(i18n-tauri): quote placeholder-leading value in ko.yml to prevent rust_i18n parse panic * chore(i18n): translate settings.json (forgot to include previously) --------- Co-authored-by: rozan <34974262+thelojan@users.noreply.github.com>
This commit is contained in:
@@ -227,8 +227,6 @@ fn linux_running_as_root() -> bool {
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
async fn uninstall_service() -> Result<()> {
|
||||
use crate::utils::i18n::t;
|
||||
|
||||
logging!(info, Type::Service, "uninstall service");
|
||||
|
||||
let binary_path = dirs::service_path()?;
|
||||
@@ -240,7 +238,9 @@ async fn uninstall_service() -> Result<()> {
|
||||
|
||||
let uninstall_shell: String = uninstall_path.to_string_lossy().into_owned();
|
||||
|
||||
let prompt = t("Service Administrator Prompt").await;
|
||||
crate::utils::i18n::sync_locale().await;
|
||||
|
||||
let prompt = rust_i18n::t!("service.adminPrompt").to_string();
|
||||
let command = format!(
|
||||
r#"do shell script "sudo '{uninstall_shell}'" with administrator privileges with prompt "{prompt}""#
|
||||
);
|
||||
@@ -263,8 +263,6 @@ async fn uninstall_service() -> Result<()> {
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
async fn install_service() -> Result<()> {
|
||||
use crate::utils::i18n::t;
|
||||
|
||||
logging!(info, Type::Service, "install service");
|
||||
|
||||
let binary_path = dirs::service_path()?;
|
||||
@@ -276,7 +274,9 @@ async fn install_service() -> Result<()> {
|
||||
|
||||
let install_shell: String = install_path.to_string_lossy().into_owned();
|
||||
|
||||
let prompt = t("Service Administrator Prompt").await;
|
||||
crate::utils::i18n::sync_locale().await;
|
||||
|
||||
let prompt = rust_i18n::t!("service.adminPrompt").to_string();
|
||||
let command = format!(
|
||||
r#"do shell script "sudo '{install_shell}'" with administrator privileges with prompt "{prompt}""#
|
||||
);
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
use crate::utils::i18n::t;
|
||||
use std::sync::Arc;
|
||||
use rust_i18n::t;
|
||||
use std::{borrow::Cow, sync::Arc};
|
||||
|
||||
fn to_arc_str(value: Cow<'static, str>) -> Arc<str> {
|
||||
match value {
|
||||
Cow::Borrowed(s) => Arc::from(s),
|
||||
Cow::Owned(s) => Arc::from(s.into_boxed_str()),
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! define_menu {
|
||||
($($field:ident => $const_name:ident, $id:expr, $text:expr),+ $(,)?) => {
|
||||
@@ -11,9 +18,10 @@ macro_rules! define_menu {
|
||||
pub struct MenuIds;
|
||||
|
||||
impl MenuTexts {
|
||||
pub async fn new() -> Self {
|
||||
let ($($field,)+) = futures::join!($(t($text),)+);
|
||||
Self { $($field,)+ }
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
$($field: to_arc_str(t!($text)),)+
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,26 +32,26 @@ macro_rules! define_menu {
|
||||
}
|
||||
|
||||
define_menu! {
|
||||
dashboard => DASHBOARD, "tray_dashboard", "Dashboard",
|
||||
rule_mode => RULE_MODE, "tray_rule_mode", "Rule Mode",
|
||||
global_mode => GLOBAL_MODE, "tray_global_mode", "Global Mode",
|
||||
direct_mode => DIRECT_MODE, "tray_direct_mode", "Direct Mode",
|
||||
profiles => PROFILES, "tray_profiles", "Profiles",
|
||||
proxies => PROXIES, "tray_proxies", "Proxies",
|
||||
system_proxy => SYSTEM_PROXY, "tray_system_proxy", "System Proxy",
|
||||
tun_mode => TUN_MODE, "tray_tun_mode", "TUN Mode",
|
||||
close_all_connections => CLOSE_ALL_CONNECTIONS, "tray_close_all_connections", "Close All Connections",
|
||||
lightweight_mode => LIGHTWEIGHT_MODE, "tray_lightweight_mode", "LightWeight Mode",
|
||||
copy_env => COPY_ENV, "tray_copy_env", "Copy Env",
|
||||
conf_dir => CONF_DIR, "tray_conf_dir", "Conf Dir",
|
||||
core_dir => CORE_DIR, "tray_core_dir", "Core Dir",
|
||||
logs_dir => LOGS_DIR, "tray_logs_dir", "Logs Dir",
|
||||
open_dir => OPEN_DIR, "tray_open_dir", "Open Dir",
|
||||
app_log => APP_LOG, "tray_app_log", "Open App Log",
|
||||
core_log => CORE_LOG, "tray_core_log", "Open Core Log",
|
||||
restart_clash => RESTART_CLASH, "tray_restart_clash", "Restart Clash Core",
|
||||
restart_app => RESTART_APP, "tray_restart_app", "Restart App",
|
||||
verge_version => VERGE_VERSION, "tray_verge_version", "Verge Version",
|
||||
more => MORE, "tray_more", "More",
|
||||
exit => EXIT, "tray_exit", "Exit",
|
||||
dashboard => DASHBOARD, "tray_dashboard", "tray.dashboard",
|
||||
rule_mode => RULE_MODE, "tray_rule_mode", "tray.ruleMode",
|
||||
global_mode => GLOBAL_MODE, "tray_global_mode", "tray.globalMode",
|
||||
direct_mode => DIRECT_MODE, "tray_direct_mode", "tray.directMode",
|
||||
profiles => PROFILES, "tray_profiles", "tray.profiles",
|
||||
proxies => PROXIES, "tray_proxies", "tray.proxies",
|
||||
system_proxy => SYSTEM_PROXY, "tray_system_proxy", "tray.systemProxy",
|
||||
tun_mode => TUN_MODE, "tray_tun_mode", "tray.tunMode",
|
||||
close_all_connections => CLOSE_ALL_CONNECTIONS, "tray_close_all_connections", "tray.closeAllConnections",
|
||||
lightweight_mode => LIGHTWEIGHT_MODE, "tray_lightweight_mode", "tray.lightweightMode",
|
||||
copy_env => COPY_ENV, "tray_copy_env", "tray.copyEnv",
|
||||
conf_dir => CONF_DIR, "tray_conf_dir", "tray.confDir",
|
||||
core_dir => CORE_DIR, "tray_core_dir", "tray.coreDir",
|
||||
logs_dir => LOGS_DIR, "tray_logs_dir", "tray.logsDir",
|
||||
open_dir => OPEN_DIR, "tray_open_dir", "tray.openDir",
|
||||
app_log => APP_LOG, "tray_app_log", "tray.appLog",
|
||||
core_log => CORE_LOG, "tray_core_log", "tray.coreLog",
|
||||
restart_clash => RESTART_CLASH, "tray_restart_clash", "tray.restartClash",
|
||||
restart_app => RESTART_APP, "tray_restart_app", "tray.restartApp",
|
||||
verge_version => VERGE_VERSION, "tray_verge_version", "tray.vergeVersion",
|
||||
more => MORE, "tray_more", "tray.more",
|
||||
exit => EXIT, "tray_exit", "tray.exit",
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ use crate::{
|
||||
feat, logging,
|
||||
module::lightweight::is_in_lightweight_mode,
|
||||
singleton_lazy,
|
||||
utils::{dirs::find_target_icons, i18n::t},
|
||||
utils::{dirs::find_target_icons, i18n},
|
||||
};
|
||||
|
||||
use super::handle;
|
||||
@@ -438,6 +438,8 @@ 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);
|
||||
@@ -464,9 +466,9 @@ impl Tray {
|
||||
}
|
||||
|
||||
// Get localized strings before using them
|
||||
let sys_proxy_text = t("SysProxy").await;
|
||||
let tun_text = t("TUN").await;
|
||||
let profile_text = t("Profile").await;
|
||||
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 v = env!("CARGO_PKG_VERSION");
|
||||
let reassembled_version = v.split_once('+').map_or_else(
|
||||
@@ -622,7 +624,7 @@ async fn create_profile_menu_item(
|
||||
CheckMenuItem::with_id(
|
||||
&app_handle,
|
||||
format!("profiles_{profile_uid}"),
|
||||
t(profile_name).await,
|
||||
profile_name.as_str(),
|
||||
true,
|
||||
is_current_profile,
|
||||
None::<&str>,
|
||||
@@ -817,6 +819,8 @@ async fn create_tray_menu(
|
||||
) -> Result<tauri::menu::Menu<Wry>> {
|
||||
let current_proxy_mode = mode.unwrap_or("");
|
||||
|
||||
i18n::sync_locale().await;
|
||||
|
||||
// 获取当前配置文件的选中代理组信息
|
||||
let current_profile_selected = {
|
||||
let profiles_config = Config::profiles().await;
|
||||
@@ -877,7 +881,7 @@ async fn create_tray_menu(
|
||||
create_profile_menu_item(app_handle, profile_uid_and_name).await?;
|
||||
|
||||
// Pre-fetch all localized strings
|
||||
let texts = &MenuTexts::new().await;
|
||||
let texts = MenuTexts::new();
|
||||
// Convert to references only when needed
|
||||
let profile_menu_items_refs: Vec<&dyn IsMenuItem<Wry>> = profile_menu_items
|
||||
.iter()
|
||||
|
||||
Reference in New Issue
Block a user