edit | blame | history | raw

容器内 App 手动排序专题讨论纪要

用户目标

  • 用户希望在容器中,每个 App 的位置可以拖动,改变默认显示顺序。
  • 本轮要求拉 2 个架构师、1 个代码审核员、1 个 QA 做专题讨论,评估可行性、开发风险和最优方案。

参与视角

  • 架构师 A:数据模型、分类方案、导入导出、SmartStart 影响。
  • 架构师 B:App Grid / 容器视图 / 拖拽交互。
  • 代码审核员:风险、必须避免的实现方式、代码切分。
  • QA:验收矩阵、自动化与人工验证边界。

关键结论

  • 功能可做,但不能只做 UI 数组重排;必须把容器内 App 顺序持久化到 TagDatabase.Store
  • 当前 App 默认顺序来自扫描后名称排序,AppIndexer.group() 只负责分组,组内顺序没有用户字段。
  • 推荐新增 containerAppOrder: [String: [String]],按稳定容器 ID 保存每个容器内的 app path 顺序。
  • 容器 ID 不能使用本地化显示名;建议使用 tag:<tagName>system:<SmartCategoryID>__container.uncategorized__container.appleBuiltIn 等稳定 key。
  • 新字段必须纳入分类方案快照、导出、导入、恢复、SmartStart 回滚;否则“分类与布局”导出会丢布局。
  • 第一版只支持同一容器内拖动排序;跨容器移动/复制标签、拖到空白移除标签、Apple 内置保护等旧行为保持不变。
  • 不建议使用 SwiftUI onDrag/onDrop。当前 App Grid 是 AppKit NSViewRepresentable + 自定义拖拽,拖拽排序应在 AppGridCollectionView / AppGridGroupCardView / AppGridIconNSView 链路扩展。

推荐开发切分

  1. 数据层:
  • Store 增加 containerAppOrder,兼容旧 JSON。
  • 增加容器 ID helper 和排序 helper。
  • CategorySchemeFingerprint 纳入顺序字段。
  • 导入、导出、恢复、未分类重置、SmartStart replace、tag rename/delete/relocalize 清理或迁移顺序。
  1. UI hit-test:
  • AppGridCollectionView 增加同容器插入位置计算。
  • 排序拖拽与现有跨 tag 移动/复制拖拽隔离。
  • 先做本地预览,不落盘,不改跨容器行为。
  1. 集成:
  • ContentView 增加 reorder callback。
  • drop/end 时保存该容器完整顺序。
  • 刷新 displayGroups 后顺序保持。
  1. QA:
  • 旧 JSON 兼容、新 JSON roundtrip、导入导出、恢复、重置、SmartStart 数据断言。
  • macOS 14 typecheck/build metadata/window logic/Quick Search/SmartStart 现有回归。
  • 真实鼠标拖拽、滚动拖拽、显示模式、标签位置、编辑模式必须人工 smoke。

风险评估

  • 最小方案风险:中等。
  • 若一次性支持跨容器插入、跨机器稳定匹配、复杂拖拽 payload、所有显示模式完整预览,风险升为高。
  • 最大风险点:
  • 刷新/重启后顺序丢失。
  • 导入导出/恢复/SmartStart 漏掉顺序。
  • 同容器排序误触发跨容器移动、复制、移除标签确认。
  • 用本地化显示名做 key 导致语言切换后顺序错位。
  • 编辑模式、tag 拖拽排序、hover bubble、滚动抑制互相冲突。

建议决策

  • 先做低风险 spike:只做同容器排序,path-based 顺序持久化,所有 display mode 读取排序,但第一版优先在容器/网格容器拖拽入口验证。
  • 暂不改 Quick Search 排名,不改 appTags 语义,不存像素坐标/IndexPath,不把顺序放 UserDefaults。