fix(presenter,app-iced,i18n): M132 缺 MSA client id 上屏成「未配置 + 怎么补」
缺 client id 原来整条链路只给 `LoginFailure::Other`:界面画「Sign-in failed / 完整原因在启动器日志里 / Code: other」,用户得翻日志才知道要设 `ULL_MSA_CLIENT_ID`。 落点定在**账户页登录面板**,不是启动流程:这个失败只发生在 `microsoft_auth()`(两条 登录流的入口);没配 id 的发布版建不出微软账户,`identity::resolve` 那条启动路径用户 撞不到(只有「有 id 的构建里登录过、之后 id 被摘掉」才可达)。 - presenter:新增 `LoginFailure::MsaNotConfigured`(`msa_not_configured`)。`microsoft_auth` 改为回 `AuthResult`,`AuthError::Unsupported`(`from_env` 唯一的产出点,零网络)单独成码, 其余失败照旧走 `classify`。诊断原文仍只进日志。 - i18n:账户域新增 `AccountLoginNotConfigured`(标题)/ `AccountFailureMsaNotConfigured` (正文:设 `ULL_MSA_CLIENT_ID=<id>` 或构建时注入,改完重启),golden 同步。 - app-iced:`failure_title_key` 给这一类专属标题;正文按码查表;这一类**不给「重试」** (进程内的环境变量改不了,重试必然是同一个错)。 - 测试:`a_missing_client_id_tells_the_user_what_to_configure` 断言 UI 模型里出现「未配置」 + 变量名 + `<id>` 占位 + `msa_not_configured`,且没有那句「去翻日志」;反向锚 `a_network_failure_does_not_look_like_a_missing_config` 与 `only_a_missing_client_id_becomes_the_config_gap_code` 钉住别的失败不许跟着变。 为什么这一类可以上屏:上屏的是 catalog 固定文案(无凭据、无 token、无内部细节), `DevicePanel::Failed` 里没有 `message`/`detail` 字段,原文在类型上就画不出来; 理由是它的原因本身就是用户的下一步。M117/M119 的「诊断不上屏」约定不动。
This commit is contained in:
1 parent
01ca8033be
commit
af39efd23b
7 files changed
+223
-52
No files matched your search
@@ -278,33 +278,36 @@ fn countdown_line<'a>(
|
||||
|
||||
/// 失败态:**M3 内联 alert**(左侧 `ErrorContainer` 图标块 + 标题/正文/Code + 重试/关闭)。
|
||||
///
|
||||
/// 两条修订叠在这里:
|
||||
/// 三点修订叠在这里:
|
||||
/// - **语言泄漏(r1 p1)**:只画原因码对应的 i18n + 一行 `Code: …`,后端中文原文不上屏;
|
||||
/// - **不许通栏实心红(tower r2)**:面板底走 `SurfaceContainerHigh` + 描边,
|
||||
/// `ErrorContainer`/`OnErrorContainer` 只作左侧图标块的强调(角色不变,面积收小)。
|
||||
/// `ErrorContainer`/`OnErrorContainer` 只作左侧图标块的强调(角色不变,面积收小);
|
||||
/// - **可操作的失败要有可读说明(M132)**:缺 client id 换专属标题 + 「要设哪个环境变量」的
|
||||
/// 正文,且**不给「重试」**——进程内的环境变量改不了,重试必然还是同一个错。
|
||||
fn failed<'a>(ui: &'a Ui, failure: LoginFailure, catalog: Catalog) -> Element<'a, PageMessage> {
|
||||
let body = catalog.text(failure_body_key(failure)).to_string();
|
||||
let code = catalog.render(Key::AccountFailureCode, &[("code", failure.code())]);
|
||||
let actions = vec![
|
||||
buttons::tonal(
|
||||
let mut actions: Vec<Element<'a, PageMessage>> = Vec::new();
|
||||
if !matches!(failure, LoginFailure::MsaNotConfigured) {
|
||||
actions.push(buttons::tonal(
|
||||
ui,
|
||||
Button::new(
|
||||
catalog.text(Key::AccountDeviceRetry),
|
||||
Account::StartDevice.into_page(),
|
||||
),
|
||||
));
|
||||
}
|
||||
actions.push(buttons::text(
|
||||
ui,
|
||||
Button::new(
|
||||
catalog.text(Key::AccountDialogClose),
|
||||
Account::Close.into_page(),
|
||||
),
|
||||
buttons::text(
|
||||
ui,
|
||||
Button::new(
|
||||
catalog.text(Key::AccountDialogClose),
|
||||
Account::Close.into_page(),
|
||||
),
|
||||
),
|
||||
];
|
||||
));
|
||||
super::widgets::alert(
|
||||
ui,
|
||||
super::widgets::Tone::Error,
|
||||
catalog.text(Key::AccountLoginFailed),
|
||||
catalog.text(failure_title_key(failure)),
|
||||
body,
|
||||
Some(code),
|
||||
actions,
|
||||
@@ -347,6 +350,18 @@ pub(super) fn failure_body_key(failure: LoginFailure) -> Key {
|
||||
LoginFailure::BadCredentials => Key::AccountFailureBadCredentials,
|
||||
LoginFailure::NoProfile => Key::AccountFailureNoProfile,
|
||||
LoginFailure::StoreFailed => Key::AccountFailureStore,
|
||||
LoginFailure::MsaNotConfigured => Key::AccountFailureMsaNotConfigured,
|
||||
LoginFailure::Other => Key::AccountFailureOther,
|
||||
}
|
||||
}
|
||||
|
||||
/// 原因码 → i18n **标题** key。
|
||||
///
|
||||
/// 只有「缺 client id」有专属标题(M132):标题写着 `Sign-in failed` 的话,用户会以为是自己
|
||||
/// 的账号/网络出了问题,而不会被指向那一项要补的配置。
|
||||
pub(super) fn failure_title_key(failure: LoginFailure) -> Key {
|
||||
match failure {
|
||||
LoginFailure::MsaNotConfigured => Key::AccountLoginNotConfigured,
|
||||
_ => Key::AccountLoginFailed,
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user