This commit is contained in:
2025-08-06 11:32:29 +08:00
parent 90afd6e520
commit 351a79d54c
21 changed files with 915 additions and 16 deletions

View 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())
}

View File

@@ -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
View 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()
}

View File

@@ -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() {

View File

@@ -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");