汉化
This commit is contained in:
119
src-tauri/Cargo.lock
generated
119
src-tauri/Cargo.lock
generated
@@ -625,11 +625,14 @@ dependencies = [
|
||||
"cocoa",
|
||||
"dirs 5.0.1",
|
||||
"env_logger",
|
||||
"fluent",
|
||||
"fluent-bundle",
|
||||
"futures",
|
||||
"glob",
|
||||
"libc",
|
||||
"log",
|
||||
"objc",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"rusqlite",
|
||||
@@ -650,6 +653,7 @@ dependencies = [
|
||||
"tauri-plugin-updater",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"unic-langid",
|
||||
"uuid",
|
||||
"walkdir",
|
||||
"which",
|
||||
@@ -1333,6 +1337,50 @@ dependencies = [
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluent"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb74634707bebd0ce645a981148e8fb8c7bccd4c33c652aeffd28bf2f96d555a"
|
||||
dependencies = [
|
||||
"fluent-bundle",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluent-bundle"
|
||||
version = "0.15.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fe0a21ee80050c678013f82edf4b705fe2f26f1f9877593d13198612503f493"
|
||||
dependencies = [
|
||||
"fluent-langneg",
|
||||
"fluent-syntax",
|
||||
"intl-memoizer",
|
||||
"intl_pluralrules",
|
||||
"rustc-hash 1.1.0",
|
||||
"self_cell 0.10.3",
|
||||
"smallvec",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluent-langneg"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94"
|
||||
dependencies = [
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fluent-syntax"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a530c4694a6a8d528794ee9bbd8ba0122e779629ac908d15ad5a7ae7763a33d"
|
||||
dependencies = [
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
@@ -2243,6 +2291,25 @@ dependencies = [
|
||||
"cfb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "intl-memoizer"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "310da2e345f5eb861e7a07ee182262e94975051db9e4223e909ba90f392f163f"
|
||||
dependencies = [
|
||||
"type-map",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "intl_pluralrules"
|
||||
version = "7.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972"
|
||||
dependencies = [
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.11.0"
|
||||
@@ -3604,7 +3671,7 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustc-hash",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustls",
|
||||
"socket2",
|
||||
"thiserror 2.0.12",
|
||||
@@ -3624,7 +3691,7 @@ dependencies = [
|
||||
"lru-slab",
|
||||
"rand 0.9.1",
|
||||
"ring",
|
||||
"rustc-hash",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"slab",
|
||||
@@ -3947,6 +4014,12 @@ version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
@@ -4129,6 +4202,21 @@ dependencies = [
|
||||
"thin-slice",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "self_cell"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d"
|
||||
dependencies = [
|
||||
"self_cell 1.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "self_cell"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.26"
|
||||
@@ -5428,6 +5516,15 @@ version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||
|
||||
[[package]]
|
||||
name = "type-map"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90"
|
||||
dependencies = [
|
||||
"rustc-hash 2.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typeid"
|
||||
version = "1.0.3"
|
||||
@@ -5472,6 +5569,24 @@ version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
|
||||
|
||||
[[package]]
|
||||
name = "unic-langid"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a28ba52c9b05311f4f6e62d5d9d46f094bd6e84cb8df7b3ef952748d752a7d05"
|
||||
dependencies = [
|
||||
"unic-langid-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-langid-impl"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dce1bf08044d4b7a94028c93786f8566047edc11110595914de93362559bc658"
|
||||
dependencies = [
|
||||
"tinystr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-ucd-ident"
|
||||
version = "0.9.0"
|
||||
|
@@ -53,6 +53,10 @@ zstd = "0.13"
|
||||
uuid = { version = "1.6", features = ["v4", "serde"] }
|
||||
walkdir = "2"
|
||||
serde_yaml = "0.9"
|
||||
fluent = "0.16"
|
||||
fluent-bundle = "0.15"
|
||||
unic-langid = "0.9"
|
||||
once_cell = "1.19"
|
||||
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
|
44
src-tauri/locales/en/messages.ftl
Normal file
44
src-tauri/locales/en/messages.ftl
Normal file
@@ -0,0 +1,44 @@
|
||||
# Error Messages
|
||||
error-failed-to-create = Failed to create {$item}
|
||||
error-failed-to-update = Failed to update {$item}
|
||||
error-failed-to-delete = Failed to delete {$item}
|
||||
error-failed-to-read = Failed to read {$item}
|
||||
error-failed-to-write = Failed to write to {$item}
|
||||
error-file-not-found = File not found: {$path}
|
||||
error-permission-denied = Permission denied
|
||||
error-invalid-input = Invalid input provided
|
||||
error-network-error = Network error occurred
|
||||
error-database-error = Database error occurred
|
||||
error-unknown-error = Unknown error occurred
|
||||
|
||||
# Success Messages
|
||||
success-created = {$item} created successfully
|
||||
success-updated = {$item} updated successfully
|
||||
success-deleted = {$item} deleted successfully
|
||||
success-saved = Saved successfully
|
||||
|
||||
# Agent Messages
|
||||
agent-not-found = Agent not found
|
||||
agent-execution-failed = Agent execution failed
|
||||
agent-invalid-config = Invalid agent configuration
|
||||
|
||||
# Claude Messages
|
||||
claude-not-installed = Claude Code is not installed
|
||||
claude-version-check-failed = Failed to check Claude version
|
||||
claude-execution-failed = Claude execution failed
|
||||
claude-session-not-found = Claude session not found
|
||||
|
||||
# MCP Messages
|
||||
mcp-server-not-found = MCP server not found
|
||||
mcp-connection-failed = Failed to connect to MCP server
|
||||
mcp-invalid-config = Invalid MCP server configuration
|
||||
|
||||
# Project Messages
|
||||
project-not-found = Project not found
|
||||
project-access-denied = Access denied to project
|
||||
session-not-found = Session not found
|
||||
|
||||
# General Messages
|
||||
operation-cancelled = Operation cancelled
|
||||
timeout-error = Operation timed out
|
||||
validation-error = Validation failed
|
44
src-tauri/locales/zh/messages.ftl
Normal file
44
src-tauri/locales/zh/messages.ftl
Normal file
@@ -0,0 +1,44 @@
|
||||
# 错误消息
|
||||
error-failed-to-create = 创建{$item}失败
|
||||
error-failed-to-update = 更新{$item}失败
|
||||
error-failed-to-delete = 删除{$item}失败
|
||||
error-failed-to-read = 读取{$item}失败
|
||||
error-failed-to-write = 写入{$item}失败
|
||||
error-file-not-found = 未找到文件:{$path}
|
||||
error-permission-denied = 权限被拒绝
|
||||
error-invalid-input = 提供的输入无效
|
||||
error-network-error = 发生网络错误
|
||||
error-database-error = 发生数据库错误
|
||||
error-unknown-error = 发生未知错误
|
||||
|
||||
# 成功消息
|
||||
success-created = {$item}创建成功
|
||||
success-updated = {$item}更新成功
|
||||
success-deleted = {$item}删除成功
|
||||
success-saved = 保存成功
|
||||
|
||||
# 智能体消息
|
||||
agent-not-found = 未找到智能体
|
||||
agent-execution-failed = 智能体执行失败
|
||||
agent-invalid-config = 智能体配置无效
|
||||
|
||||
# Claude 消息
|
||||
claude-not-installed = 未安装 Claude Code
|
||||
claude-version-check-failed = 检查 Claude 版本失败
|
||||
claude-execution-failed = Claude 执行失败
|
||||
claude-session-not-found = 未找到 Claude 会话
|
||||
|
||||
# MCP 消息
|
||||
mcp-server-not-found = 未找到 MCP 服务器
|
||||
mcp-connection-failed = 连接 MCP 服务器失败
|
||||
mcp-invalid-config = MCP 服务器配置无效
|
||||
|
||||
# 项目消息
|
||||
project-not-found = 未找到项目
|
||||
project-access-denied = 拒绝访问项目
|
||||
session-not-found = 未找到会话
|
||||
|
||||
# 通用消息
|
||||
operation-cancelled = 操作已取消
|
||||
timeout-error = 操作超时
|
||||
validation-error = 验证失败
|
27
src-tauri/src/commands/language.rs
Normal file
27
src-tauri/src/commands/language.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
use tauri::command;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::i18n;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct LanguageSettings {
|
||||
pub locale: String,
|
||||
}
|
||||
|
||||
#[command]
|
||||
pub async fn get_current_language() -> Result<String, String> {
|
||||
Ok(i18n::get_current_locale())
|
||||
}
|
||||
|
||||
#[command]
|
||||
pub async fn set_language(locale: String) -> Result<(), String> {
|
||||
i18n::set_locale(&locale)
|
||||
.map_err(|e| format!("Failed to set language: {}", e))?;
|
||||
|
||||
log::info!("Language changed to: {}", locale);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[command]
|
||||
pub async fn get_supported_languages() -> Result<Vec<String>, String> {
|
||||
Ok(i18n::SUPPORTED_LOCALES.iter().map(|&s| s.to_string()).collect())
|
||||
}
|
@@ -5,3 +5,4 @@ pub mod usage;
|
||||
pub mod storage;
|
||||
pub mod slash_commands;
|
||||
pub mod proxy;
|
||||
pub mod language;
|
||||
|
77
src-tauri/src/i18n.rs
Normal file
77
src-tauri/src/i18n.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use std::sync::{Arc, Mutex, OnceLock};
|
||||
|
||||
// 支持的语言
|
||||
pub const SUPPORTED_LOCALES: &[&str] = &["en-US", "zh-CN"];
|
||||
|
||||
// 简化的 I18n 实现,避免线程安全问题
|
||||
pub struct SimpleI18n {
|
||||
current_locale: Arc<Mutex<String>>,
|
||||
}
|
||||
|
||||
impl SimpleI18n {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
current_locale: Arc::new(Mutex::new("en-US".to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_locale(&self, locale: &str) {
|
||||
if SUPPORTED_LOCALES.contains(&locale) {
|
||||
if let Ok(mut current) = self.current_locale.lock() {
|
||||
*current = locale.to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_current_locale(&self) -> String {
|
||||
match self.current_locale.lock() {
|
||||
Ok(locale) => locale.clone(),
|
||||
Err(_) => "en-US".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn t(&self, key: &str) -> String {
|
||||
let locale = self.get_current_locale();
|
||||
|
||||
// 简单的翻译映射,避免复杂的 FluentBundle
|
||||
match (locale.as_str(), key) {
|
||||
// 英文翻译
|
||||
("en-US", "error-failed-to-create") => "Failed to create".to_string(),
|
||||
("en-US", "error-failed-to-update") => "Failed to update".to_string(),
|
||||
("en-US", "error-failed-to-delete") => "Failed to delete".to_string(),
|
||||
("en-US", "agent-not-found") => "Agent not found".to_string(),
|
||||
("en-US", "claude-not-installed") => "Claude Code is not installed".to_string(),
|
||||
|
||||
// 中文翻译
|
||||
("zh-CN", "error-failed-to-create") => "创建失败".to_string(),
|
||||
("zh-CN", "error-failed-to-update") => "更新失败".to_string(),
|
||||
("zh-CN", "error-failed-to-delete") => "删除失败".to_string(),
|
||||
("zh-CN", "agent-not-found") => "未找到智能体".to_string(),
|
||||
("zh-CN", "claude-not-installed") => "未安装 Claude Code".to_string(),
|
||||
|
||||
// 默认情况
|
||||
_ => key.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 全局实例
|
||||
static GLOBAL_I18N: OnceLock<SimpleI18n> = OnceLock::new();
|
||||
|
||||
fn get_i18n() -> &'static SimpleI18n {
|
||||
GLOBAL_I18N.get_or_init(|| SimpleI18n::new())
|
||||
}
|
||||
|
||||
// 便捷函数用于全局访问
|
||||
pub fn t(key: &str) -> String {
|
||||
get_i18n().t(key)
|
||||
}
|
||||
|
||||
pub fn set_locale(locale: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
get_i18n().set_locale(locale);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_current_locale() -> String {
|
||||
get_i18n().get_current_locale()
|
||||
}
|
@@ -5,6 +5,7 @@ pub mod checkpoint;
|
||||
pub mod claude_binary;
|
||||
pub mod commands;
|
||||
pub mod process;
|
||||
pub mod i18n;
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
|
@@ -5,6 +5,7 @@ mod checkpoint;
|
||||
mod claude_binary;
|
||||
mod commands;
|
||||
mod process;
|
||||
mod i18n;
|
||||
|
||||
use checkpoint::state::CheckpointState;
|
||||
use commands::agents::{
|
||||
@@ -43,6 +44,7 @@ use commands::storage::{
|
||||
storage_insert_row, storage_execute_sql, storage_reset_database,
|
||||
};
|
||||
use commands::proxy::{get_proxy_settings, save_proxy_settings, apply_proxy_settings};
|
||||
use commands::language::{get_current_language, set_language, get_supported_languages};
|
||||
use process::ProcessRegistryState;
|
||||
use std::sync::Mutex;
|
||||
use tauri::Manager;
|
||||
@@ -249,6 +251,11 @@ fn main() {
|
||||
// Proxy Settings
|
||||
get_proxy_settings,
|
||||
save_proxy_settings,
|
||||
|
||||
// Language Settings
|
||||
get_current_language,
|
||||
set_language,
|
||||
get_supported_languages,
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
Reference in New Issue
Block a user