fix(app-iced): M125 chips 档列表不被选项区压成缝;Compact 档主版本首项不再裁字

两条缺陷都是 M123 取证时在真图上拍出来的,塔台另行核过图:

缺陷 1(medium):chips 档(窗口 < 736,可用宽 < 600)里选项区按内容高
≈316px 钉在列表下面,列表只剩 18px(0.4 行,行高 44)——版本号读不出来、
换不了版本。修法:`rows::TailShare` 两档,chips 档改成「列表与面板各吃一半、
面板自己可滚」(列表拿到 ≈182px = 4 整行,面板顶端那个实心「安装」与五个
loader chip 仍在屏内);三栏三档照旧钉死(760 高下列表还有 3 整行、面板
整块在屏内,两样都对)。判据按档位而不是按高度:页面模型里只有 window_width,
窗口高度没接进页面(边界写进 TailShare 文档与报告)。

缺陷 2(medium):Compact 档主版本栏宽 64,`ListItem` 两侧内边距各 16 ⇒ 文本格
32,首项「All versions」要 ≈84 ⇒ 图上只剩「All v」;中文「全部版本」= 4 全角字
= 64,32 里只剩「全部」且正好顶到裁切边。修法:图标条档的「全部版本」不画文字,
改画与本页第一级那个「全部」同一个网格图标(40×40 Tonal 药丸 + 全称 tooltip);
桶标签(1.21/24w,实测墨迹 26)放得下,照旧画原文。`rails.rs` 那条「64 宽里
1.21 仍完整」的注释改成实测宽度表,并写清它对首项不成立。

顺带:列表与尾部面板之间补上分隔线(三态一致),`rows::content` 与两个装配点
按档位传 `TailShare`。

守门:
- `tests/options_shot.rs` 解掉 M123 那条 `#[ignore]`(期望值一个字没改,只加
  「列表区 ≥ 3 整行」与「面板仍在屏内、没被底边切」两条);
- 新增 `a_compact_tier_shot_draws_an_icon_for_the_first_major_entry`:缺陷 2 的
  像素守门(首项是 40×40 居中药丸,不是 64×44 通栏文字行)。复审建议的
  「墨迹右边界 ≤ 栏右内边界」在坏图上也是绿的(修前墨迹 216..244,边界 248),
  所以改钉形状,理由写在测试文档里;
- `tests/rails.rs`:中文与英文都走 Icon 分支、以及 32px 文本格的宽度账
  (「全部版本」= 64 > 32 是精确值,「全部」= 32 零余量所以不选短标签);
- `tests/view.rs`:档位 → TailShare 的决策面 + 两个装配点都按档位传。

未改产品文案、未改窗口最小宽、未动 M123 的任何断言期望值。
This commit is contained in:
AskaEth committed 2026-11-05 15:48:57 +08:00
1 parent df0e98d811
commit 822f98022d
7 files changed
+444 -47

No files matched your search

