9.2 KiB
预览面板 Option A 设计
背景
当前预览面板已经具备以下能力:
- 统计预览项数量、冲突数量与执行状态。
- 按状态高亮冲突、失败、成功、待执行项目。
- 在长列表场景下使用虚拟列表优化渲染性能。
但当前实现仍有一个明显的确认断点:用户在预览区只能看到新文件名,无法直接看到对应的旧文件名。这会导致用户在执行前需要依赖记忆完成确认,尤其在以下场景下体验较差:
- 文件名格式相近,只靠新名称无法分辨来源。
- 剧集提取、正则替换等规则会对多个文件同时生效,用户需要确认映射是否正确。
- 冲突和失败项虽然有状态提示,但用户无法第一时间知道“是哪一个原文件会出问题”。
与 docs/renamer.js 的对比中,这也是最容易被用户感知到的交互差距。因此本次选择采用 Option A:在不改变整体三栏布局的前提下,为每条预览项补充“旧名 -> 新名”对照信息。
目标
- 在不重做整体布局的前提下,补齐预览项的“旧名 -> 新名”映射展示。
- 保持当前三栏布局与信息密度,不引入更重的审阅台模型。
- 让冲突项、失败项的可理解性提升,不需要用户额外点开详情或回到文件列表反查。
- 尽量复用现有
PreviewItem数据结构和virtual-preview-list渲染链路,降低改动面。
非目标
- 不在本次改动中引入单条操作按钮,例如“排除”“仅重试此项”“从此项填充剧名”等。
- 不将预览区改造成完整的“变更审阅中心”。
- 不调整当前执行流程、冲突检测流程或批量执行引擎。
- 不新增新的规则类型或剧集提取逻辑。
方案对比
方案 A:双行映射预览(采用)
- 每条预览项显示:
- 第一行:旧文件名 + 当前状态
- 第二行:新文件名 + 方向箭头
- 第三行:仅在必要时显示补充说明,例如冲突原因、失败原因或提取结果提示
优点
- 最大收益来自补足确认链路,而不是重做布局。
- 可以直接复用当前的
PreviewItem.file.name与PreviewItem.newName。 - 改动集中在展示层,风险较低。
- 与现有三栏布局兼容,不会显著压缩左右两栏可用空间。
缺点
- 单条项目高度会增加,列表可视密度略低于当前实现。
- 视觉表达力不如更重的“审阅台”方案。
方案 B:变更审阅视图
- 每条项目除旧名、新名外,还显式展示规则来源、风险标签、操作建议。
优点
- 表达力更强,后续可自然承接单条操作入口。
缺点
- 单项高度更大,长列表滚动负担更高。
- 需要重新设计预览面板层级,超出本轮“低风险优化”的目标。
采用方案:A。
交互设计
1. 面板整体结构
保留当前右侧预览面板结构:
- 标题区
- 统计区
- 列表区
不改变面板层级,只调整列表项视觉结构。
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_namepreview_new_namepreview_mapping_arrowpreview_conflict_reason_existing_namepreview_extract_summarypreview_failed_reason_prefix
如果实现时认为标签文本过多,也可以不引入“旧名/新名”显式标题,而仅通过层级和箭头表达映射关系,以减少视觉拥挤。
错误文案策略
当前失败项可能直接显示错误码,例如 extract_episode_not_found。在本方案中建议:
- UI 层优先转成面向用户的可读文案;
- 保留原始错误码作为
title或调试信息; - 避免在主列表里直接暴露生硬内部标识。
数据流
现有流程
file-selector-panel根据规则生成previewListpreview-panel接收itemsvirtual-preview-list渲染每个PreviewItem
方案 A 调整后
数据流保持不变,仅增强最后一步渲染:
file-selector-panel无需新增字段preview-panel无需新增协议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 是一次典型的“高感知、低侵入”优化:
- 它不解决所有预览场景问题;
- 但它能直接补足当前最明显的确认断点;
- 且几乎不需要改动执行逻辑、状态管理和数据结构。
因此本次建议按 展示层局部升级 的方式推进,先把“旧名 -> 新名”的确认能力补齐,再根据真实反馈决定是否继续向更重的审阅模型演进。