fix(app-iced): 点选共享档立刻显示后果原文,登记在飞时不吃关闭(M223 自检)
两处自己复审抓到的问题: 1. 契约 §5.2 要求 Shared/VersionDir 被**点选**就展示 target_notes() 原文,而上一版要等 用户再点一次「预检」才出现。现在点选这两档会顺手发一次**零写盘**的预检,结果落在 Pick 段当提示读(不把用户甩到确认页:确认仍由显式的「预检」按钮触发,Form::checked)。 改档之后旧 plan 因目标档不一致而不再显示(Form::fresh_plan),避免画上一档的后果原文。 2. 「关闭」在登记在飞时被忽略:core 那条线程已经开跑,关面板会让 Done 事件被代次丢掉, 用户看到的就是「实例写进去了,界面什么都没说」。 用例:a_foreign_target_shows_its_notes_without_jumping_to_confirm / choosing_a_foreign_target_previews_but_waits_for_the_user / closing_is_ignored_while_the_registration_is_in_flight。
This commit is contained in:
1 parent
9ca5ee8ae7
commit
a36e17a5d3
4 files changed
+163
-19
No files matched your search
@@ -14,7 +14,7 @@ use unlucky_design::shape::ShapeScale;
|
||||
use unlucky_design::spacing::Space as Sp;
|
||||
use unlucky_design::typography::TypeRole;
|
||||
use unlucky_i18n::{Catalog, Key};
|
||||
use unlucky_presenter::dto::{AdoptCandidateView, AdoptScanView, AdoptTargetView};
|
||||
use unlucky_presenter::dto::{AdoptCandidateView, AdoptPlanView, AdoptScanView, AdoptTargetView};
|
||||
|
||||
use crate::app::components::inputs::{text_field, Field};
|
||||
use crate::app::components::selection::{chip, Chip};
|
||||
@@ -30,6 +30,7 @@ pub(super) fn pick<'a>(
|
||||
ui: &'a Ui,
|
||||
form: &'a Form,
|
||||
scan: Option<&'a AdoptScanView>,
|
||||
plan: Option<&'a AdoptPlanView>,
|
||||
catalog: Catalog,
|
||||
) -> Element<'a, Message> {
|
||||
let Some(scan) = scan else {
|
||||
@@ -57,6 +58,13 @@ pub(super) fn pick<'a>(
|
||||
body = body.push(frame::divider(ui).map(Message::Page));
|
||||
body = body.push(label(ui, catalog.text(Key::AdoptTargetLabel)));
|
||||
body = body.push(target_row(ui, form, catalog));
|
||||
// 后果原文(契约 §5.2):共享档 / 版本目录档一被点选就显示 core `target_notes()` 的原文——
|
||||
// 这一条来自**零写盘**的自动预检(见 `AdoptMessage::Target` 的落点),不是界面另写的一句。
|
||||
if let Some(plan) = plan {
|
||||
for note in &plan.notes {
|
||||
body = body.push(wrapped(ui, note.clone(), ui.color(Role::OnSurfaceVariant)));
|
||||
}
|
||||
}
|
||||
body = body.push(text_field(
|
||||
ui,
|
||||
Field::new(form.name.as_str()).label(catalog.text(Key::AdoptNameLabel)),
|
||||
|
||||
@@ -90,11 +90,11 @@ fn the_four_stages_project_from_the_event_state() {
|
||||
// Pick
|
||||
assert_eq!(state.stage(), AdoptStage::Pick);
|
||||
assert_eq!(
|
||||
title_text(&state, catalog),
|
||||
title_text(state.stage(), catalog),
|
||||
catalog.text(Key::AdoptTitle),
|
||||
"标题走目录"
|
||||
);
|
||||
assert!(subtitle(&state, catalog).contains("不复制"));
|
||||
assert!(subtitle(state.stage(), &state, catalog).contains("不复制"));
|
||||
|
||||
// Preview:`notes` 是 core `target_notes()` 的原文,界面一个字都不许改
|
||||
let note =
|
||||
@@ -136,7 +136,7 @@ fn the_four_stages_project_from_the_event_state() {
|
||||
"两条问题一条都不许吞"
|
||||
);
|
||||
assert_eq!(
|
||||
title_text(&state, catalog),
|
||||
title_text(state.stage(), catalog),
|
||||
catalog.text(Key::AdoptFailureTitle)
|
||||
);
|
||||
|
||||
@@ -152,7 +152,7 @@ fn the_four_stages_project_from_the_event_state() {
|
||||
})));
|
||||
assert_eq!(state.stage(), AdoptStage::Done);
|
||||
assert_eq!(
|
||||
title_text(&state, catalog),
|
||||
title_text(state.stage(), catalog),
|
||||
catalog.text(Key::AdoptDoneTitle)
|
||||
);
|
||||
}
|
||||
@@ -199,3 +199,47 @@ fn both_catalogs_have_the_wizard_wording() {
|
||||
let hint = Lang::En.catalog().text(Key::AdoptTargetSharedHint);
|
||||
assert!(hint.contains(".minecraft"), "{hint}");
|
||||
}
|
||||
|
||||
/// 「点选共享档 ⇒ 立刻看到后果原文」但**不**把用户甩到确认页:
|
||||
/// 预检结果到了也只是 Pick 段里的提示,直到用户点过「预检」(`checked`) 才进 Preview。
|
||||
///
|
||||
/// 抓得住:把 `Form::stage` 写回直接取 `AdoptState::stage()`(点一次共享档就跳到确认页,
|
||||
/// 实例名还没来得及改);或忘了 `fresh_plan` 的目标一致性判据(改档之后画上一档的后果原文)。
|
||||
#[test]
|
||||
fn a_foreign_target_shows_its_notes_without_jumping_to_confirm() {
|
||||
let mut state = state_with_scan();
|
||||
let note =
|
||||
"运行目录 = /game(共享档):mods/saves/config 会落在别人的 .minecraft 里".to_string();
|
||||
state.apply(AdoptEvent::Planned(Box::new(AdoptPlanView {
|
||||
version_id: "1.20.1".to_string(),
|
||||
name: "1.20.1".to_string(),
|
||||
target: AdoptTargetView::Shared,
|
||||
isolation: AdoptIsolationView::Shared,
|
||||
run_dir: std::path::PathBuf::from("/game"),
|
||||
notes: vec![note.clone()],
|
||||
})));
|
||||
|
||||
let mut form = Form {
|
||||
open: true,
|
||||
selected: Some("1.20.1".to_string()),
|
||||
target: AdoptTargetView::Shared,
|
||||
..Form::default()
|
||||
};
|
||||
|
||||
// 自动预检回来但用户没点「预检」:仍是 Pick 段,notes 当作提示可读
|
||||
assert_eq!(form.stage(&state), AdoptStage::Pick);
|
||||
assert_eq!(
|
||||
form.fresh_plan(&state)
|
||||
.map(|plan| plan.notes.first().cloned()),
|
||||
Some(Some(note.clone())),
|
||||
"后果原文必须能取到"
|
||||
);
|
||||
|
||||
// 点过「预检」之后才进确认段
|
||||
form.checked = true;
|
||||
assert_eq!(form.stage(&state), AdoptStage::Preview);
|
||||
|
||||
// 换了目标档:上一档的预检作废(不再当后果原文画)
|
||||
form.target = AdoptTargetView::VersionDir;
|
||||
assert!(form.fresh_plan(&state).is_none(), "过期的预检不许画");
|
||||
}
|
||||
Reference in new issue
Block a user