mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 17:15:38 +08:00
feat: optimize backend i18n resource usage and improve language loading
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
- 改进 macos 下系统代理设置的方法
|
- 改进 macos 下系统代理设置的方法
|
||||||
- 优化 TUN 模式可用性的判断
|
- 优化 TUN 模式可用性的判断
|
||||||
- 移除流媒体检测的系统级提示(使用软件内通知)
|
- 移除流媒体检测的系统级提示(使用软件内通知)
|
||||||
|
- 优化后端 i18n 资源占用
|
||||||
|
|
||||||
### 🐞 修复问题
|
### 🐞 修复问题
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::{config::Config, utils::dirs};
|
use crate::{config::Config, utils::dirs};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::{collections::HashMap, fs, path::PathBuf};
|
use std::{fs, path::PathBuf, sync::RwLock};
|
||||||
use sys_locale;
|
use sys_locale;
|
||||||
|
|
||||||
const DEFAULT_LANGUAGE: &str = "zh";
|
const DEFAULT_LANGUAGE: &str = "zh";
|
||||||
@@ -33,22 +33,20 @@ pub fn get_supported_languages() -> Vec<String> {
|
|||||||
languages
|
languages
|
||||||
}
|
}
|
||||||
|
|
||||||
static TRANSLATIONS: Lazy<HashMap<String, Value>> = Lazy::new(|| {
|
static TRANSLATIONS: Lazy<RwLock<(String, Value)>> = Lazy::new(|| {
|
||||||
let mut translations = HashMap::new();
|
let lang = get_system_language();
|
||||||
|
let json = load_lang_file(&lang).unwrap_or_else(|| Value::Object(Default::default()));
|
||||||
if let Some(locales_dir) = get_locales_dir() {
|
RwLock::new((lang, json))
|
||||||
for lang in get_supported_languages() {
|
|
||||||
let file_path = locales_dir.join(format!("{lang}.json"));
|
|
||||||
if let Ok(content) = fs::read_to_string(file_path)
|
|
||||||
&& let Ok(json) = serde_json::from_str(&content)
|
|
||||||
{
|
|
||||||
translations.insert(lang.to_string(), json);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
translations
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fn load_lang_file(lang: &str) -> Option<Value> {
|
||||||
|
let locales_dir = get_locales_dir()?;
|
||||||
|
let file_path = locales_dir.join(format!("{lang}.json"));
|
||||||
|
fs::read_to_string(file_path)
|
||||||
|
.ok()
|
||||||
|
.and_then(|content| serde_json::from_str(&content).ok())
|
||||||
|
}
|
||||||
|
|
||||||
fn get_system_language() -> String {
|
fn get_system_language() -> String {
|
||||||
sys_locale::get_locale()
|
sys_locale::get_locale()
|
||||||
.map(|locale| locale.to_lowercase())
|
.map(|locale| locale.to_lowercase())
|
||||||
@@ -58,8 +56,6 @@ fn get_system_language() -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn t(key: &str) -> String {
|
pub async fn t(key: &str) -> String {
|
||||||
let key = key.to_string(); // own the string
|
|
||||||
|
|
||||||
let current_lang = Config::verge()
|
let current_lang = Config::verge()
|
||||||
.await
|
.await
|
||||||
.latest_ref()
|
.latest_ref()
|
||||||
@@ -68,22 +64,35 @@ pub async fn t(key: &str) -> String {
|
|||||||
.map(String::from)
|
.map(String::from)
|
||||||
.unwrap_or_else(get_system_language);
|
.unwrap_or_else(get_system_language);
|
||||||
|
|
||||||
if let Some(text) = TRANSLATIONS
|
|
||||||
.get(¤t_lang)
|
|
||||||
.and_then(|trans| trans.get(&key))
|
|
||||||
.and_then(|val| val.as_str())
|
|
||||||
{
|
{
|
||||||
return text.to_string();
|
if let Ok(cache) = TRANSLATIONS.read()
|
||||||
|
&& cache.0 == current_lang
|
||||||
|
&& let Some(text) = cache.1.get(key).and_then(|val| val.as_str())
|
||||||
|
{
|
||||||
|
return text.to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(new_json) = load_lang_file(¤t_lang)
|
||||||
|
&& let Ok(mut cache) = TRANSLATIONS.write()
|
||||||
|
{
|
||||||
|
*cache = (current_lang.clone(), new_json);
|
||||||
|
|
||||||
|
if let Some(text) = cache.1.get(key).and_then(|val| val.as_str()) {
|
||||||
|
return text.to_string();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if current_lang != DEFAULT_LANGUAGE
|
if current_lang != DEFAULT_LANGUAGE
|
||||||
&& let Some(text) = TRANSLATIONS
|
&& let Some(default_json) = load_lang_file(DEFAULT_LANGUAGE)
|
||||||
.get(DEFAULT_LANGUAGE)
|
&& let Ok(mut cache) = TRANSLATIONS.write()
|
||||||
.and_then(|trans| trans.get(&key))
|
|
||||||
.and_then(|val| val.as_str())
|
|
||||||
{
|
{
|
||||||
return text.to_string();
|
*cache = (DEFAULT_LANGUAGE.to_string(), default_json);
|
||||||
|
|
||||||
|
if let Some(text) = cache.1.get(key).and_then(|val| val.as_str()) {
|
||||||
|
return text.to_string();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
key
|
key.to_string()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user