diff --git a/crates/presenter/src/state.rs b/crates/presenter/src/state.rs index 5fad98a..a3b6518 100644 --- a/crates/presenter/src/state.rs +++ b/crates/presenter/src/state.rs @@ -40,13 +40,12 @@ use crate::wizard::WizardState; // 所以这里没有 `mod ai;` / `pub use ai::AiSession;`——M114 r1 曾把旧结构搬到 `state/ai.rs`, // 该文件已随 rebase 删除,**以 main 的 agent 契约为准**。 mod accounts; +mod live; mod tiles; +pub use live::MAX_LIVE_LINES; pub use tiles::{grid_positions, TileCell}; -/// 实时日志最多保留的行数(滚动窗口;更多行由日志页的筛选/历史会话承担)。 -pub const MAX_LIVE_LINES: usize = 2_000; - /// 一份加载器版本清单查询的结果(`Ok` = 最新在前;`Err` = 人读原因)。 pub type LoaderVersions = Result, String>; @@ -317,25 +316,6 @@ impl AppState { self.ai_mode() == AiPanelMode::Page || !self.prefs.ai_collapsed } - /// 实时日志增量:只追加,封顶 [`MAX_LIVE_LINES`] 行(滚动窗口)。 - fn append_live_lines(&mut self, batch: &crate::dto::LiveLogBatch) { - if self - .live_session - .as_deref() - .is_some_and(|session| session != batch.session) - { - // 换了一个会话在跑:清掉上一场的行,避免两场日志混在一起 - self.log_lines.clear(); - } - self.live_session = batch.running.then(|| batch.session.clone()); - self.selected_session = Some(batch.session.clone()); - self.log_lines.extend(batch.lines.iter().cloned()); - if self.log_lines.len() > MAX_LIVE_LINES { - let drop = self.log_lines.len() - MAX_LIVE_LINES; - self.log_lines.drain(..drop); - } - } - /// 按搜索词过滤后的磁贴网格(顺序稳定 = 实例列表顺序)。 pub fn tiles(&self) -> Vec> { let query = self.instance_query.trim().to_lowercase(); diff --git a/crates/presenter/src/state/live.rs b/crates/presenter/src/state/live.rs new file mode 100644 index 0000000..15d2a57 --- /dev/null +++ b/crates/presenter/src/state/live.rs @@ -0,0 +1,30 @@ +//! 实时日志的滚动窗口(从 `state.rs` 搬出,守 400 行硬线)。 +//! +//! 纯搬移:常量与 `append_live_lines` 一字未改;`state.rs` 用 `pub use` 再导出 +//! [`MAX_LIVE_LINES`],老路径 `crate::state::MAX_LIVE_LINES` 继续可用。 + +use super::AppState; + +/// 实时日志最多保留的行数(滚动窗口;更多行由日志页的筛选/历史会话承担)。 +pub const MAX_LIVE_LINES: usize = 2_000; + +impl AppState { + /// 实时日志增量:只追加,封顶 [`MAX_LIVE_LINES`] 行(滚动窗口)。 + pub(super) fn append_live_lines(&mut self, batch: &crate::dto::LiveLogBatch) { + if self + .live_session + .as_deref() + .is_some_and(|session| session != batch.session) + { + // 换了一个会话在跑:清掉上一场的行,避免两场日志混在一起 + self.log_lines.clear(); + } + self.live_session = batch.running.then(|| batch.session.clone()); + self.selected_session = Some(batch.session.clone()); + self.log_lines.extend(batch.lines.iter().cloned()); + if self.log_lines.len() > MAX_LIVE_LINES { + let drop = self.log_lines.len() - MAX_LIVE_LINES; + self.log_lines.drain(..drop); + } + } +}