Files
soft_quay/docs/routes.md
T

97 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 页面与视图结构(Gio)
> 本项目是 Gio 桌面应用,没有 URL 路由;本文约定页面(视图)划分、职责和组件归属。现代版与 Win7 版共享 ViewModel 和交互语义,Gio 控件实现允许分别适配。
## 主窗口布局
```text
┌─────────────────────────────────────────────┐
│ 顶部栏:搜索框 · 分类筛选 · 检测更新 · 下载队列入口 │
├────────┬────────────────────────────────────┤
│ 左侧 │ 中部:虚拟化软件列表(layout.List) │
│ 视图 │ 每项:图标·名称·版本·状态·进度·主操作按钮 │
│ 全部 │ │
│ 已安装 │ 右侧/弹层:软件详情 │
│ 可更新 │ 版本 · 简介 · 安全诊断 · 状态 · 操作 │
│ 最近使用│ │
├────────┴────────────────────────────────────┤
│ 底部状态栏:网络 · 任务数 · 磁盘 · 盒子版本(Legacy 标识) │
└─────────────────────────────────────────────┘
```
## 视图清单
| 视图 | 职责 | MVP |
| --- | --- | --- |
| 软件列表(主视图) | T-203 已实现全部/已安装/可更新切换、名称/ID/tag 即时搜索、单分类筛选、稳定滚动与明确空状态;下载中/最近使用和多标签复选随对应用例后续接入 | P0 |
| 软件详情(弹层或右栏) | T-204 已实现右栏、关闭、版本/分类/简介/tags/状态/不可用原因/教程/主页展示与内存图标;T-611 仅对当前 `unsafe_cache` 显示稳定安全诊断和人工恢复提示;真实操作和授权事实随对应模块接入 | P0 |
| 下载队列 | 所有任务的进度、速度、剩余时间;暂停/取消/重试 | P0 |
| 设置 | 并发数、目录、代理、自动检查更新、beta 通道、日志级别、便携模式(V2) | P0(最小集) |
| 授权 | 许可证导入、已授权软件列表、machine 信息、换绑/申诉入口 | P0 |
| 提示/错误弹窗 | 失败原因、重试路径、更新确认、退出运行中软件提示 | P0 |
## 组件归属
| 组件 | 归属 | 说明 |
| --- | --- | --- |
| AppShell | 全局 | 窗口框架、顶部栏、左侧导航、底部状态栏 |
| AppList | 主视图 | 惰性 `layout.List`;控件状态按软件 ID 保存,不按列表序号 |
| AppRow | 主视图 | 单个软件项:状态、进度和主操作按钮 |
| AppDetail | 详情 | 详情展示与操作 |
| DownloadPanel | 下载队列 | 任务列表与控制 |
| SettingsForm | 设置 | 设置项读写(经 application 用例) |
| LicensePanel | 授权 | 导入与状态展示 |
| Toast/Dialog | 全局 | 错误与确认交互 |
T-610 固定 modern 与 Win7 两个 `ui/gio` 适配器的同 package 文件职责;文件名镜像,但不跨 workspace 共享 Gio 代码:
| 文件 | 职责 |
| --- | --- |
| `shell.go` | `AppShell` 状态/构造、`SetItems`/`ApplyIcon` 生命周期、根 `Layout` 与输入 drain |
| `shell_header.go` | 顶部栏、分类、view/filter 导航与版本特有 footer |
| `shell_catalog.go` | content/catalog、惰性列表、app row/icon 与空状态 |
| `shell_detail.go` | 详情布局、详情字段、`unsafe_cache` 安全诊断与动作/回退文案 helper |
| `shell_style.go` | palette/theme、panel 绘制、view/status 文案与颜色 helper |
这些文件仍共同实现一个 `gio` package,不是新增页面 API 或状态层。modern-only 的 `layoutCatalog`/`layoutFooter`/`actionLabel` 等保留在对应职责文件,Win7 不增加空壳;后续视图应进入相应职责文件,不能重新把布局链堆回根 `shell.go`。
每个页面用独立 struct 保存:`widget.Clickable`、`widget.Editor`、`layout.List`、过滤条件、当前 ViewModel、pending RequestID、临时提示和错误状态。
## 交互规则(硬约束)
- 每帧先 drain application relay 与点击事件,再提交用例;后台只把事件放入有界 relay 并调用并发安全的 `Window.Invalidate`,Frame/UI goroutine 在 `ApplyEvent` 中更新 ViewModel/ImageOp。
- Layout 中不得读磁盘、访问网络、计算哈希;图标走内存 + 磁盘缓存(按 DPI)。
- 数百个软件项滚动不卡顿是验收标准,不是优化项。
- 未验证/不兼容的软件显示原因,操作按钮禁用,不静默失败。
- Win7 版允许减少动画、阴影和高成本渲染,但交互语义与现代版一致,并明显展示 Legacy 标识。
T-203 已落地的列表交互约束:
- 共享 `core/application.CatalogListModel` 只消费预先准备的内存快照;搜索覆盖名称、稳定 ID 和 tags,分类与 all/installed/updates 可组合。
- modern/win7 都使用惰性 `layout.List`;500 项有限 viewport 测试必须证明不会布局全部行。
- Editor、视图按钮、分类按钮、软件行的键盘顺序与视觉顺序一致;搜索和软件行有可见焦点反馈,所有按钮最小高度 44dp。
- 行 Clickable 保存在以 app ID 为键的 map;筛选、视图切换或 Catalog 快照更新不按可见序号迁移控件状态。
- 无 Catalog 与过滤无结果是两个不同空状态;后者提供“显示全部软件”恢复操作。
T-608 用 modern/win7 同场景适配器契约固定上述接线:Editor 和视图/分类/行/恢复/关闭 Clickable 必须经 `Layout`/`drainInput` 更新共享 model;Catalog 重排后行事件仍按 AppID 选择,关闭详情保留筛选与 list First/Offset。500 项有限 viewport 同时核对实际布局计数与 `layout.List.Position.Count`;空 Catalog、过滤无结果及恢复按钮通过 Gio 语义树区分。两端测试只在 edition/窗口尺寸上保留真实差异,不互相 import Gio。
T-609 固定 `VisibleItems()` 的只读 snapshot generation:筛选或 Catalog 变化时由 model 完整构造新 backing array 后发布,已被上一帧持有的旧 generation 保持稳定;同一 generation 的每帧读取不复制。两个 Gio 适配仍只在 UI owner goroutine 读取,不得修改返回 slice、item 或 Tags,该契约不提供并发读写安全。
T-616 固定启动快照投递:`cmd` 只在后台运行 `CatalogBootstrap`,它将已准备内存快照或稳定失败 code 发布到 runtime;relay 后的 UI Frame 通过 `ApplyEvent` 更新 shell。初始 loading、`catalog_source_unconfigured`、`catalog_load_failed`、已加载空 Catalog 和筛选无结果必须有不同的可见文本,错误不清除已加载快照。当前没有可信发布配置时,只能显示未配置诊断,不能从 testdata、环境变量、任意 URL、未签名本地文件或 allow-all verifier 生成列表;任何这些 I/O/校验仍不得进入 Layout。
T-204 已落地的详情/图标约束:
- 点击软件行用 selected app ID 打开右侧详情,关闭后回到同一列表/筛选/滚动上下文。
- modern 与 Legacy 均显示版本、分类、简介、tags、状态、不可用原因、教程和主页文本;尚未接入的安装/启动/授权不伪装为已可执行操作。
- T-607 由 `IconEventDelivery` 在后台完成可信加载/解码并发布强类型 `IconReady`/`IconFailed`;有界 FIFO relay 只请求 Invalidate,Frame/UI goroutine drain 后才调用 `ApplyEvent`/`ApplyIcon`。相同 app 只接受最新且 IconRef/DPI 匹配的 request_id;Catalog 删除、IconRef 变化或取消后丢弃迟到结果,IconRef 变化同时清除旧 ImageOp。
- 图标未命中或离线缓存不可用时显示非 emoji 的字母占位,不阻塞列表或详情。
- T-611 将最近一次已验证失败保存为完整 `IconEventIdentity + IconFailureCode`;新请求、匹配 ready、IconRef/DPI 变化、取消和 app 删除清除旧诊断,同引用 Catalog snapshot 可保留。只有 `unsafe_cache` 在当前选中详情显示文字告警、`unsafe_cache`、app ID 与 `<digest>-<dpi>.icon` locator;`unavailable`/`invalid_content` 保持普通占位,不冒充安全事件。
- 安全告警必须有可访问标题、明确说明本次未继续远端获取/自动修复并指向 [故障排查](troubleshooting.md);颜色不能作为唯一信号,不得增加清理、隔离或重试按钮,不得显示绝对路径、原始 error、URL/query 或 link target。
## 导航规则
- 列表 → 详情:点击软件项;详情保留返回/关闭。
- 任一视图可进下载队列(顶部入口);任务完成后返回时列表状态已回填。
- 启动需授权的软件而无有效许可证时,引导到授权视图,不直接报错退出。
- 更新需要退出运行中的软件时,弹确认对话框,等待用户处理,超时取消更新。