feat(download): M94 下载页换成真组件 + 真快照 + 真指令(PAGEDL)
页面(crates/app-iced/src/pages/download*):
- Tabs(分类)/ ListItem(版本行)/ filled 安装按钮 / progress / EmptyState / divider
全部取自 components/ 的真组件;页头动作换成 buttons::text
- 数据只吃 pages::download::Download(app/view.rs 由 AppState 快照转,installed_only 与
download_query 照用);页面自己不留业务状态,交互只发意图
- 状态:加载(不确定进度 + 文案)/ 空(EmptyState + 刷新 CTA)/ 有数据 / 安装中 / 安装失败
(失败给可读文案 + 「打开日志」出口)
接线(追加式):
- pages::Message 加 SelectVersion / InstallVersion / CancelInstall / SetCategory
- app/update.rs 翻成 AppCommand::{InstallVersion, CancelInstall, ListVersions}
(SelectVersion 只改视图模型;「刷新」= 当前分类重新拉,全部走 RefreshAll)
- pages::Model 加 download 字段
文案:28 个 Download* key 进中英两套 catalog(一行一个 key 的全语言);页面零中文字面量,
core 的中文阶段串(InstallStage::label / message)一律不进界面
i18n 结构:catalog.rs 的既有测试模块原样外置到 catalog/tests.rs(392 行 → 282 行,
逐字未改),新 key 才装得下 400 行硬上限
测试:app-iced 276 + i18n 23 全绿;clippy -D warnings 与 fmt --check 干净
This commit is contained in:
1 parent
b3f99652bb
commit
57e8380b24
14 files changed
+1633
-247
No files matched your search
@@ -0,0 +1,132 @@
|
||||
//! 下载页的**演示数据**(截图 harness 与单测的输入,产品路径不读)。
|
||||
//!
|
||||
//! 与 `pages/instances/data.rs` 同一条纪律:演示条目是**页面侧常量**,不是业务 DTO——
|
||||
//! 于是核心 DTO 每改一次字段,基线图不会跟着漂。真页面的数据只走
|
||||
//! [`Download::from_snapshot`](super::model::Download::from_snapshot)。
|
||||
//!
|
||||
//! 演示条目本身也是一步「DTO → 视图模型」的真转换([`VersionRow::of`](super::model::VersionRow)、
|
||||
//! [`InstallView::of`](super::model::InstallView)):图上看到的副文案 / 进度行就是产品路径
|
||||
//! 那条转换的产物,不是另写一套拼串。
|
||||
//!
|
||||
//! ## 为什么要一个环境变量
|
||||
//!
|
||||
//! 状态矩阵(加载 / 空 / 有数据 / 安装中 / 安装失败)都要出图,而 harness 的
|
||||
//! `--screen` 只选页面、选不了页面状态:
|
||||
//!
|
||||
//! ```text
|
||||
//! ULL_DL_DEMO=empty cargo run -p unlucky-app-iced --example pages_demo -- \
|
||||
//! --screen=download --screenshot=out.png --screenshot-theme=light --software-renderer
|
||||
//! ```
|
||||
//!
|
||||
//! 取值:`ready`(缺省)/ `loading` / `empty` / `selected` / `installing` / `failed`。
|
||||
//! **只有 harness 与演示走这里**:产品路径由 `app/view.rs` 从 presenter 快照建模型。
|
||||
|
||||
use unlucky_presenter::dto::{
|
||||
AncientKind, InstallProgressView, InstallStage, VersionKind, VersionSummary,
|
||||
};
|
||||
|
||||
use unlucky_i18n::Catalog;
|
||||
|
||||
use super::model::{Category, Download, InstallView, VersionRow};
|
||||
|
||||
/// 取证开关的名字([`demo`] 读它)。
|
||||
pub const DEMO_STATE_ENV: &str = "ULL_DL_DEMO";
|
||||
|
||||
/// 演示模型:按 [`DEMO_STATE_ENV`] 选状态,缺省是「有数据」。
|
||||
pub fn demo(catalog: Catalog) -> Download {
|
||||
match std::env::var(DEMO_STATE_ENV).ok().as_deref() {
|
||||
Some("loading") => Download::loading(),
|
||||
Some("empty") => Download {
|
||||
loaded: true,
|
||||
..Download::loading()
|
||||
},
|
||||
Some("installing") => Download {
|
||||
install: Some(install(InstallStage::Downloading, 0.42, catalog)),
|
||||
selected: Some("1.21.9".to_string()),
|
||||
..ready(catalog)
|
||||
},
|
||||
Some("selected") => Download {
|
||||
selected: Some("1.21.9".to_string()),
|
||||
..ready(catalog)
|
||||
},
|
||||
Some("failed") => Download {
|
||||
install: Some(install(InstallStage::Failed, 0.0, catalog)),
|
||||
selected: Some("1.21.9".to_string()),
|
||||
..ready(catalog)
|
||||
},
|
||||
_ => ready(catalog),
|
||||
}
|
||||
}
|
||||
|
||||
/// 有数据:六行(三条正式、一条预览、两条远古),与 presenter 的 `mock_versions` 同形。
|
||||
///
|
||||
/// 不复用 `mock_data::mock_versions()`:演示数据是**出图的基线**,得比 mock 稳定
|
||||
/// (mock 随 P3 的假数据一起漂)。
|
||||
fn ready(catalog: Catalog) -> Download {
|
||||
fn summary(id: &str, kind: VersionKind, released: &str, installed: bool) -> VersionSummary {
|
||||
VersionSummary {
|
||||
id: id.to_string(),
|
||||
kind,
|
||||
released: released.to_string(),
|
||||
installed,
|
||||
}
|
||||
}
|
||||
|
||||
let versions = vec![
|
||||
summary("1.21.9", VersionKind::Release, "2026-09-20", false),
|
||||
summary("1.21.8", VersionKind::Release, "2026-07-11", true),
|
||||
summary("1.20.4", VersionKind::Release, "2023-12-07", true),
|
||||
summary("1.21.9-pre3", VersionKind::Snapshot, "2026-09-01", false),
|
||||
summary(
|
||||
"rd-132211",
|
||||
VersionKind::Ancient(AncientKind::Classic),
|
||||
"2009-05-13",
|
||||
false,
|
||||
),
|
||||
summary(
|
||||
"a1.2.6",
|
||||
VersionKind::Ancient(AncientKind::OldAlpha),
|
||||
"2010-08-11",
|
||||
false,
|
||||
),
|
||||
];
|
||||
|
||||
let rows: Vec<VersionRow> = versions
|
||||
.iter()
|
||||
.map(|version| VersionRow::of(version, catalog))
|
||||
.collect();
|
||||
|
||||
Download {
|
||||
// 混合分类 → 没有单个 chip 该亮(这正是 `Category::of` 的反推结果)
|
||||
category: Category::of(&versions),
|
||||
rows,
|
||||
selected: None,
|
||||
install: None,
|
||||
loaded: true,
|
||||
}
|
||||
}
|
||||
|
||||
/// 一次安装的演示快照(文件计数 / 字节 / 速度 / 剩余时间都给真值,进度条画得出来)。
|
||||
fn install(stage: InstallStage, ratio: f32, catalog: Catalog) -> InstallView {
|
||||
let total = 512;
|
||||
let done = (f64::from(ratio) * total as f64) as u64;
|
||||
let failed = matches!(stage, InstallStage::Failed);
|
||||
|
||||
InstallView::of(
|
||||
&InstallProgressView {
|
||||
version: "1.21.9".to_string(),
|
||||
instance: "1.21.9".to_string(),
|
||||
// 演示也**不**搬 core 的中文串:`loader` 字段这里给的是结构化徽标的英文名
|
||||
loader: "Vanilla".to_string(),
|
||||
stage,
|
||||
files_done: if failed { 137 } else { done },
|
||||
files_total: total,
|
||||
bytes_done: 0,
|
||||
bytes_total: 0,
|
||||
speed_bps: if failed { 0 } else { 1_258_291 },
|
||||
eta_secs: if failed { 0 } else { 75 },
|
||||
message: String::new(),
|
||||
},
|
||||
catalog,
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user