fix(app-iced): M106 r2 —— 两处「改了行为、旧口径还在树里」(复审 p2-1 / p2-2)

p2-1(它在撒谎):`renderer/acceptance/locale.rs::Chain::line()` 还打 `ui_text=pinned-en`,
注释写着「pages/mod.rs::render 里下载页固定传 Lang::En」、`setting` 回退 `<未接线>`——M106 之后
两句同时为假,于是 `ULL_ACCEPTANCE=1` 时启动日志两行互相矛盾(旧行说「文案钉在英文」,新行说
「生效中文」)。修法:`Chain` 增 `machine`(只看平台源 + 环境变量,供 `[env] language=` 用)与
`detection`(含 `ui.language` 手选,与 App 的 `[i18n] choice=…` 同源);`host()` 真读
`SettingsBridge::load_ui_language()`,`line()` 删掉 `ui_text`、`setting` 打真实值。
实测三行现在一致:
  [i18n] setting=<未设置=跟随系统> platform=registry:zh-CN env=env:<未设置> -> lang=zh-CN locale=zh-CN source=registry
  [i18n] choice=system lang=zh-CN locale=zh-CN source=registry effective=zh-CN
`locale_tests.rs` 把钉假串的那条改成「不许出现 pinned-en」的回归绊线,并新增
`i18n_line_honours_the_explicit_setting_without_rewriting_the_machine_language`。

p2-2(doc-only):`pages/model.rs` 的「只是留口,产品路径先给 Lang::En」与 `pages/download.rs`
的「产品路径现传 Lang::En,接上探测结果时只改调用点」都已被实际代码推翻(`app/state.rs` +
`refresh_view` 在填、调用点已是 `model.lang`),按事实重写。顺带修掉 `fonts/cjk.rs` 里同样的
「设置层的读取点尚未接线」。

门禁:`cargo fmt --all -- --check` 退出码 0;`cargo test -p unlucky-app-iced --lib` 退出码 0
(409 passed, 0 failed)。全改动文件 ≤400 行(最大 269)。
This commit is contained in:
AskaEth committed 2026-11-05 01:17:36 +08:00
1 parent 89dcb6bdf3
commit 954a129e01
14 files changed
+286 -107

No files matched your search

+2 -2
View File
@@ -95,8 +95,8 @@ use super::{Action, Message};
/// 整页(**唯一**的真数据入口:`model` 由 `app/view.rs` 从 presenter 快照建)。
///
/// `lang` 是 i18n 的入参:`theme::Ui` 还没有 language 字段(那条在 M93 手里),产品路径现传
/// [`Lang::En`](D28 的英文基线零中文负担);接上探测结果时只改调用点,页面不用动。
/// `lang` 是 i18n 的入参,调用点传的是 `pages::Model.lang`(M106 起 = `App` 的生效语言,
/// 见 `ui::lang::LangState`);页面自己不读全局、不猜语言。
pub fn view<'a>(
ui: &'a Ui,
metrics: FrameMetrics,
+4 -3
View File
@@ -89,10 +89,11 @@ pub struct Model {
pub download: Download,
/// 日志页的数据(M95:presenter 快照 → 日志行 + 诊断结论,见 [`super::logs`])。
pub logs: Logs,
/// 界面语言(M95):页面文案走 i18n key,语言由 app 层决定后灌进来。
/// 界面语言(M106):页面文案走 i18n key,语言由 app 层决定后灌进来。
///
/// 这里只是**留口**:`theme.rs` 还没有「当前语言」的入口(那条线归 M93),
/// 产品路径先给 `Lang::En`;将来 `Ui` 拿到语言后,这个字段改由它填。
/// 谁填:`app/state.rs` 的 `App::refresh_view`(`LangState::lang()` → `view::model(..)`),
/// 即「用户档位 / 系统 locale → 生效语言」这条链的结论。**不是**基线值:M95 以前这里是
/// `Lang::En` 占位,M106 之后中文系统上灌进来的是 `Lang::ZhCn`。
pub lang: Lang,
/// 取证用的强制交互态(`--force-state`):`Some` 时页面里的控件按该态画。
///
+6 -3
View File
@@ -101,9 +101,12 @@
//! `app/view.rs` 不用动 —— **推荐这个形状**。
//!
//! 顺带订正 r3 之前那句「在 `app/state.rs` 用真值初始化 `Groups.language_appearance`(1 个文件)」:
//! 今天 `App` / `app/state.rs` 里**没有**任何语言真值源(`presenter::prefs::AppearancePrefs` 无
//! language 字段;唯一的值是 `app/view.rs:128` 里硬编码的 `Lang::En`),要先有真值源才谈得上
//! 初始化位置。两种形状都是「谁先撞谁付一次钱」的一次性代价,不是永久性四路撞车。
//! **M106 起语言已经有真值源**——`App::lang: LangState`(`crates/app-iced/src/ui/lang.rs`,用户档位
//! `LangChoice` + 探测结论 `Detection`),由 `App::refresh_view` 经 `view::model(…, lang)` 灌进
//! `pages::Model.lang`,设置页再从 `settings::view` 的 `language` 形参拿到它。所以下一条线要给某一组
//! 读「当前语言」时,**不需要**再造一层状态:要么走 `Model.lang`(给 `settings::view` 加形参,
//! 与 M106 同形状),要么读 `Groups` 里本线的字段。两种形状都是「谁先撞谁付一次钱」的一次性代价,
//! 不是永久性四路撞车。
//! 5. **首帧取数 / 异步发起**(同上,r2 复审 P1 补)—— [`Body`] 是
//! `fn(&Ui, States) -> Option<Element>`,返回不了 `Task`;而且 `settings::view` → `pages::render`
//! → `App::view` **一路都返回 `Element`**(iced 0.14 的 `view` 也只返回 `Element`,`view(&self)`