+69 -6
View File
@@ -17,6 +17,24 @@
//! 折行的唯一可能来源是定宽格子挤爆容器——那条由列表列下限 424 挡住(`layout/rails/tests.rs`
//! 的扫描断言)。
//!
//! ## 尾巴不能把列表压成缝(M125 缺陷 1)
//!
//! 这一列是 `column![搜索, 分隔线, 计数头, 列表(Fill), 尾巴]`:`body` 吃剩下的高度、`tail`
//! 按内容高钉死。iced 的 `Column` 不会把溢出交给滚动,所以**尾巴一高,列表就被压成一条缝**——
//! M123 在 700×760 拍的 `02-options-fabric-en-light-chips700.png` 里,8 行版本只剩 **18px**
//! 可视高(行高 44),版本号一个字都读不出来,用户想换版本点不到。
//!
//! 病根是 chips 档比三栏档多花两行 chip(tabs 48 + chips 48 + 两处间距),而选项区那一块
//! 固定 ≈316px(版本行 40 + 标题 16 + 五个 loader chip 34 + 标题 16 + 菜单 112 + 实例名 56)。
//! 同样的 760 高窗口里:三栏档列表还剩 158px(3 整行),chips 档只剩 18px。
//!
//! 修法是 [`TailShare`] 两档:三栏档照旧钉死(面板整块在屏内),chips 档改成两半各 `Fill`
//! ——列表拿到 ≈182px(**4 整行**),面板拿到同样一半、**自己可滚**(顶端那个实心「安装」
//! 按钮与五个 loader chip 仍在屏内,实例名那一格滚一下就到)。
//!
//! 这条判据按**档位**而不是按高度:页面的模型里只有 `window_width`,窗口高度没接进页面,
//! 所以「760 高到底够不够」在运行时是未知量(边界写在 [`TailShare`] 的文档里)。
//!
//! ## 搜索的三条口径
//!
//! | 情形 | 画什么 | 为什么 |
@@ -50,15 +68,20 @@ use crate::theme::Ui;
use super::super::frame;
use super::super::layout::rails::{LIST_DATE_WIDTH, LIST_KIND_WIDTH, ROW_GAP, ROW_ICON_BUTTON};
use super::super::layout::VersionRailTier;
use super::super::Message;
use super::model::{Download, VersionRow};
use super::{install, states};
/// 列表列(三栏档与 chips 档共用一份)。
///
/// `share` 决定「列表」与「尾部面板」怎么分这块高度:三栏档钉死面板、chips 档各吃一半
/// (见 [`TailShare`] 与模块文档「尾巴不能把列表压成缝」)。
pub(super) fn content<'a>(
ui: &'a Ui,
catalog: Catalog,
model: &'a Download,
share: TailShare,
) -> Element<'a, Message> {
let visible = visible(model);
@@ -72,13 +95,23 @@ pub(super) fn content<'a>(
list(ui, catalog, model, &visible)
};
let tail: Element<'a, Message> = if model.install.is_some() {
column![divider::full(ui), install::panel(ui, catalog, model)]
.spacing(ui.space(Space::X3))
.width(Length::Fill)
.into()
} else {
// 列表与尾部面板之间**总是**有一条分隔线(三态一致):M123 的取证图里「选好了版本」
// 那一态原先没有它,版本行与选项区第一行(版本号 + 安装按钮)读起来像同一块内容。
let tail: Element<'a, Message> = column![
divider::full(ui),
install::panel(ui, catalog, model)
]
.spacing(ui.space(Space::X3))
.width(Length::Fill)
.into();
// chips 档:面板收回自己的一半、内部可滚(它原先按内容高钉死,把列表压成 18px 的缝)。
let tail: Element<'a, Message> = match share {
TailShare::Pinned => tail,
TailShare::Shared => scrollable(tail)
.height(Length::Fill)
.style(frame::scroll_style(ui))
.into(),
};
column![
@@ -94,6 +127,36 @@ pub(super) fn content<'a>(
.into()
}
/// 列表与尾部面板怎么分这块高度(M125 缺陷 1 的修法)。
///
/// | 档 | 分法 | 为什么 |
/// |---|---|---|
/// | `Wide` / `Narrow` / `Compact` | [`TailShare::Pinned`]:面板按内容高钉在底部,列表吃剩下的 | 竖栏档在 760 高的窗口里列表还剩 158px(3 整行),面板整块在屏内——两样都对 |
/// | `Chips` | [`TailShare::Shared`]:两半各 `Fill`,面板自己可滚 | chips 档比三栏档多花两行 chip(tabs 48 + chips 48 + 间距),列表只剩 **18px**(M123 实测 0.4 行),面板 316px 全在屏内也没用——版本号读不出来就换不了版本 |
///
/// 判据是**档位**不是高度:页面的模型里只有 `window_width`(`pages/model.rs`),窗口高度
/// 没有接进页面(要接得改 `pages/mod.rs` 的入口签名,超出本页的边界)。所以这里按「哪一档
/// 的竖排 chrome 会把列表压没」来分,并在报告里登记这条判据的边界。
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum TailShare {
/// 面板钉在底部(三栏档)。
Pinned,
/// 面板与列表各吃一半(chips 档)。
Shared,
}
impl TailShare {
/// 档位 → 分高方式(纯函数,单测直接钉它)。
pub(super) const fn of(tier: VersionRailTier) -> Self {
match tier {
VersionRailTier::Chips => Self::Shared,
VersionRailTier::Wide | VersionRailTier::Narrow | VersionRailTier::Compact => {
Self::Pinned
}
}
}
}
/// 搜索条 + 清空按钮 + 命中数(三者一行;命中数只在有查询词时出现)。
pub(super) fn search_row<'a>(
ui: &'a Ui,