Memories / 文档

本页目录

本地化

Flutter 客户端和 CLI 支持英语(en)、简体中文(zh)、日语(ja)、德语(de)和法语(fr)。英语为回退语言。中文系统语言变体均使用简体中文翻译。

Web 客户端与注册邮件

托管 Web 客户端和验证邮件支持英语(en)、简体中文(zh-CN)、繁体中文(zh-TW)、日语(ja)、法语(fr)、德语(de)和西班牙语(es)。这一集合独立于原生客户端的语言集合。Web 语言选择器在登录前即可使用,且只保存语言偏好。没有已保存偏好时使用浏览器语言;不支持的语言回退到英语。zh-Hant、zh-HK 和 zh-MO 使用繁体中文;显式 zh-Hans 使用简体中文。

Web 文案位于 website/app/i18n.mjs。每个语言目录都应添加相同的键。注册请求将 locale 发送给 Center;crates/center/src/saas/accounts/email.rs 中的邮件主题和正文使用该请求的语言。未提供此字段的现有客户端收到英语邮件。验证码保持不变。待处理验证码复用与节流规则跨语言变更适用。独立文档网站以同样的七种语言提供每份指南和隐私政策。切换语言会保留当前文档和所在章节。

Flutter

mobile/l10n.yaml 配置 Flutter 官方本地化生成器。在 mobile/lib/l10n/app_en.arb 添加消息,并在其他四个 ARB 文件中翻译相同的键。使用描述性键和命名占位符表达完整消息;计数影响措辞时使用 ICU 复数。在英语模板中声明占位符类型。编辑资源后运行 flutter gen-l10n。

组件通过 context.l10n 获取字符串。资料库状态在 didChangeDependencies 中刷新本地化引用,使异步操作能够使用字符串,而无需跨 await 保留 BuildContext。flutter_localizations 提供 Material/Cupertino 标签,intl 格式化日期和计数。在 preferred-supported-locales 中将英语放在首位,使未知系统语言具有确定的回退行为。iOS 在 Runner/Info.plist 中声明支持的语言。

语言菜单在解锁前即可使用。SharedPreferences 只存储非秘密的 language 偏好;system 会删除该偏好。保存失败时保留现有选择并显示本地化错误。切换语言不会重新创建后端或改变已解锁会话。没有已保存偏好时,应用运行期间的系统语言变更会更新界面和字体回退。已保存的选择会保持固定,直到手动更改或重置为系统默认值。

本地错误在显示时翻译,因此现有提示横幅会随语言改变。原生错误使用稳定错误码提供翻译后的回退文案。不要翻译协议值、标识符、URL、账号元数据、用户标题、正文、标签、关系、签名审计记录或秘密值。受保护预览必须继续使用 protected_cards.dart 中明确的字段允许列表和固定遮罩。

CLI

crates/cli/src/i18n.rs 在 Clap 渲染帮助之前确定语言。优先级为:

  1. --lang en|zh|ja|de|fr,顶层与子命令均支持。
  2. 非空的 MEMORIES_LANG。
  3. 所选 Memories 主目录内保存的偏好。
  4. LC_ALL、LC_MESSAGES 或 LANG 中第一个非空值。
  5. Windows 用户语言区域;其他平台没有语言环境变量时使用英语。
memories language zh       # Save a language for subsequent commands
memories language          # Show the saved choice and effective language
memories language system   # Clear the choice and follow the system

非秘密偏好以 language.txt 保存在 --home / MEMORIES_HOME 下(或默认 memories 数据目录下)。保存使用原子文件替换。初始化之前或没有运行守护进程时也可使用。仅检测系统语言不会创建偏好文件。缺失、不可读或无效的偏好会回退到系统语言;写入失败会报告错误。临时 --lang 和 MEMORIES_LANG 覆盖不会更改该文件。

ja_JP.UTF-8 等语言区域变体会规范化为其基础语言。不支持的环境/系统语言回退到英语。显式无效的 --lang 值由 Clap 拒绝。初始扫描在 -- 处停止,以保留传给被捕获程序的类似语言参数。

crates/cli/locales/ 中的 UTF-8 语言目录在编译时嵌入;安装后的二进制无需附带资源文件。目录键是原始英语消息。Clap 文档注释需同时保留完整和去句点变体,因为简短帮助会去掉末尾句点。简短和详细帮助都需翻译。每个新增的 CLI 自有错误和提示都应添加目录条目。

命名占位符使用 i18n::format。替换只处理模板一次,因此包含花括号的用户文本不会变成其他占位符。密码和秘密捕获仍使用隐藏输入。USE 和 APPROVE 始终是字面确认标记,必须原样出现在翻译后的提示中。

JSON 输出保留现有版本、字段名、错误码和退出状态。只本地化面向人的消息。未映射的原生/操作系统诊断在本地化摘要之后保留原文;Clap 解析诊断包含本地化介绍和原始参数详情。MCP schema、工具名和协议消息保持稳定,不依赖 CLI 语言区域。

验证

cargo test -p memories --locked
cd mobile
flutter gen-l10n
flutter analyze
flutter test

Rust 测试覆盖所有语言目录、帮助覆盖率、占位符保留、语言优先级、转发参数、嵌套帮助,以及保留稳定 JSON 字段的本地化错误。Flutter 测试覆盖目录一致性、全部五种系统语言、不支持语言的回退、偏好持久化、会话保留、手机宽度下的本地化对话框,以及遮罩后的受保护卡片预览。

在配置 HTTP 代理的主机上运行组件测试时,应将 localhost、127.0.0.1 和 ::1 排除在代理之外;Flutter 本地测试 WebSocket 必须直接连接。仍需设备测试来验证平台字体回退、原生文件选择器和 OAuth 浏览器界面,后者的语言由操作系统或提供商管理。