feat(presenter): adopt 的指令/事件/任务接线 + install 那句假话变真话(M223)

- AppCommand::Adopt(Box<AdoptCommand>)、CoreEvent::Adopt(Box<AdoptEvent>)、
  HostTask::Adopt { event, epoch }:三条穷尽枚举各加一条变体(代次独立于安装与 pack);
- dispatch.rs 一条分支、handle.rs 一条分支、state.rs 的 adopt 字段与一条 apply 分支;
- host/install.rs 的「还没有接入安装管线…请先在实例页导入已有版本」改成指向真入口:
  那里以前是一句假话(实例页根本没有导入动作),现在向导落地了,它才成立。
This commit is contained in:
AskaEth committed 2026-11-10 19:37:41 +08:00
1 parent 26e4fbb91d
commit 5a59cb33b2
6 files changed
+30 -1

No files matched your search

+9
View File
@@ -12,6 +12,8 @@ use crate::dto::{
// 主线(M109 的 Content* / M113 的 Pack*)与 M114 的 Authlib*/AccountNotice 的并集。 // 主线(M109 的 Content* / M113 的 Pack*)与 M114 的 Authlib*/AccountNotice 的并集。
AccountNotice, AccountNotice,
AccountView, AccountView,
AdoptCommand,
AdoptEvent,
AgentEvent, AgentEvent,
AuthlibLoginView, AuthlibLoginView,
AuthlibRequest, AuthlibRequest,
@@ -149,6 +151,11 @@ pub enum CoreEvent {
// M113: import/export // M113: import/export
/// 导入/导出(M113):进度、结果、探测诊断、导出预检(子枚举见 [`PackEvent`]) /// 导入/导出(M113):进度、结果、探测诊断、导出预检(子枚举见 [`PackEvent`])
Pack(Box<PackEvent>), Pack(Box<PackEvent>),
/// 导入已有版本(M223):扫描 / 预检 / 完成 / 失败(子枚举见 [`AdoptEvent`])
///
/// 与 [`Self::Pack`] 分开是**语义**上必须的:整合包导入会把内容真搬进实例目录,
/// 而这里只登记盘上已有的版本、写两份配置(`versions/` 一个字节都不动)。
Adopt(Box<AdoptEvent>),
/// 自更新(M159):整份状态快照(检查结论 + 就位状态 + 用户是否已拒绝)。 /// 自更新(M159):整份状态快照(检查结论 + 就位状态 + 用户是否已拒绝)。
/// ///
/// 与 `SettingsChanged` 同一条形态:快照整体替换,UI 不做增量合并。 /// 与 `SettingsChanged` 同一条形态:快照整体替换,UI 不做增量合并。
@@ -263,6 +270,8 @@ pub enum AppCommand {
// M113: import/export // M113: import/export
/// 整合包导入/导出(M113):导入 / 预检 / 确认写盘 / 关面板(子枚举见 [`PackCommand`]) /// 整合包导入/导出(M113):导入 / 预检 / 确认写盘 / 关面板(子枚举见 [`PackCommand`])
Pack(Box<PackCommand>), Pack(Box<PackCommand>),
/// 导入已有版本(M223):扫描 / 预检 / 确认登记 / 关面板(子枚举见 [`AdoptCommand`])
Adopt(Box<AdoptCommand>),
// M159: 自更新 // M159: 自更新
/// 查一次更新(设置页「立即检查」;会清掉「忽略这个版本」的标记并重新请求网络) /// 查一次更新(设置页「立即检查」;会清掉「忽略这个版本」的标记并重新请求网络)
CheckUpdate, CheckUpdate,
+2
View File
@@ -253,6 +253,8 @@ impl CoreHost {
// (`CancelInstall` 会把标记置位,下载在阶段边界收尾)。 // (`CancelInstall` 会把标记置位,下载在阶段边界收尾)。
// M113: import/export —— 导入 / 预检 / 确认写盘 / 关面板 // M113: import/export —— 导入 / 预检 / 确认写盘 / 关面板
AppCommand::Pack(command) => self.pack(*command), AppCommand::Pack(command) => self.pack(*command),
// M223: 导入已有版本 —— 扫描 / 预检 / 确认登记 / 关面板
AppCommand::Adopt(command) => self.adopt(*command),
AppCommand::InstallContent(request) => { AppCommand::InstallContent(request) => {
let cancel = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)); let cancel = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
self.install_cancel = Some(std::sync::Arc::clone(&cancel)); self.install_cancel = Some(std::sync::Arc::clone(&cancel));
+1
View File
@@ -69,6 +69,7 @@ impl CoreHost {
// M105 的形状(代次丢包)为准:旧任务(已取消 / 被下一轮顶掉)的进度一律丢掉。 // M105 的形状(代次丢包)为准:旧任务(已取消 / 被下一轮顶掉)的进度一律丢掉。
// 这是「点了取消没反应」的根因:取消时 `InstallProgress(None)` 刚把面板收回, // 这是「点了取消没反应」的根因:取消时 `InstallProgress(None)` 刚把面板收回,
// 旧任务的下一条「下载中」事件立刻又把它点亮。 // 旧任务的下一条「下载中」事件立刻又把它点亮。
HostTask::Adopt { event, epoch } => self.handle_adopt(*event, epoch),
HostTask::Install { progress, epoch } => { HostTask::Install { progress, epoch } => {
if epoch != self.install_epoch { if epoch != self.install_epoch {
return; return;
+1 -1
View File
@@ -106,7 +106,7 @@ pub fn supported(kind: LoaderKind) -> bool {
/// 不支持的加载器 → 给用户的可执行建议。 /// 不支持的加载器 → 给用户的可执行建议。
pub fn unsupported_reason(kind: LoaderKind) -> String { pub fn unsupported_reason(kind: LoaderKind) -> String {
format!( format!(
"{} 还没有接入安装管线(目前支持原版 + Fabric/Quilt/Forge/NeoForge/LiteLoader);请先在实例页导入已有版本,或换成受支持的加载器。", "{} 还没有接入安装管线(目前支持原版 + Fabric/Quilt/Forge/NeoForge/LiteLoader);如果别的启动器已经装好了这个版本,可以在实例页用「导入已有版本」把它只读接进来(不复制文件),否则请换成受支持的加载器。",
kind.label() kind.label()
) )
} }
+11
View File
@@ -68,6 +68,17 @@ pub enum HostTask {
/// 任务代次 /// 任务代次
epoch: u64, epoch: u64,
}, },
// M223: 导入已有版本
/// 扫描 / 预检 / 确认的结果(一条事件 + 任务代次)
///
/// 代次是 adopt 自己的(`CoreHost::adopt_epoch`),**不**与安装或 pack 的代次共用:
/// 关一次导入面板不该把下载页在跑的安装静默丢掉。
Adopt {
/// 事件载荷(扫描 / 预检 / 完成 / 失败)
event: Box<crate::dto::AdoptEvent>,
/// 任务代次
epoch: u64,
},
/// 安装进度(高频,host 只做聚合与转发) /// 安装进度(高频,host 只做聚合与转发)
Install { Install {
/// 进度快照 /// 进度快照
+6
View File
@@ -8,6 +8,7 @@ use crate::dialogs::DialogQueue;
use crate::dto::{ use crate::dto::{
// 主线(M105 的 `LoaderKind` / M113 的 `PackState`)与 M114 的 `AuthlibLoginView` 并集。 // 主线(M105 的 `LoaderKind` / M113 的 `PackState`)与 M114 的 `AuthlibLoginView` 并集。
AccountView, AccountView,
AdoptState,
AppEvent, AppEvent,
AuthlibLoginView, AuthlibLoginView,
CoreEvent, CoreEvent,
@@ -133,6 +134,8 @@ pub struct AppState {
pub content: ContentState, pub content: ContentState,
/// 整合包导入/导出:进度 / 结果 / 探测诊断 / 导出预检(M113) /// 整合包导入/导出:进度 / 结果 / 探测诊断 / 导出预检(M113)
pub pack: PackState, pub pack: PackState,
/// 导入已有版本(M223):扫描 / 预检 / 失败 / 完成(**只装事件态**,表单在页面本地态)
pub adopt: AdoptState,
} }
impl Default for AppState { impl Default for AppState {
@@ -178,6 +181,7 @@ impl AppState {
live_session: None, live_session: None,
content: ContentState::default(), content: ContentState::default(),
pack: PackState::default(), pack: PackState::default(),
adopt: AdoptState::default(),
} }
} }
@@ -296,6 +300,8 @@ impl AppState {
CoreEvent::Update(view) => self.update = *view, CoreEvent::Update(view) => self.update = *view,
// M113: import/export // M113: import/export
CoreEvent::Pack(event) => self.pack.apply(*event), CoreEvent::Pack(event) => self.pack.apply(*event),
// M223: 导入已有版本(唯一写入点:`AdoptState::apply`)
CoreEvent::Adopt(event) => self.adopt.apply(*event),
CoreEvent::ContentResults(results) => self.apply_content(*results), CoreEvent::ContentResults(results) => self.apply_content(*results),
CoreEvent::ContentFailed(failure) => self.apply_content_failure(*failure), CoreEvent::ContentFailed(failure) => self.apply_content_failure(*failure),
// M162:详情/版本列表(判断逻辑在 `state/content.rs`,这里只有一行投递) // M162:详情/版本列表(判断逻辑在 `state/content.rs`,这里只有一行投递)