cloud-drive-renamer/docs/superpowers/specs/2026-03-20-preview-panel-option-a-design.md

9.2 KiB

预览面板 Option A 设计

背景

当前预览面板已经具备以下能力:

  • 统计预览项数量、冲突数量与执行状态。
  • 按状态高亮冲突、失败、成功、待执行项目。
  • 在长列表场景下使用虚拟列表优化渲染性能。

但当前实现仍有一个明显的确认断点:用户在预览区只能看到新文件名,无法直接看到对应的旧文件名。这会导致用户在执行前需要依赖记忆完成确认,尤其在以下场景下体验较差:

  1. 文件名格式相近,只靠新名称无法分辨来源。
  2. 剧集提取、正则替换等规则会对多个文件同时生效,用户需要确认映射是否正确。
  3. 冲突和失败项虽然有状态提示,但用户无法第一时间知道“是哪一个原文件会出问题”。

与 docs/renamer.js 的对比中,这也是最容易被用户感知到的交互差距。因此本次选择采用 Option A:在不改变整体三栏布局的前提下,为每条预览项补充“旧名 -> 新名”对照信息。

目标

  • 在不重做整体布局的前提下,补齐预览项的“旧名 -> 新名”映射展示。
  • 保持当前三栏布局与信息密度,不引入更重的审阅台模型。
  • 让冲突项、失败项的可理解性提升,不需要用户额外点开详情或回到文件列表反查。
  • 尽量复用现有 PreviewItem 数据结构和 virtual-preview-list 渲染链路,降低改动面。

非目标

  • 不在本次改动中引入单条操作按钮,例如“排除”“仅重试此项”“从此项填充剧名”等。
  • 不将预览区改造成完整的“变更审阅中心”。
  • 不调整当前执行流程、冲突检测流程或批量执行引擎。
  • 不新增新的规则类型或剧集提取逻辑。

方案对比

方案 A:双行映射预览(采用)

  • 每条预览项显示:
    • 第一行:旧文件名 + 当前状态
    • 第二行:新文件名 + 方向箭头
    • 第三行:仅在必要时显示补充说明,例如冲突原因、失败原因或提取结果提示

优点

  • 最大收益来自补足确认链路,而不是重做布局。
  • 可以直接复用当前的 PreviewItem.file.name 与 PreviewItem.newName。
  • 改动集中在展示层,风险较低。
  • 与现有三栏布局兼容,不会显著压缩左右两栏可用空间。

缺点

  • 单条项目高度会增加,列表可视密度略低于当前实现。
  • 视觉表达力不如更重的“审阅台”方案。

方案 B:变更审阅视图

  • 每条项目除旧名、新名外,还显式展示规则来源、风险标签、操作建议。

优点

  • 表达力更强,后续可自然承接单条操作入口。

缺点

  • 单项高度更大,长列表滚动负担更高。
  • 需要重新设计预览面板层级,超出本轮“低风险优化”的目标。

采用方案:A。

交互设计

1. 面板整体结构

保留当前右侧预览面板结构:

  1. 标题区
  2. 统计区
  3. 列表区

不改变面板层级,只调整列表项视觉结构。

2. 预览项结构

每条预览项调整为三层信息:

第一层:旧文件名

  • 使用较弱的视觉层级展示原文件名。
  • 文本颜色弱于新文件名,但仍需足够可读。
  • 右侧保留状态标签,例如:
    • 成功
    • 待执行
    • 冲突
    • 失败

第二层:新文件名

  • 使用较强视觉层级展示新文件名。
  • 保持当前预览区域的主阅读焦点。
  • 可在最右侧加入轻量箭头,强调“从旧名映射到新名”。

第三层:补充信息

  • 仅在需要时展示,避免噪声。
  • 建议场景:
    • 剧集提取成功时:显示提取结果摘要,如 剧集提取 / 季号 01 / 集号 003
    • 冲突时:显示“与现有文件名重复”
    • 失败时:显示可读性更强的原因文案,而不是裸错误码

3. 状态表达

保留当前背景色与左侧强调边的状态表达方式:

  • success:浅绿色背景
  • warning/conflict:浅橙色背景
  • error:浅红色背景
  • pending:中性背景

但状态标签需要从“附属角标”升级为“与旧名同行的信息”,这样用户先看到旧文件,再看到它当前是否有风险。

4. 长文件名处理

  • 旧文件名与新文件名均保留单行截断。
  • title 保持完整名称悬浮提示。
  • 对失败原因仍使用一行或两行受控显示,避免把列表高度拉得过长。

5. 空状态与加载状态

沿用当前空状态和 loading 状态,不做额外改动。

架构与组件设计

