Files
Unlucky-Launcher/crates/presenter/src/state/content.rs
T
AskaEth c319f9dbfd fix(m162-rebase): M161 合入后三处越线文件回到 400 行内
rebase 到 0241f79(M161)之后,两侧各加了几行,这三个文件同时越过 400 行硬线
(guards.yml::file-size 会红)。处理原则:**不删语义、只搬位置**。

- `app-iced/src/pages/content/parts.rs` 410 → **240**:把状态层(loading / empty / failed /
  offline / centered / status_body)搬到新文件 `pages/content/parts/status.rs`(200 行)。
  状态层本来就是「一屏只有一个」的独立东西,拆开后 parts.rs 只剩筛选条、列表、图标与排序文案。
- `presenter/src/dto/events.rs` 402 → **399**:`CoreEvent::ContentDetail` 的文档由 4 行压成 1 行
  (字段说明一个不少,`project` 是请求时选中的 id 这句保留)。
- `presenter/src/state.rs` 404 → **400**:把 `ContentFailed` / `ContentDetail` 两个事件的落地
  搬进 `state/content.rs`(`apply_content_failure` / `apply_content_detail`),state.rs 只剩
  一行投递——与既有的 `apply_content` 同一个形状。

`state/content.rs` 58 → 64(两个新方法),仍在 400 内。语义零改动:只是投递点换文件。
2026-11-07 17:37:13 +08:00

65 lines
2.9 KiB
Rust

//! 内容库的状态机(M109):结果落地与条件提交两件事。
//!
//! 从 `state.rs` 拆出(那个文件重新合流 M105 之后贴着 400 行上限)。放在 `impl AppState` 的
//! **另一个 impl 块**里,路径与可见性都不变:`apply_core` 直接调 `self.apply_content(..)`。
use crate::dto::{ContentDetail, ContentFailure, ContentQuery, ContentResults};
use super::AppState;
impl AppState {
/// 内容库结果落地(M109):同条件换页 ⇒ **追加**;换条件 ⇒ **整批替换**;迟到 ⇒ 丢掉。
///
/// 这三条就是「列表画的永远是当前筛选条件」的全部保证——页面自己没有过滤逻辑,也没有第二份真相。
pub(super) fn apply_content(&mut self, results: ContentResults) {
self.content.pending = false;
self.content.failed = None;
if !self.content.accepts(&results) {
// 迟到的一批:用户已经改了条件,覆盖上去就会出现「筛选条说 A、列表是 B」。
return;
}
// **先**按「这一页装没装满」记一位,再把它并进累计列表(复审 P1-2:判据不能读累计值)。
self.content.last_page_filled = results.has_more();
match &mut self.content.results {
Some(current) if results.query.offset > 0 => {
current.hits.extend(results.hits);
current.total = results.total;
current.curseforge = results.curseforge;
current.query = results.query;
}
_ => self.content.results = Some(results),
}
}
/// 检索失败落地(M162 起带大类):清掉「在飞」并记下失败。
pub(super) fn apply_content_failure(&mut self, failure: ContentFailure) {
self.content.pending = false;
self.content.failed = Some(failure);
}
/// 详情事件落地(M162):`Ok` 走 `apply_detail`、`Err` 走 `fail_detail`,两者都按
/// **请求时的项目 id** 判迟到(用户可能已经切到别的项目了)。
pub(super) fn apply_content_detail(
&mut self,
project: &str,
result: Result<ContentDetail, ContentFailure>,
) {
match result {
Ok(detail) => self.content.apply_detail(project, detail),
Err(failure) => self.content.fail_detail(project, failure),
}
}
/// 记下新的检索条件并进入「请求在飞」态(指令由调用方随后 dispatch)。
pub fn set_content_query(&mut self, query: ContentQuery) {
self.content.pending = true;
self.content.failed = None;
if query.offset == 0 {
self.content.last_page_filled = false;
// 换条件(不是换页):先把旧结果清掉,否则加载态会画出上一批命中项。
self.content.results = None;
}
self.content.query = query;
}
}