feat(app-iced,i18n): M106 —— 界面跟随系统语言 + 设置页真实语言行
用户原话:「我系统语言是中文 为什么打开软件是英文 并且设置页里面显示的是 English(system)」。
两处根源:①M92 的探测链一直是对的,但 `pages::Model.lang` 在 `app/view.rs` 里写死成
`Lang::En`(`pages::render` 还把下载页写死成英文),探测结果没人用;②设置页语言行是硬编码
字面量 `("Language", "English (System)")`。
新增/改动(按层):
- i18n:新域 `catalog/general.rs`(24 条中英双份 key,装配链尾追加)+ `catalog/golden.rs`
只追加不重排;`choice.rs`(`LangChoice`:跟随系统/手选 + D28 四级优先级真值表 + 字体优先级真值表)。
- app-iced 语言入口 `src/ui.rs` + `src/ui/lang.rs`:`LangState` = 用户档位 + 探测结论;
启动判定 `ULL_LANG` > 配置 `ui.language` > 系统 locale > 英文;两行日志(探测/生效 + 中文策略)。
- `app/state.rs`:`App` 持有 `LangState`,切语言 = 换目录 + 落盘 + 重建视图模型;
`app/view.rs` 的 `model()` 收 `lang`,不再写死英文。
- 设置页:语言行换真控件(跟随系统 / 简体中文 / 英文,回显「界面当前使用:简体中文」);
页头、左列分组名、逐实例空态、导航轨标签全部走 catalog。
- presenter:`settings_bridge_lang.rs`(`load_ui_language` / `persist_ui_language`)。
「跟随系统」= **删键**(schema 允许值只有 zh_cn/en_us),读的是 `doc().get()` 而不是
`effective_str`(后者会把默认值 `zh_cn` 当成用户手选,英文机器一启动就被切成中文)。
验证:408 条 app-iced lib 测试 + 28 条 i18n 测试 + 全仓 `cargo test --workspace --exclude
unlucky-app` 全绿;fmt / clippy `-D warnings` 干净;出图 6 张(en/zh × 浅/深 + 下载页对照)
在 `DevDocs/artifacts/m106/`(该目录被 .gitignore 忽略,按仓内惯例作为本地验收产物)。
This commit is contained in:
1 parent
777d02e7cb
commit
89dcb6bdf3
25 files changed
+1456
-92
No files matched your search
@@ -69,12 +69,15 @@ impl App {
|
||||
appearance: Some(&self.appearance),
|
||||
groups: &self.settings,
|
||||
},
|
||||
// M106:设置页 General 组要画「当前档位 + 生效语言」。
|
||||
self.language(),
|
||||
)
|
||||
.map(Message::Page),
|
||||
agent::docked(&self.ui, &self.agent, self.width)
|
||||
.map(|element| element.map(Message::Agent)),
|
||||
overlay,
|
||||
self.options.force_state,
|
||||
self.lang(),
|
||||
),
|
||||
// `Route::Agent`:独立页与右栗共用同一个 `conversation::view`(`agent::page` 内部调的它)。
|
||||
None => shell::view_with_background(
|
||||
@@ -86,6 +89,7 @@ impl App {
|
||||
None,
|
||||
overlay,
|
||||
self.options.force_state,
|
||||
self.lang(),
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -93,9 +97,12 @@ impl App {
|
||||
|
||||
// --------------------------------------------------------------- 快照 → 视图模型
|
||||
|
||||
/// **产品路径此刻的界面语言**(唯一入口):语言还没接到设置(M106 的范围),所以恒为英文。
|
||||
/// 收成一处是为了别让第二个地方(如取消提示)各硬编码一次;M106 只改这里。
|
||||
/// **M106 合并前中文译文在产品路径上不可达**(页面与提示语都是英文)。
|
||||
/// **测试用的英文基线**(M105 留的占位在这里收口)。
|
||||
///
|
||||
/// 产品路径的界面语言由 `App::lang()` 经 `model(…, lang)` 与 `pages::cancelled_toast(lang)`
|
||||
/// 递进去(M106),这个函数只剩测试还在用(`app/update/download_wiring.rs` 的取消提示断言要一个
|
||||
/// 与产品无关的语言常量)。`#[cfg(test)]`:非测试构建里它没有调用点,留着就是死代码。
|
||||
#[cfg(test)]
|
||||
pub(super) fn ui_lang() -> Lang {
|
||||
Lang::En
|
||||
}
|
||||
@@ -113,6 +120,7 @@ pub(super) fn model(
|
||||
forced: Option<crate::cli::ForcedState>,
|
||||
category: pages::Category,
|
||||
draft: &pages::InstallDraft,
|
||||
lang: Lang,
|
||||
) -> pages::Model {
|
||||
let route = state.route().clone();
|
||||
let screen = pages::Screen::of(&route).unwrap_or(pages::Screen::Instances);
|
||||
@@ -137,19 +145,12 @@ pub(super) fn model(
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let lang = ui_lang();
|
||||
|
||||
pages::Model {
|
||||
screen,
|
||||
window_width: width,
|
||||
active: route.nav(),
|
||||
instances: pages::Instances { rows, detail },
|
||||
download: pages::Download::from_snapshot(
|
||||
state,
|
||||
category,
|
||||
draft,
|
||||
unlucky_i18n::Lang::En.catalog(),
|
||||
),
|
||||
download: pages::Download::from_snapshot(state, category, draft, lang.catalog()),
|
||||
logs: logs_model(state).with_status(lang),
|
||||
lang,
|
||||
forced: forced.map(|state| match state {
|
||||
@@ -289,7 +290,14 @@ mod tests {
|
||||
/// 测试用的薄包装:默认宽度 / 默认分类 / 空草稿。
|
||||
fn at(state: &AppState, forced: Option<crate::cli::ForcedState>) -> pages::Model {
|
||||
let draft = pages::InstallDraft::default();
|
||||
model(state, 1180.0, forced, pages::Category::All, &draft)
|
||||
model(
|
||||
state,
|
||||
1180.0,
|
||||
forced,
|
||||
pages::Category::All,
|
||||
&draft,
|
||||
Lang::En,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user