镜像自地址
https://github.com/lhly/cloud-drive-renamer.git
已同步 2026-10-21 06:01:51 +08:00
245 行
9.2 KiB
Markdown
245 行
9.2 KiB
Markdown
# 预览面板 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 是一次典型的“高感知、低侵入”优化:
|
||
|
||
- 它不解决所有预览场景问题;
|
||
- 但它能直接补足当前最明显的确认断点;
|
||
- 且几乎不需要改动执行逻辑、状态管理和数据结构。
|
||
|
||
因此本次建议按 **展示层局部升级** 的方式推进,先把“旧名 -> 新名”的确认能力补齐,再根据真实反馈决定是否继续向更重的审阅模型演进。
|