feat(app-iced): M101 r2 设置页状态漏斗 + pages/mod.rs 拆分 + r1 复审订正
r1 复审的 P1:消息漏斗只解决了「加一支消息」,一组要画真值仍要改 `settings/mod.rs` (`Group.body` 与 `view` 只认 `appearance::State`)。本 commit 补齐与消息漏斗同构的状态漏斗: - 新增 `pages/settings/state.rs`:`Groups`(一个组一个字段,字段类型在组自己文件里)+ `States`(按值传给渲染器的只读视图:外观状态 + 组状态)+ `demo_groups()`(harness 的 `'static` 默认状态)。 - `Group.body` 签名改成 `for<'a> fn(&'a Ui, States<'a>) -> Option<Element>`:每组自己从 `States` 取自己要的数据,「没有可画的状态」返回 `None` 由 `form` 退回演示行。 `appearance` 组照旧接 `pages/appearance/section.rs`(M93 路径行为不变)。 - `App.settings: pages::settings::Groups`(`app/state.rs` 字段列表末尾)+ `app/view.rs` 构造 `States` 走新入口 `pages::page_with_settings`。加/改某一组的字段只改那一组的文件。 - 四个组各自的 `State` 落在各自文件;`java::Message` 留一支只有测试构造的 `Ping`,配 `app/update/settings/tests.rs` 的 `a_group_message_reaches_its_handler_through_the_funnel` ——消息漏斗第一次有**运行时**证据。 r1 其余条目: - P2-1 删掉 `only_the_appearance_group_carries_a_real_control_body`(被四条 per-group 断言蕴含), 并在同处写明删掉之后「唯一性」没人守;三份 section 文档从「改 3 个文件」订正为 2 个。 - P2-2 `pub mod settings` → `pub(crate) mod settings`(四个消息口模块 `pub(crate)`), 并订正两处理由(lint 按类型自身可见性判,不是可达性)。 - P2-3 `pages/mod.rs` 397 行 → 拆出 `pages/message.rs` / `pages/screen.rs`(纯搬移,`pub use` 保证 `pages::Message` / `Action` / `Screen` 路径不变),并删掉 M101 自己那 18 行重复文档。 - P3-1 订正共享点清单(`Key` 由宏从域文件累积生成,加 key 不改 `catalog.rs`)。 - P3-2 守门改成「除已知臂外任何含 `=>` 的行都算兜底」(`other =>` 也拦),并加「恰好四臂」断言。 - P3-3 `ai.rs` → `ai_about.rs` 单独一条 R100 改名提交,`git log --follow` 不断链。 - P3-4 `message.rs` 的「加一支消息改 1 个文件」订正为 2 个。
This commit is contained in:
1 parent
423ea77758
commit
029ece3f17
25 files changed
+1004
-240
No files matched your search
@@ -0,0 +1,78 @@
|
||||
//! 页面枚举 `Screen` 与它的三张对照表(版面 / 导航项 / 路由;M101 r2 从 `pages/mod.rs` **原样搬出**)。
|
||||
//!
|
||||
//! 为什么拆:合并 M100/M101 之后 `pages/mod.rs` 是 397 行,只剩 3 行余量。纯搬移,路径靠
|
||||
//! `pages/mod.rs` 的 `pub use screen::Screen;` 保持不变(`pages::Screen`)。
|
||||
|
||||
use unlucky_presenter::router::{NavSection, Route};
|
||||
|
||||
use super::layout::PaneKit;
|
||||
|
||||
/// 四个页面。
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Screen {
|
||||
/// 实例(list-detail)。
|
||||
Instances,
|
||||
/// 下载(单列)。
|
||||
Download,
|
||||
/// 设置(supporting-pane)。
|
||||
Settings,
|
||||
/// 日志(单列,两行页头)。
|
||||
Logs,
|
||||
}
|
||||
|
||||
impl Screen {
|
||||
/// 全部页面(截图矩阵按这个顺序铺)。
|
||||
pub const ALL: [Screen; 4] = [
|
||||
Screen::Instances,
|
||||
Screen::Download,
|
||||
Screen::Settings,
|
||||
Screen::Logs,
|
||||
];
|
||||
|
||||
/// 稳定 slug(命令行参数与文件名用)。
|
||||
pub const fn slug(self) -> &'static str {
|
||||
match self {
|
||||
Screen::Instances => "instances",
|
||||
Screen::Download => "download",
|
||||
Screen::Settings => "settings",
|
||||
Screen::Logs => "logs",
|
||||
}
|
||||
}
|
||||
|
||||
/// 反向解析(`--screen=instances`)。
|
||||
pub fn from_slug(slug: &str) -> Option<Self> {
|
||||
Self::ALL.into_iter().find(|screen| screen.slug() == slug)
|
||||
}
|
||||
|
||||
/// 页面声明的**最宽**版面;实际用哪个由 [`layout::resolve`](super::layout) 按窗口宽度决定。
|
||||
pub const fn kit(self) -> PaneKit {
|
||||
match self {
|
||||
Screen::Instances => PaneKit::ListDetail,
|
||||
Screen::Settings => PaneKit::Supporting,
|
||||
Screen::Download | Screen::Logs => PaneKit::Single,
|
||||
}
|
||||
}
|
||||
|
||||
/// 路由落在哪一页上(`None` = 这一页还没有实现,由 app 层决定回退)。
|
||||
///
|
||||
/// `Route::Detail(_)` 仍属实例页(窄窗时是「整页切换」的那一屏)。
|
||||
pub fn of(route: &Route) -> Option<Self> {
|
||||
Some(match route {
|
||||
Route::Instances | Route::Detail(_) => Screen::Instances,
|
||||
Route::Download => Screen::Download,
|
||||
Route::Logs => Screen::Logs,
|
||||
Route::Settings => Screen::Settings,
|
||||
Route::Agent => return None,
|
||||
})
|
||||
}
|
||||
|
||||
/// 该页高亮的导航项(与 `Route::nav` 同源,但这里是「按页问」的口径)。
|
||||
pub const fn nav(self) -> NavSection {
|
||||
match self {
|
||||
Screen::Instances => NavSection::Instances,
|
||||
Screen::Download => NavSection::Download,
|
||||
Screen::Logs => NavSection::Logs,
|
||||
Screen::Settings => NavSection::Settings,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user