来源:M106 r1 复审点名——中文机器上首屏(实例页)仍是英中混排(页头 / New instance / Import / ALL INSTANCES / VERSION / Present on disk / Running · pid / Launch failed)。 用户的原话是「我系统语言是中文 为什么打开软件是英文」。 改了什么 - i18n:catalog/instances.rs 从 6 条死 key 补到 34 条(页头 / 列表列头 / 详情动作 / 窄窗说明 / 元信息标签与值 / 隔离档位 / 运行状态 / 四个启动阶段)。族在装配链第 2 位, 新 key 追加在本族末尾,golden 对应位置插入(不是文件末尾追加)。 - 页面:新增 pages/instances/text.rs(Texts)——页面唯一的取词入口,实例页里不再有 任何可见英文字面量;detail / demo 也改从它取。 - 阶段标签:view/instances.rs 的 Running / Launch failed / 四阶段全部走目录; **数字与分隔符不随语言变形**(运行中 · pid 1234 与 Running · pid 1234 只换前半句)。 - 顺手修掉两处「语言反向泄漏」:原版徽标此前直接画 presenter 的中文「原版」(英文界面 会漏中文),现在走 LoaderVanilla;隔离档位 isolated/shared 也从 core 的稳定 id 换成人话。 - 删掉 InstancesLastPlayed:M117 加的整句 key,从未接线,形状与「标签 + 值」的元信息卡 不符,由 InstancesMetaLastPlayed + InstancesNeverPlayed 取代。 守门(pages/instances/tests/i18n.rs + app/view/tests.rs) - 中文态无 ASCII 英文单词(品牌 Java / 技术标识 pid 白名单); - 每一条 Instances* 的两套译文必须不同(切语言时真的变); - Running 的数字与 · pid 分隔符在两套语言里逐字保留; - 页面源码里 29 条旧英文基线不许回来;每条 key 都必须被页面引用(死 key)。 出图:DevDocs/artifacts/m120/01~12(有实例 / 空态 / 运行中 × 浅深 × 中英)。
103 lines
4.4 KiB
Rust
103 lines
4.4 KiB
Rust
//! 实例页的**文案入口**:页面上一处可见英文字面量都不留,全部从目录取。
|
||
//!
|
||
//! ## 为什么要有这一层(而不是在控件树里直接 `catalog.text(..)`)
|
||
//!
|
||
//! 页面要的文案有 20 多条,直接写的话每个调用点都是「key 名 + 这一处画什么」的重复劳动,
|
||
//! 而且**守门测试没法取样**:iced 0.14 的 `Element` 没有内省接口(`instances/tests.rs` 里
|
||
//! 「读源码」那条注释解释过同一件事),所以「上屏文本」只能从**页面取词的那一个入口**拿。
|
||
//! 于是所有取词收进 [`Texts`],页面用 `texts.xxx()` 画,测试用同一个 `Texts` 断言——
|
||
//! 一处定义、两处消费,不存在「测试抄了一份平行实现」。
|
||
//!
|
||
//! ## 它抓得住什么 / 抓不住什么
|
||
//!
|
||
//! - **抓得住**:目录里某条中文忘了翻(`pages/instances/tests/i18n.rs` 的「无 ASCII 英文单词」)、
|
||
//! 某条中英写成一样(「切换语言文本真的变」)、`Running · pid {pid}` 的数字与分隔符被翻译走样;
|
||
//! - **抓不住**:页面上又冒出一条**新**硬编码字面量——那由同文件里「旧串不许回来」的源码扫描
|
||
//! 兜已知的那批,加上出图人工看(`DevDocs/artifacts/m120/`);
|
||
//! - **抓不住**:译文本身翻得顺不顺(那只能人工审图)。
|
||
//!
|
||
//! ## 口径
|
||
//!
|
||
//! 品牌名不翻译(`Java` / `Fabric` / `Forge` 原样);`pid` 是进程号的技术标识,两套语言都写
|
||
//! `pid`(改成「进程」会丢掉「拿它去任务管理器里搜」这条可操作性)。
|
||
//!
|
||
//! **启动阶段(下载中 / 校验中 / …)不在这张表里**:它在 `app/view/instances.rs` 拼进
|
||
//! `Row.status`(「阶段 · 百分比」是一整句),与元信息卡同一层——页面只画模型给的字符串。
|
||
|
||
use unlucky_i18n::{Catalog, Key};
|
||
|
||
/// 实例页 + 详情列的文案(一个 `Catalog` 的薄包装,`Copy`)。
|
||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||
pub(crate) struct Texts(Catalog);
|
||
|
||
impl Texts {
|
||
/// 从目录取一套(调用方给 `model.lang.catalog()`)。
|
||
pub(super) fn of(catalog: Catalog) -> Self {
|
||
Self(catalog)
|
||
}
|
||
|
||
// ------------------------------------------------------------- 页头
|
||
pub(super) fn title(self) -> &'static str {
|
||
self.text(Key::InstancesTitle)
|
||
}
|
||
pub(super) fn subtitle(self) -> &'static str {
|
||
self.text(Key::InstancesSubtitle)
|
||
}
|
||
pub(super) fn new_instance(self) -> &'static str {
|
||
self.text(Key::InstancesNew)
|
||
}
|
||
pub(super) fn import(self) -> &'static str {
|
||
self.text(Key::InstancesImport)
|
||
}
|
||
|
||
// --------------------------------------------------------------- 列表列
|
||
pub(super) fn all_title(self) -> &'static str {
|
||
self.text(Key::InstancesAllTitle)
|
||
}
|
||
|
||
// --------------------------------------------------------------- 详情列
|
||
pub(super) fn back(self) -> &'static str {
|
||
self.text(Key::InstancesBack)
|
||
}
|
||
pub(super) fn play(self) -> &'static str {
|
||
self.text(Key::InstancesPlay)
|
||
}
|
||
pub(super) fn stop(self) -> &'static str {
|
||
self.text(Key::InstancesStop)
|
||
}
|
||
pub(super) fn duplicate(self) -> &'static str {
|
||
self.text(Key::InstancesDuplicate)
|
||
}
|
||
pub(super) fn open_folder(self) -> &'static str {
|
||
self.text(Key::InstancesOpenFolder)
|
||
}
|
||
pub(super) fn delete(self) -> &'static str {
|
||
self.text(Key::InstancesDelete)
|
||
}
|
||
pub(super) fn empty_title(self) -> &'static str {
|
||
self.text(Key::InstancesEmptyTitle)
|
||
}
|
||
pub(super) fn empty_body(self) -> &'static str {
|
||
self.text(Key::InstancesEmptyBody)
|
||
}
|
||
pub(super) fn narrow_note(self) -> &'static str {
|
||
self.text(Key::InstancesNarrowNote)
|
||
}
|
||
|
||
fn text(self, key: Key) -> &'static str {
|
||
self.0.text(key)
|
||
}
|
||
|
||
/// 这一页的全部 key(守门测试的取样口:**从 `Key::ALL` 过滤出来**,不是手抄一份清单)。
|
||
///
|
||
/// 域判据是前缀 `Instances`——本族的 key 名是契约(`catalog/instances.rs` 里一条一条写着),
|
||
/// 新加的 key 只要还在这个族里就自动进守门范围,不需要有人记得来登记。
|
||
#[cfg(test)]
|
||
pub(super) fn keys() -> impl Iterator<Item = Key> {
|
||
Key::ALL
|
||
.iter()
|
||
.copied()
|
||
.filter(|key| key.name().starts_with("Instances"))
|
||
}
|
||
}
|