mirror of
https://github.com/shadowsocks/ShadowsocksX-NG.git
synced 2026-10-28 05:03:49 +00:00
6.7 KiB
6.7 KiB
服务器三栏视图
状态:实现与自动检查完成(2026-10-09);视觉及原生交互交给人工验证。 日期:2026-10-09。
本文记录本次任务的需求与设计决定,不代表当前实现。
确定要求
- 服务器页面使用三栏
HSplitView:左栏为来源边栏,中栏为服务器列表,右栏为原详情视图。用户后续要求用HSplitView替换最初批准的NavigationSplitView。 - 不修改原服务器详情与配置组详情。
- 来源边栏只有「本地」和「订阅」。主窗口原「订阅」管理页面保留。
- 「本地」展示手动来源的根层节点与后代,不展示虚拟目录根。
- 「订阅」展示订阅组与后代。
- Content 用 SwiftUI
Table展示层级,类似 Finder 列表大纲。 - 三列为「名称」「创建时间」「修改时间」。名称列含配置组/服务器图标、左对齐的名称,以及右对齐的活动目标图标。
- 活动目标图标只标记目标节点本身,包含配置组目标,不级联标记后代。保留无效服务器与包含无效后代的配置组的警告图标。
- 单击选择节点,激活继续使用现有命令。列表保持单选。
- 切换来源清空节点选择,详情显示原有空状态。
- 默认展示目录顺序。列头排序只改变展示顺序,不改写目录;每组的直接子节点分别排序。
- 拖动仅改变父分组,不提供同级重排。移除右键菜单「移动到…」。其余现有操作保留,继续调用
CatalogWorkflow。 - 时间采用系统本地化日期和时间,精度到分钟;未知时间显示「—」。时间事实遵循 GLOSSARY「节点时间戳」与 ADR-0031。
- 拖放仅接受手动分组与「本地」列表空白;空白代表目录根。新父分组不同才执行移动,移动后追加到目标目录顺序末尾。服务器、订阅节点、自身及后代均不接受落点。
- 列头排序时,分组和服务器一起排序;未知时间始终排在最后,相等值保持目录顺序。
- 折叠包含选中节点的配置组时,选择切换到收起的配置组,详情同步切换。
- 创建、导入或订阅组复制产生手动节点后,切换到「本地」,展开其祖先并选择新节点。
- 支持列宽调整,固定显示三列。名称列占剩余宽度,时间列初始宽度按日期文本确定。
- 三栏保持显示;改用
HSplitView后不提供NavigationSplitView的系统边栏显隐按钮。 - 来源、排序与展开状态在本次运行内跨主窗口页面切换保留,不落盘。重启恢复「本地」、目录顺序和全部展开。来源切换仍清空节点选择。
- 英文文案为
Local、Subscriptions、Name、Date Created、Date Modified。 - 增加列表排序菜单;「无」表示不施加展示排序、按目录顺序展示。英文为
None。列头继续切换对应列的升序与降序。 - 拖动移动成功后展开目标的祖先和目标分组,选择移动的节点,详情同步显示该节点。移到根层时无需展开目标分组。
实施前代码核实
ServersView使用HSplitView和扁平可见行List。CatalogTreeNode已包含来源、父节点与子树,但尚未包含创建时间与修改时间。CatalogEntry已保存两个可空时间戳,无需重新定义时间语义。- 现有目录移动命令支持同父重排;新列表必须拒绝同父拖放。
- 当前服务器管理的展开状态跨工作区页面切换保留,不落盘,重启全部展开。
最终确认
用户确认全部交互决定,并批准「无」的英文 None。用户要求使用 implement 流程,完成后提交当前分支;视觉验证交给人工,不由 Agent 执行。
Module 方向
沿用 CatalogWorkflow 的 Interface 提供目录事实与变更命令。列表展示排序不进入目录持久化。树投影补充非敏感时间事实。视图持有来源、排序、展开和选择的呈现状态。具体 Interface 在交互规则确定后核实,不增加仅转发调用的 Module。
浏览状态需由跨工作区页面切换仍存续的持有者管理;不能只放入随页面卸载的 ServersView 局部状态。来源与排序属于服务器页面呈现,不加入工作区顶层路由或持久配置。新 Table 直接使用节点身份驱动选择与展开,替换原扁平 List 呈现。保留原详情 View 与现有变更工作流。
文档范围
本次沿用配置目录、服务器配置、配置组、手动组、订阅组、活动目标与节点时间戳的既有定义,不新增领域术语。本次布局与呈现决定可以局部修改,不新增 ADR。
实现验证范围
- 核实非敏感树投影中的时间戳与来源筛选。
- 验证每层排序、未知时间、相等值及目录顺序恢复。
- 验证同父拖放不提交目录变更,跨父移动仍使用现有工作流。
- 构建 macOS App,检查原详情与现有操作的编译集成。
- 视觉与原生交互由人工验证:三栏、层级 Table、列宽、选择、展开、排序菜单与拖放。Agent 不执行视觉验证,构建与 hostless 测试不替代该证据。
实现期间的补充决定
- 排序按钮直接展开字段列表;Picker 使用 inline 样式,不产生额外「排序」子菜单。
- 用户要求只给树展开图标设置最小宽度。名称列的展开按钮设置最小宽度 24 点、最小高度 28 点;图标不放大。
- Table 的行由树投影按来源、每层展示排序与展开状态生成,名称列按深度缩进。展开按钮显式绑定既有展开状态,以控制点击宽度和折叠选择规则。
TableRowContent.dropDestination不提供拒绝返回值,因此不使用该行级接口。统一DropDelegate借用原生NSTableView.row(at:)区分行与空白;无效行不得回退为根落点。AppKit Adapter 不替换 Table 或其 delegate。- 目录节点拖放使用本进程专用载荷类型,释放时再次核对载荷身份与移动资格。
验证记录(2026-10-09)
- 定向验证树投影时间戳、来源筛选、每层排序、未知时间最后、相等值稳定、折叠选择和同父移动拒绝。
- Debug 构建通过;全量 hostless 摘要为 976 个测试通过、0 失败、0 跳过,包含 1062 次参数化执行。
- 两组 Python 离线检查分别通过 4 项与 17 项。
- 格式化和 diff 检查通过;SwiftLint 为 22 条非严重警告,严重违规为 0。ServersView 文件长度仍有警告。
- code-review 的 Standards 与 Spec 两轴最终均为 0 项发现;初次发现的无效行落点问题在复核中关闭。
- 原生拖放命中、菜单呈现、展开按钮点击区域与三栏视觉未验证,按用户要求由人工验证。