From abedf5ba5f5c612d42081d3f9a793063735f9d6d Mon Sep 17 00:00:00 2001 From: zeemoh Date: Thu, 27 Aug 2026 18:57:38 +0800 Subject: [PATCH 1/3] feat(i18n): add Simplified Chinese localization --- README.md | 1 + src-tauri/src/commands.rs | 1 + src-tauri/src/i18n.rs | 17 +++- src-tauri/src/watcher.rs | 13 ++- src/components/Settings.tsx | 1 + src/i18n/index.ts | 4 +- src/i18n/locales/zh-CN.json | 172 ++++++++++++++++++++++++++++++++++++ 7 files changed, 204 insertions(+), 5 deletions(-) create mode 100644 src/i18n/locales/zh-CN.json diff --git a/README.md b/README.md index 68fedad..3edce81 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ Auto-detects your system language. Supported: - 🇻🇳 Vietnamese - 🇪🇸 Spanish - 🇺🇦 Ukrainian +- 🇨🇳 Simplified Chinese *(Falls back to English if system language is not supported)* diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index 77b59f8..d77707b 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -27,6 +27,7 @@ pub fn get_system_language() -> String { "ja" => "ja".to_string(), "es" => "es".to_string(), "uk" => "uk".to_string(), + "zh" => "zh-CN".to_string(), _ => "en".to_string(), } } diff --git a/src-tauri/src/i18n.rs b/src-tauri/src/i18n.rs index 0753b13..a847264 100644 --- a/src-tauri/src/i18n.rs +++ b/src-tauri/src/i18n.rs @@ -96,6 +96,18 @@ impl TrayI18n { strings.insert("settings_title", "Configuración de Mouzi"); strings.insert("organized", "{} archivo(s) organizado(s)"); } + "zh-CN" => { + strings.insert("quit", "退出"); + strings.insert("settings", "设置"); + strings.insert("clean_now", "立即整理"); + strings.insert("tooltip", "Mouzi"); + strings.insert("tooltip_one_pending", "Mouzi – {} 个文件等待整理"); + strings.insert("tooltip_many_pending", "Mouzi – {} 个文件等待整理"); + strings.insert("popup_title", "Mouzi"); + strings.insert("settings_title", "Mouzi 设置"); + strings.insert("organized", "已整理 {} 个文件"); + strings.insert("notification_title", "Mouzi – 点击打开文件夹"); + } "uk" => { strings.insert("quit", "Вийти"); strings.insert("settings", "Налаштування"); @@ -123,6 +135,9 @@ impl TrayI18n { } pub fn get<'a>(&self, key: &'a str) -> &'a str { - self.strings.get(key).copied().unwrap_or(key) + self.strings.get(key).copied().unwrap_or_else(|| match key { + "notification_title" => "Mouzi – click to open folder", + _ => key, + }) } } diff --git a/src-tauri/src/watcher.rs b/src-tauri/src/watcher.rs index 88f869a..12f2b54 100644 --- a/src-tauri/src/watcher.rs +++ b/src-tauri/src/watcher.rs @@ -1,4 +1,5 @@ use crate::db::{get_watched_folders, is_folder_manual_mode, is_folder_paused_mode}; +use crate::i18n::TrayI18n; use crate::rules::{is_file_ignored_by_mouziignore, process_file, should_ignore_file}; use notify::{Config, Event, RecommendedWatcher, RecursiveMode, Watcher}; use std::collections::{HashMap, HashSet}; @@ -184,21 +185,27 @@ impl FolderWatcher { // when the user clicks the notification (Windows activates the app) *pending_open_folder.lock().unwrap() = Some(last_dest_folder.clone()); + let lang = crate::db::get_settings() + .map(|settings| settings.language) + .unwrap_or_else(|_| "en".to_string()); + let i18n = TrayI18n::new(&lang); + let notification_title = i18n.get("notification_title").to_string(); let body = if organized_count == 1 { last_notification_message .clone() .unwrap_or_else(|| format!("{} → {}", last_file_name, last_rule_name)) } else { - format!("Organized {} files", organized_count) + i18n.get("organized").replace("{}", &organized_count.to_string()) }; #[cfg(target_os = "windows")] { let dest_folder_clone = last_dest_folder.clone(); let body_clone = body.clone(); + let title_clone = notification_title.clone(); let _ = std::thread::spawn(move || { let _ = tauri_winrt_notification::Toast::new("cc.mouzi.app") - .title("Mouzi – click to open folder") + .title(&title_clone) .text1(&body_clone) .on_activated(move |_action| { // Open the folder in Explorer robustly @@ -216,7 +223,7 @@ impl FolderWatcher { let _ = handle .notification() .builder() - .title("Mouzi – click to open folder") + .title(notification_title) .body(body) .extra("destFolder", last_dest_folder) .show(); diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index ff90d39..4969cde 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -912,6 +912,7 @@ export default function Settings() { +
diff --git a/src/i18n/index.ts b/src/i18n/index.ts index fda7957..2440849 100644 --- a/src/i18n/index.ts +++ b/src/i18n/index.ts @@ -10,6 +10,7 @@ import ja from './locales/ja.json'; import vi from './locales/vi.json'; import es from './locales/es.json'; import uk from './locales/uk.json'; +import zhCN from './locales/zh-CN.json'; const resources = { en: { translation: en }, @@ -22,9 +23,10 @@ const resources = { vi: { translation: vi }, es: { translation: es }, uk: { translation: uk }, + 'zh-CN': { translation: zhCN }, }; -export type SupportedLang = 'en' | 'pl' | 'it' | 'de' | 'fr' | 'ru' | 'ja' | 'vi' | 'es' | 'uk'; +export type SupportedLang = 'en' | 'pl' | 'it' | 'de' | 'fr' | 'ru' | 'ja' | 'vi' | 'es' | 'uk' | 'zh-CN'; export async function initI18n(lang: SupportedLang) { await i18n.use(initReactI18next).init({ diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json new file mode 100644 index 0000000..094ce95 --- /dev/null +++ b/src/i18n/locales/zh-CN.json @@ -0,0 +1,172 @@ +{ + "app": { + "name": "Mouzi", + "tagline": "下载后无需操心,Mouzi 会记得", + "loading": "Mouzi..." + }, + "popup": { + "title": "Mouzi", + "cleanNow": "立即整理", + "organizeNow": "立即整理", + "openDownloads": "打开下载文件夹", + "recentActions": "最近操作", + "noActions": "暂无操作", + "weeklyStats": "本周", + "undo": "撤销", + "settings": "设置", + "quit": "退出", + "organized": "已整理:{{file}}", + "openFolder": "点击打开 → {{folder}}", + "pendingFiles": "{{count}} 个文件等待整理", + "cleanManual": "立即整理", + "selectAll": "全选", + "clearSelection": "清除选择", + "organizeSelected": "整理所选文件({{count}})", + "openActionFolder": "打开目标文件夹" + }, + "settings": { + "title": "Mouzi 设置", + "folders": { + "title": "监视的文件夹", + "add": "添加文件夹", + "remove": "移除", + "mode": "模式", + "silent": "静默", + "suggest": "建议", + "placeholder": "C:/Users/.../Downloads", + "modeSilent": "静默(自动)", + "modeManual": "手动(仅收集)", + "modePaused": "已暂停", + "modeDesc": "选择 Mouzi 处理此文件夹中文件的方式。" + }, + "archive": { + "title": "导入归档文件", + "description": "选择 Google Takeout 的 .zip、.tgz 或 .tar.gz 归档文件。Mouzi 会将其解压,安全地展平重复嵌套的名称,然后执行你的规则。", + "import": "导入归档文件", + "importing": "正在导入归档文件...", + "importingShort": "正在导入...", + "importSuccess": "已解压 {{extracted}} 个文件,并整理 {{count}} 个文件。", + "importError": "导入归档文件失败:{{error}}", + "openImportFolder": "打开导入文件夹" + }, + "rules": { + "title": "规则", + "add": "添加规则", + "edit": "编辑", + "save": "保存", + "delete": "删除", + "name": "名称", + "extensions": "扩展名", + "destination": "目标位置", + "pattern": "匹配模式", + "priority": "优先级", + "action": "操作", + "enabled": "已启用", + "export": "导出规则", + "import": "导入规则", + "exportSuccess": "规则已导出", + "importSuccess": "已导入 {{count}} 条规则", + "importError": "导入规则失败", + "exportError": "导出规则失败", + "replaceOnImport": "替换现有规则(否则追加)", + "pickDestination": "选择目标文件夹", + "actionMove": "移动到文件夹", + "actionRecycle": "移至回收站", + "actionIgnore": "忽略", + "recycleBin": "回收站", + "normalizeExtensions": "规范化文件扩展名", + "normalizeHelp": "移动前映射等效的扩展名,例如 jpeg:jpg。多个映射请用逗号分隔。", + "notificationMessage": "自定义通知", + "notificationPlaceholder": "Mouzi 已移动危险文件:{file}", + "notificationHelp": "可选。可用占位符:{file}、{rule}、{destination}。" + }, + "history": { + "title": "历史记录", + "clear": "清除历史记录", + "undo": "撤销", + "undone": "已撤销", + "empty": "暂无历史记录", + "revertAll": "全部还原", + "revertAllDisabled": "没有可还原的操作", + "confirmTitle": "删除全部历史记录?", + "confirmDescription": "这只会删除 Mouzi 的活动记录,不会移动或删除你的文件。", + "confirmDelete": "删除历史记录" + }, + "general": { + "title": "常规", + "language": "语言", + "theme": "主题", + "themeSystem": "跟随系统", + "themeLight": "浅色", + "themeDark": "深色", + "telemetry": "启用遥测", + "startWithSystem": "开机时启动", + "gracePeriod": "等待时间", + "gracePeriodDesc": "文件最后修改后,等待一段时间再移动。设为 0 表示立即移动。", + "checkFileLock": "检查文件占用", + "checkFileLockDesc": "跳过正被其他进程使用的文件", + "gracePeriodSeconds": "秒", + "gracePeriodMinutes": "分钟", + "gracePeriodHours": "小时", + "gracePeriodCustom": "自定义", + "gracePeriodMaxError": "等待时间不能超过 7 天", + "autoUpdates": "自动检查更新", + "autoUpdatesDesc": "检查 Mouzi 新版本,并提供一键安装。" + }, + "ignore": { + "title": "忽略", + "rulesTitle": "忽略规则", + "description": "选择一个监视的文件夹,并设置 Mouzi 应跳过的文件匹配模式。匹配模式将保存到该文件夹中的 .mouziignore 文件。", + "folder": "文件夹", + "selectFolder": "选择文件夹...", + "patterns": "匹配模式", + "noRules": "暂无忽略规则。请在下方添加。", + "placeholder": "例如 *.tmp 或 node_modules/", + "add": "添加", + "tips": "提示:", + "save": "保存 .mouziignore", + "saved": "已保存!", + "remove": "移除" + }, + "about": { + "title": "关于", + "tagline": "让下载文件井然有序。", + "description": "Mouzi 是一款安静、简洁的文件整理工具。它驻留在系统托盘中,自动保持下载文件夹及其他文件夹整洁。它会在后台静默运行,监视选定的文件夹,并根据自定义规则移动、重命名或分类文件。", + "checkUpdates": "检查更新", + "support": "在 Ko-fi 上支持 Mouzi", + "supportDesc": "你的支持会帮助 Mouzi 持续改进。谢谢!🙏", + "versionLabel": "版本", + "releaseDateLabel": "发布日期", + "builtBy": "由 hsr 用心打造" + }, + "scheduler": { + "title": "定时任务", + "enable": "启用定时整理", + "timesPerDay": "每天执行次数", + "time": "时间 {{number}}", + "desc": "在设定的时间自动整理文件。", + "once": "每天一次", + "twice": "每天两次", + "thrice": "每天 3 次", + "fourTimes": "每天 4 次" + } + }, + "notifications": { + "cleaned": "已整理 {{count}} 个文件" + }, + "common": { + "cancel": "取消", + "off": "关闭", + "close": "关闭", + "back": "返回" + }, + "updater": { + "available": "Mouzi {{version}} 可用", + "checking": "正在检查更新...", + "current": "你已经在使用最新版本。", + "error": "无法检查更新,请稍后重试。", + "installVersion": "安装 Mouzi {{version}}", + "installRestart": "安装并重启", + "installing": "正在安装更新..." + } +} From dacfc618243b110693ffb39075cc3ccd92c49c49 Mon Sep 17 00:00:00 2001 From: zeemoh Date: Thu, 27 Aug 2026 21:19:34 +0800 Subject: [PATCH 2/3] fix(i18n): distinguish Chinese locale variants --- src-tauri/src/commands.rs | 78 +++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index d77707b..991d743 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -17,18 +17,72 @@ pub fn greet(name: &str) -> String { #[tauri::command] pub fn get_system_language() -> String { let locale = sys_locale::get_locale().unwrap_or_else(|| "en".to_string()); - let lang = locale.split('-').next().unwrap_or("en").to_lowercase(); - match lang.as_str() { - "pl" => "pl".to_string(), - "it" => "it".to_string(), - "de" => "de".to_string(), - "fr" => "fr".to_string(), - "ru" => "ru".to_string(), - "ja" => "ja".to_string(), - "es" => "es".to_string(), - "uk" => "uk".to_string(), - "zh" => "zh-CN".to_string(), - _ => "en".to_string(), + map_system_locale(&locale).to_string() +} + +fn map_system_locale(locale: &str) -> &'static str { + let normalized = locale.replace('_', "-").to_lowercase(); + let mut parts = normalized.split('-'); + let language = parts.next().unwrap_or("en"); + + if language == "zh" { + let variants: Vec<&str> = parts.collect(); + + if variants.contains(&"hant") { + return "en"; + } + if variants.contains(&"hans") { + return "zh-CN"; + } + if variants + .iter() + .any(|part| matches!(*part, "tw" | "hk" | "mo")) + { + return "en"; + } + if variants.iter().any(|part| matches!(*part, "cn" | "sg")) { + return "zh-CN"; + } + + return "en"; + } + + match language { + "pl" => "pl", + "it" => "it", + "de" => "de", + "fr" => "fr", + "ru" => "ru", + "ja" => "ja", + "es" => "es", + "uk" => "uk", + _ => "en", + } +} + +#[cfg(test)] +mod locale_tests { + use super::map_system_locale; + + #[test] + fn maps_simplified_chinese_variants_to_zh_cn() { + for locale in ["zh-CN", "zh-SG", "zh-Hans", "zh-Hans-CN", "zh_CN"] { + assert_eq!(map_system_locale(locale), "zh-CN", "locale: {locale}"); + } + } + + #[test] + fn falls_back_for_traditional_and_ambiguous_chinese_locales() { + for locale in ["zh-TW", "zh-HK", "zh-MO", "zh-Hant", "zh-Hant-TW", "zh"] { + assert_eq!(map_system_locale(locale), "en", "locale: {locale}"); + } + } + + #[test] + fn preserves_existing_supported_language_mapping() { + assert_eq!(map_system_locale("pl-PL"), "pl"); + assert_eq!(map_system_locale("ja_JP"), "ja"); + assert_eq!(map_system_locale("en-US"), "en"); } } From dd1e925cca09eac175e7c32783fcff7a459853ce Mon Sep 17 00:00:00 2001 From: zeemoh Date: Thu, 27 Aug 2026 21:58:20 +0800 Subject: [PATCH 3/3] fix: keep notification title in default locale map --- src-tauri/src/i18n.rs | 285 +++++++++++++++++++++--------------------- 1 file changed, 142 insertions(+), 143 deletions(-) diff --git a/src-tauri/src/i18n.rs b/src-tauri/src/i18n.rs index a847264..107a327 100644 --- a/src-tauri/src/i18n.rs +++ b/src-tauri/src/i18n.rs @@ -1,143 +1,142 @@ -use std::collections::HashMap; - -pub struct TrayI18n { - strings: HashMap<&'static str, &'static str>, -} - -impl TrayI18n { - pub fn new(lang: &str) -> Self { - let mut strings = HashMap::new(); - match lang { - "pl" => { - strings.insert("quit", "Zamknij"); - strings.insert("settings", "Ustawienia"); - strings.insert("clean_now", "Uporządkuj teraz"); - strings.insert("tooltip", "Mouzi"); - strings.insert("tooltip_one_pending", "Mouzi – {} plik czeka"); - strings.insert("tooltip_many_pending", "Mouzi – {} pliki czekają"); - strings.insert("popup_title", "Mouzi"); - strings.insert("settings_title", "Ustawienia Mouzi"); - strings.insert("organized", "Uporządkowano {} plik(i)"); - } - "it" => { - strings.insert("quit", "Esci"); - strings.insert("settings", "Impostazioni"); - strings.insert("clean_now", "Organizza ora"); - strings.insert("tooltip", "Mouzi"); - strings.insert("tooltip_one_pending", "Mouzi – {} file in attesa"); - strings.insert("tooltip_many_pending", "Mouzi – {} file in attesa"); - strings.insert("popup_title", "Mouzi"); - strings.insert("settings_title", "Impostazioni Mouzi"); - strings.insert("organized", "Organizzati {} file"); - } - "de" => { - strings.insert("quit", "Beenden"); - strings.insert("settings", "Einstellungen"); - strings.insert("clean_now", "Jetzt organisieren"); - strings.insert("tooltip", "Mouzi"); - strings.insert("tooltip_one_pending", "Mouzi – {} Datei wartend"); - strings.insert("tooltip_many_pending", "Mouzi – {} Dateien wartend"); - strings.insert("popup_title", "Mouzi"); - strings.insert("settings_title", "Mouzi Einstellungen"); - strings.insert("organized", "{} Datei(en) organisiert"); - } - "fr" => { - strings.insert("quit", "Quitter"); - strings.insert("settings", "Paramètres"); - strings.insert("clean_now", "Organiser maintenant"); - strings.insert("tooltip", "Mouzi"); - strings.insert("tooltip_one_pending", "Mouzi – {} fichier en attente"); - strings.insert("tooltip_many_pending", "Mouzi – {} fichiers en attente"); - strings.insert("popup_title", "Mouzi"); - strings.insert("settings_title", "Paramètres Mouzi"); - strings.insert("organized", "{} fichier(s) organisé(s)"); - } - "ru" => { - strings.insert("quit", "Выход"); - strings.insert("settings", "Настройки"); - strings.insert("clean_now", "Организовать сейчас"); - strings.insert("tooltip", "Mouzi"); - strings.insert("tooltip_one_pending", "Mouzi – {} файл ожидает"); - strings.insert("tooltip_many_pending", "Mouzi – {} файла ожидают"); - strings.insert("popup_title", "Mouzi"); - strings.insert("settings_title", "Настройки Mouzi"); - strings.insert("organized", "Организовано {} файл(ов)"); - } - "ja" => { - strings.insert("quit", "終了"); - strings.insert("settings", "設定"); - strings.insert("clean_now", "今すぐ整理"); - strings.insert("tooltip", "Mouzi"); - strings.insert("tooltip_one_pending", "Mouzi – {} 個のファイルが待機中"); - strings.insert("tooltip_many_pending", "Mouzi – {} 個のファイルが待機中"); - strings.insert("popup_title", "Mouzi"); - strings.insert("settings_title", "Mouziの設定"); - strings.insert("organized", "{}個のファイルを整理しました"); - } - "vi" => { - strings.insert("quit", "Thoát"); - strings.insert("settings", "Cài đặt"); - strings.insert("clean_now", "Sắp xếp ngay"); - strings.insert("tooltip", "Mouzi"); - strings.insert("tooltip_one_pending", "Mouzi – {} tệp đang chờ"); - strings.insert("tooltip_many_pending", "Mouzi – {} tệp đang chờ"); - strings.insert("popup_title", "Mouzi"); - strings.insert("settings_title", "Cài đặt Mouzi"); - strings.insert("organized", "Đã sắp xếp {} tệp"); - } - "es" => { - strings.insert("quit", "Salir"); - strings.insert("settings", "Configuración"); - strings.insert("clean_now", "Organizar ahora"); - strings.insert("tooltip", "Mouzi"); - strings.insert("tooltip_one_pending", "Mouzi – {} archivo esperando"); - strings.insert("tooltip_many_pending", "Mouzi – {} archivos esperando"); - strings.insert("popup_title", "Mouzi"); - strings.insert("settings_title", "Configuración de Mouzi"); - strings.insert("organized", "{} archivo(s) organizado(s)"); - } - "zh-CN" => { - strings.insert("quit", "退出"); - strings.insert("settings", "设置"); - strings.insert("clean_now", "立即整理"); - strings.insert("tooltip", "Mouzi"); - strings.insert("tooltip_one_pending", "Mouzi – {} 个文件等待整理"); - strings.insert("tooltip_many_pending", "Mouzi – {} 个文件等待整理"); - strings.insert("popup_title", "Mouzi"); - strings.insert("settings_title", "Mouzi 设置"); - strings.insert("organized", "已整理 {} 个文件"); - strings.insert("notification_title", "Mouzi – 点击打开文件夹"); - } - "uk" => { - strings.insert("quit", "Вийти"); - strings.insert("settings", "Налаштування"); - strings.insert("clean_now", "Упорядкувати зараз"); - strings.insert("tooltip", "Mouzi"); - strings.insert("tooltip_one_pending", "Mouzi — очікує {} файл"); - strings.insert("tooltip_many_pending", "Mouzi — очікує файлів: {}"); - strings.insert("popup_title", "Mouzi"); - strings.insert("settings_title", "Налаштування Mouzi"); - strings.insert("organized", "Впорядковано файлів: {}"); - } - _ => { - strings.insert("quit", "Quit"); - strings.insert("settings", "Settings"); - strings.insert("clean_now", "Organize Now"); - strings.insert("tooltip", "Mouzi"); - strings.insert("tooltip_one_pending", "Mouzi – {} file waiting"); - strings.insert("tooltip_many_pending", "Mouzi – {} files waiting"); - strings.insert("popup_title", "Mouzi"); - strings.insert("settings_title", "Mouzi Settings"); - strings.insert("organized", "Organized {} file(s)"); - } - } - Self { strings } - } - - pub fn get<'a>(&self, key: &'a str) -> &'a str { - self.strings.get(key).copied().unwrap_or_else(|| match key { - "notification_title" => "Mouzi – click to open folder", - _ => key, - }) - } -} +use std::collections::HashMap; + +pub struct TrayI18n { + strings: HashMap<&'static str, &'static str>, +} + +impl TrayI18n { + pub fn new(lang: &str) -> Self { + let mut strings = HashMap::new(); + match lang { + "pl" => { + strings.insert("quit", "Zamknij"); + strings.insert("settings", "Ustawienia"); + strings.insert("clean_now", "Uporządkuj teraz"); + strings.insert("tooltip", "Mouzi"); + strings.insert("tooltip_one_pending", "Mouzi – {} plik czeka"); + strings.insert("tooltip_many_pending", "Mouzi – {} pliki czekają"); + strings.insert("popup_title", "Mouzi"); + strings.insert("settings_title", "Ustawienia Mouzi"); + strings.insert("organized", "Uporządkowano {} plik(i)"); + } + "it" => { + strings.insert("quit", "Esci"); + strings.insert("settings", "Impostazioni"); + strings.insert("clean_now", "Organizza ora"); + strings.insert("tooltip", "Mouzi"); + strings.insert("tooltip_one_pending", "Mouzi – {} file in attesa"); + strings.insert("tooltip_many_pending", "Mouzi – {} file in attesa"); + strings.insert("popup_title", "Mouzi"); + strings.insert("settings_title", "Impostazioni Mouzi"); + strings.insert("organized", "Organizzati {} file"); + } + "de" => { + strings.insert("quit", "Beenden"); + strings.insert("settings", "Einstellungen"); + strings.insert("clean_now", "Jetzt organisieren"); + strings.insert("tooltip", "Mouzi"); + strings.insert("tooltip_one_pending", "Mouzi – {} Datei wartend"); + strings.insert("tooltip_many_pending", "Mouzi – {} Dateien wartend"); + strings.insert("popup_title", "Mouzi"); + strings.insert("settings_title", "Mouzi Einstellungen"); + strings.insert("organized", "{} Datei(en) organisiert"); + } + "fr" => { + strings.insert("quit", "Quitter"); + strings.insert("settings", "Paramètres"); + strings.insert("clean_now", "Organiser maintenant"); + strings.insert("tooltip", "Mouzi"); + strings.insert("tooltip_one_pending", "Mouzi – {} fichier en attente"); + strings.insert("tooltip_many_pending", "Mouzi – {} fichiers en attente"); + strings.insert("popup_title", "Mouzi"); + strings.insert("settings_title", "Paramètres Mouzi"); + strings.insert("organized", "{} fichier(s) organisé(s)"); + } + "ru" => { + strings.insert("quit", "Выход"); + strings.insert("settings", "Настройки"); + strings.insert("clean_now", "Организовать сейчас"); + strings.insert("tooltip", "Mouzi"); + strings.insert("tooltip_one_pending", "Mouzi – {} файл ожидает"); + strings.insert("tooltip_many_pending", "Mouzi – {} файла ожидают"); + strings.insert("popup_title", "Mouzi"); + strings.insert("settings_title", "Настройки Mouzi"); + strings.insert("organized", "Организовано {} файл(ов)"); + } + "ja" => { + strings.insert("quit", "終了"); + strings.insert("settings", "設定"); + strings.insert("clean_now", "今すぐ整理"); + strings.insert("tooltip", "Mouzi"); + strings.insert("tooltip_one_pending", "Mouzi – {} 個のファイルが待機中"); + strings.insert("tooltip_many_pending", "Mouzi – {} 個のファイルが待機中"); + strings.insert("popup_title", "Mouzi"); + strings.insert("settings_title", "Mouziの設定"); + strings.insert("organized", "{}個のファイルを整理しました"); + } + "vi" => { + strings.insert("quit", "Thoát"); + strings.insert("settings", "Cài đặt"); + strings.insert("clean_now", "Sắp xếp ngay"); + strings.insert("tooltip", "Mouzi"); + strings.insert("tooltip_one_pending", "Mouzi – {} tệp đang chờ"); + strings.insert("tooltip_many_pending", "Mouzi – {} tệp đang chờ"); + strings.insert("popup_title", "Mouzi"); + strings.insert("settings_title", "Cài đặt Mouzi"); + strings.insert("organized", "Đã sắp xếp {} tệp"); + } + "es" => { + strings.insert("quit", "Salir"); + strings.insert("settings", "Configuración"); + strings.insert("clean_now", "Organizar ahora"); + strings.insert("tooltip", "Mouzi"); + strings.insert("tooltip_one_pending", "Mouzi – {} archivo esperando"); + strings.insert("tooltip_many_pending", "Mouzi – {} archivos esperando"); + strings.insert("popup_title", "Mouzi"); + strings.insert("settings_title", "Configuración de Mouzi"); + strings.insert("organized", "{} archivo(s) organizado(s)"); + } + "zh-CN" => { + strings.insert("quit", "退出"); + strings.insert("settings", "设置"); + strings.insert("clean_now", "立即整理"); + strings.insert("tooltip", "Mouzi"); + strings.insert("tooltip_one_pending", "Mouzi – {} 个文件等待整理"); + strings.insert("tooltip_many_pending", "Mouzi – {} 个文件等待整理"); + strings.insert("popup_title", "Mouzi"); + strings.insert("settings_title", "Mouzi 设置"); + strings.insert("organized", "已整理 {} 个文件"); + strings.insert("notification_title", "Mouzi – 点击打开文件夹"); + } + "uk" => { + strings.insert("quit", "Вийти"); + strings.insert("settings", "Налаштування"); + strings.insert("clean_now", "Упорядкувати зараз"); + strings.insert("tooltip", "Mouzi"); + strings.insert("tooltip_one_pending", "Mouzi — очікує {} файл"); + strings.insert("tooltip_many_pending", "Mouzi — очікує файлів: {}"); + strings.insert("popup_title", "Mouzi"); + strings.insert("settings_title", "Налаштування Mouzi"); + strings.insert("organized", "Впорядковано файлів: {}"); + } + _ => { + strings.insert("quit", "Quit"); + strings.insert("settings", "Settings"); + strings.insert("clean_now", "Organize Now"); + strings.insert("tooltip", "Mouzi"); + strings.insert("tooltip_one_pending", "Mouzi – {} file waiting"); + strings.insert("tooltip_many_pending", "Mouzi – {} files waiting"); + strings.insert("popup_title", "Mouzi"); + strings.insert("settings_title", "Mouzi Settings"); + strings.insert("organized", "Organized {} file(s)"); + strings.insert("notification_title", "Mouzi – click to open folder"); + } + } + Self { strings } + } + + pub fn get<'a>(&self, key: &'a str) -> &'a str { + self.strings.get(key).copied().unwrap_or(key) + } +} +