涉及组件

  • [src/content/components/preview-panel.ts](/Users/lhly/chromeex/cloud-drive-renamer/src/content/components/preview-panel.ts)
  • [src/content/components/virtual-preview-list.ts](/Users/lhly/chromeex/cloud-drive-renamer/src/content/components/virtual-preview-list.ts)
  • [src/types/file-selector.ts](/Users/lhly/chromeex/cloud-drive-renamer/src/types/file-selector.ts)
  • [src/locales/zh_CN.json](/Users/lhly/chromeex/cloud-drive-renamer/src/locales/zh_CN.json)
  • [src/locales/zh_TW.json](/Users/lhly/chromeex/cloud-drive-renamer/src/locales/zh_TW.json)
  • [src/locales/en.json](/Users/lhly/chromeex/cloud-drive-renamer/src/locales/en.json)

数据结构

本方案优先不修改 PreviewItem 结构,因为现有数据已足够:

  • item.file.name:旧文件名
  • item.newName:新文件名
  • item.conflict:是否冲突
  • item.done:是否成功
  • item.error:失败原因

如需增加更友好的说明文案,优先在展示层通过状态推导生成,不新增持久化字段。

渲染职责

preview-panel

  • 继续负责统计区与外层容器。
  • 不承担单项结构逻辑,避免组件职责继续膨胀。

virtual-preview-list

  • 负责预览项的双行映射展示。
  • 继续承担虚拟滚动切换逻辑。
  • 负责把原始状态值转换成最终的显示块结构。

文案设计

推荐新增文案键

  • preview_old_name
  • preview_new_name
  • preview_mapping_arrow
  • preview_conflict_reason_existing_name
  • preview_extract_summary
  • preview_failed_reason_prefix

如果实现时认为标签文本过多,也可以不引入“旧名/新名”显式标题,而仅通过层级和箭头表达映射关系,以减少视觉拥挤。

错误文案策略

当前失败项可能直接显示错误码,例如 extract_episode_not_found。在本方案中建议:

  • UI 层优先转成面向用户的可读文案;
  • 保留原始错误码作为 title 或调试信息;
  • 避免在主列表里直接暴露生硬内部标识。

数据流

现有流程

  1. file-selector-panel 根据规则生成 previewList
  2. preview-panel 接收 items
  3. virtual-preview-list 渲染每个 PreviewItem

方案 A 调整后

数据流保持不变,仅增强最后一步渲染:

  1. file-selector-panel 无需新增字段
  2. preview-panel 无需新增协议
  3. virtual-preview-list 从 item.file.name 和 item.newName 生成双行映射视图

这意味着本次改动主要是视图层优化,而非状态管理或执行流程改造。

风险与权衡

1. 列表可视密度下降

双行结构会使单项高度增加。考虑到预览区已经支持虚拟列表,这个问题可接受,但需要控制补充信息的默认展示长度。

2. 样式复杂度提升

当前预览项样式较简单,双行结构会增加样式层级。需要确保:

  • 状态色仍然清晰;
  • 旧名不会抢走新名焦点;
  • 不引入与现有主题变量冲突的新颜色体系。

3. 国际化文案膨胀

若补充标签过多,会增加 i18n 维护成本。实现时应优先使用结构和层级表达含义,而不是堆更多标题文本。

测试设计

1. 组件渲染测试

针对 virtual-preview-list 增加测试,验证:

  • 成功项会同时展示旧名和新名。
  • 冲突项会显示冲突状态和冲突说明。
  • 失败项会显示失败状态和失败说明。
  • showStatus = false/true 时状态展示符合预期。

2. 截断与 title 测试

验证长文件名情况下:

  • 旧名、新名都不会撑破布局;
  • 完整名称仍能通过 title 获取。

3. 视觉回归检查

建议补一个组件级快照或 Playwright 截图验证,至少覆盖:

  • 普通项
  • 成功项
  • 冲突项
  • 失败项

4. 虚拟列表兼容性

确认增加双行结构后,虚拟列表的初始化与刷新逻辑不受影响,尤其是超过 200 条项目时的滚动与渲染稳定性。

实施建议

第一阶段

  • 仅修改 virtual-preview-list 渲染结构和样式。
  • 保持 preview-panel 统计区不变。
  • 保持数据结构不变。

第二阶段(可选)

  • 视实际效果决定是否在补充信息中加入更友好的失败原因翻译。
  • 若用户反馈仍希望进一步增强,可再演进到更强的审阅视图,而不是一次性做重。

结论

Option A 是一次典型的“高感知、低侵入”优化:

  • 它不解决所有预览场景问题;
  • 但它能直接补足当前最明显的确认断点;
  • 且几乎不需要改动执行逻辑、状态管理和数据结构。

因此本次建议按 展示层局部升级 的方式推进,先把“旧名 -> 新名”的确认能力补齐,再根据真实反馈决定是否继续向更重的审阅模型演进。