--- id: T-203 title: 主界面软件列表 phase: 2 deps: [T-202, T-003] status: DONE created: 2026-07-16 issue: null context_ref: 819b1cda1bd155c5cb76e7b05d45507f67bdb42d claim_branch: null work_branch: agent/codex/T-203 write_paths: - docs/tasks/T-203.md - core/application/ - app-modern/ui/gio/ - app-modern/cmd/softbox/ - app-win7/ui/gio/ - app-win7/cmd/softbox/ - docs/routes.md - docs/04-architecture.md - docs/current-state.md --- ## 问题 / 背景 可信 Catalog 与本地状态已经可用,但两个客户端仍只显示空 AppShell。主视图需要在不把磁盘/网络 IO 放进 Layout 的前提下,支持数百项、搜索、分类和全部/已安装/可更新切换;若控件按列表索引保存,筛选或排序后点击状态会错位。 ## 方案 1. 在 `core/application` 建立共享、无 IO 的 CatalogListModel,列表项使用稳定软件 ID;支持名称/ID/tag 搜索、分类集合与 all/installed/updates 三种视图。 2. 过滤结果保持 Catalog 原顺序;查询和分类变化不重建源数据,Gio 只消费当前可见切片。 3. modern/win7 分别实现 Gio AppShell:顶部搜索与分类、左侧视图切换、中部惰性 `layout.List`、有帮助文案的空状态和底部状态栏。 4. 每个 AppRow 的 Clickable 按软件 ID 存入 map,不按可见索引;每帧先 drain 点击,再执行布局。 5. 使用扁平、高对比、44dp 最小交互目标和 4/8dp 间距体系;Legacy 减少装饰但保持同一语义。 6. 测试共享筛选规则、ID 控件稳定性,并用数百项 + 有限 viewport 证明 layout.List 只布局可见行。 ## 验收要点 - 搜索覆盖名称、ID 与 tags,忽略大小写和首尾空白。 - 分类筛选与 all/installed/updates 视图可组合;无结果显示清晰空状态。 - 两个 Gio 版本均使用惰性 layout.List;500 项在有限 viewport 中不会布局全部行。 - 行控件状态按 app ID 保持,过滤/切换视图后不串行。 - Layout 代码不读文件、不访问网络、不计算哈希。 - modern 与 win7 UI 测试/构建、Go 1.20 core vet/test、完整双目标闸门和治理校验通过。 ## 边界(不改什么) - 不实现详情弹层与图标缓存(T-204)。 - 不发起下载、安装、启动或真实 Catalog 网络装配;主操作仅展示当前状态语义。 - 不实现下载中/最近使用视图或多标签复选;路线图 MVP 本任务只冻结 all/installed/updates。 - 不添加动画、阴影、emoji 图标或新 UI 依赖。 ## 协作约束 未启用 Gitea;本任务在 `agent/codex/T-203` 分支串行执行。`ui-ux-pro-max` 的本轮约束是高对比扁平界面、可见焦点/空状态、44dp 目标、虚拟化 50+ 项和键盘顺序与视觉顺序一致。 ## 执行记录 - 2026-07-16:按 `ui-ux-pro-max` 先生成 SoftBox 设计系统并检索虚拟列表、键盘导航、空状态与焦点规则;最终采用高对比浅色、扁平无阴影、4/8dp 间距、44dp 控件和明显 Legacy 标识。 - 2026-07-16:在 `core/application` 建立无 IO `CatalogListModel`;搜索覆盖名称/ID/tags,单分类与 all/installed/updates 可组合,过滤保持 Catalog 原顺序并保存 selected app ID。 - 2026-07-16:modern Gio v0.10.1 与 win7 Gio v0.6.0 分别实现搜索栏、横向分类、左侧视图切换、惰性软件列表、状态/原因文案、两类空状态和恢复筛选操作。 - 2026-07-16:Editor/按钮/软件行均提供键盘焦点反馈;自定义行补充 semantic button/description,未使用 emoji、阴影或额外 UI 依赖。 - 2026-07-16:行 Clickable 以软件 ID 为键保存;筛选与 Catalog 快照更新后同 ID 控件保持原实例,移除的软件控件被释放。 - 2026-07-16:两个适配各用 500 项 + 有限 viewport 测试证明 `layout.List` 只布局可见子集;空 AppShell 仍保持窗口尺寸测试。 - 2026-07-16:同步 `docs/routes.md`、`docs/04-architecture.md` 与 `docs/current-state.md`;真实 Catalog 网络/密钥装配仍保持在 Layout 外。 - 定向验证通过:`go -C core test -count=1 ./application`、modern/win7 `go test -count=1 ./ui/gio`。 - Layout IO 扫描通过:`rg` 检查两个 `ui/gio` 下无 `os`、`net/http`、文件读写、filepath 或 sha256 调用。 - 完整验证通过:`./scripts/verify_phase0.ps1`,包含 Go 1.20.14 core vet/test、治理/边界/版本检查及 modern/win7 双目标测试与构建。 - 提交前检查通过:`git diff --check`。 - 工作区中的未跟踪 `soft_quay.code-workspace` 与本任务无关,已保留且未纳入提交。