Files
ttstd-infinite-canvas/docs/plans/home-chat-optimization-plan.mdx

100 lines
11 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 首页对话区优化计划(BoardUI 参照自研)
> 状态:已确认执行顺序(2026-09-06)——Phase A 先行、随后 Phase B;代码高亮启用 `@streamdown/code`
> 关联:`docs/plans/boardui-absorption-plan.mdx`(图标/工具栏/空态已完成并落版)、`docs/plans/ui-kit-rollout-plan.mdx`
> 范围文件:`web/src/pages/create/index.tsx`(1897 行)、`web/src/styles/globals.css`(15940 行)、`web/src/components/ai/ai-message-markdown.tsx`
## 1. 背景与目标
首页(`/` = 创作页)对话区仍有多处可优化,用户点名两大方向,缺一不可:
1. **历史会话弹窗**:按钮入口 → 弹层内容 → 列表项 → 行内操作,整体打磨。
2. **消息正文富内容**:AI 回复中渲染的文本、**代码块、表格、图片**等内容形态的呈现质量。
工作方式:以 BoardUI 仓库(`../boardui`)为视觉与交互参照**自研**落地;自研过程中如发现本站代码不合理(硬编码、重复、缺无障碍、结构性膨胀),同步改进——但不引入 BoardUI 的运行时依赖(无 `react-aria-components`、无 `motion`,沿用 AntD + Tailwind + 自研 token)。
### 调研结论速览
**BoardUI 侧**(`components/application/agent-chat/*`):
- 对话外壳为「右侧会话 rail + 主消息区 + 底部输入条」三段式卡片(rail 260px 卡片、主区 `rounded-3xl bg-secondary`、输入条同宽贴底)。
- 会话 rail 交互最值得吸收:行 hover 与选中同底色(hover 即预览选中);行尾时间徽标 hover 时淡出让位给「⋯」菜单(190px 浮层:重命名/标未读/删除,删除项红色);**行内重命名**(自聚焦全选、Enter 提交、Esc 还原、blur 提交);未读蓝点 6px;新建会话置顶按钮行;分组小标。
- 消息行操作簇:hover 显露、`focus-within` 保留、流式中禁用隐藏(28px 圆形、`rounded-md`、tertiary 图标色、hover 底色)。
- 用户消息为右侧气泡:`max-w-[75%] rounded-2xl px-3 py-[11px] bg-background-primary shadow-card`;assistant 通栏无气泡,与消息簇同宽(`max-w-3xl`)排版。
- 输入条为 52px 胶囊 + 36px 圆形控制钮;发送中变「停止」;下方一条 26px 状态行如实显示 provider/消息数。
- 空态:标题 + 次级说明 + 胶囊建议钮;首 token 到达前以「思考中」占位。
- **注意**:BoardUI 的 agent-chat 是纯文本 starter,全库无 markdown/代码块/表格/图片渲染组件(已 grep 证实:无 react-markdown/shiki/prism/`language-` 类)。故**富内容方向以本站自研管线为主干**,BoardUI 仅提供容器语汇(chip/复制钮/滚动容器/间距节奏)。
**本站侧现状**(引用为现状快照,实施前以最新行号为准):
- 消息渲染:assistant 消息头含镜头徽标/模式/模型/时间/状态与「生成同款」,推理过程可折叠(`MessageReasoning`),正文经 `AIMessageMarkdown`(`web/src/components/ai/ai-message-markdown.tsx`,streamdown 流式渲染,`parseIncompleteMarkdown`,逐词淡入)。
- 富内容现状(样式见 `globals.css` 15206–15297):
- 代码块:仅有衬底 pre(`rounded r-sm`、`foreground 7%` 底),**无语言标签条、无复制按钮、无行号**(`lineNumbers={false}`)、无语法高亮。依赖 `@streamdown/code@1.1.1` 已安装但**从未被 import**(沉睡资产,即流式高亮的官方配套)。
- 表格:滚动容器 + 单元格仅下边框 + 表头 5% 底,较朴素;无边框网格/斑马纹/圆角容器。
- 图片:markdown 内 `![...]` 无自定义渲染(无圆角/尺寸约束/点击预览);会话内生成结果以媒体卡片网格呈现并有预览 Modal(含缩放拖拽),此路已通。
- 引用/列表/分割线/行内代码:已有 token 化样式(`color-mix(in srgb, currentColor …)` 自适应明暗)。
- 历史弹窗现状(`index.tsx` `CreationHistoryDrawer` 段):AntD Drawer;含标题计数、搜索框、新建会话卡、时间桶分组(今天/昨天/近 7 天/更早)、行=整行按钮 + 直接删除按钮 + 模式 tag + 摘要截断、空态、`aria-current`。已不粗糙,但与 BoardUI rail 相比缺少:**hover 菜单(重命名/删除并入)、行内重命名、未读标记、时间徽标让位动画、行间 hover 反馈一致性**;「删除」为单点直达按钮存在误删风险(删除虽走确认流程)。
- 输入条:已完成 R2 幽灵按钮统一(32px 透明按钮族),与消息区为同一 820 居中列。
## 2. 待优化清单(分阶段)
### Phase A — 历史会话弹窗升级(借鉴 BoardUI rail 交互)
目标:让「历史」弹窗的列表行达到与 BoardUI rail 同级的信息密度与操作安全度,并补齐行内编辑。
- [ ] A1 行操作重构:删除从「常驻小按钮」改为 hover「⋯」菜单(菜单项:重命名 / 删除[红]);hover 态即选中预览底色;键盘可达(按钮 `aria-expanded`、菜单 Esc 关闭、焦点回退触发器)。
- [ ] A2 行内重命名:行标题双击或菜单「重命名」进入编辑态——输入自聚焦全选,Enter 提交 / Esc 还原 / blur 提交;提交走既有改名逻辑并乐观更新。
- [ ] A3 时间徽标:展示相对时间(刚刚/n 分钟/n 小时/n 天前),hover 行时让位给操作菜单(淡出/淡入,`prefers-reduced-motion` 下直接切换)。
- [ ] A4 行信息补全与排版:摘要截断行 + 消息数/时间粒度统一;选中态、hover 态、焦点环与页面其他按钮族同源(沿用 R2 幽灵钮规范)。
- [ ] A5 空态与加载态核对:无历史时按钮/面板空态文案与插图风格对齐首页空态;打开时骨架或已有加载态统一。
- [ ] A6 删除确认保留既有确认流;确认框按钮规格对齐全局。
验收:悬停/键盘可完成重命名与删除;重命名即时生效;删除需确认;明暗两主题下 hover/选中/焦点可辨;`bunx tsc --noEmit` 通过;提交后浏览器人工验收。
### Phase B — 消息正文富内容打磨(文本/代码块/表格/图片)
目标:AI 回复中的结构化内容达到「可读、可复制、可引用、好看」的水准。以 `AIMessageMarkdown` 的 components 映射为单一扩展点,不另起渲染体系。
- [ ] B1 代码块外壳:语言标签条(语言名取自 `className="language-*"`,未知语言不显示或显 `code`)+ 复制按钮(`aria-label`、成功态反馈)+ 统一圆角/边框/底色 token;横向滚动保留;顶部标签条在流式渲染中稳定不跳动。
- [ ] B2 代码高亮:评估启用 `@streamdown/code`(流式友好,已装未用)。决策点见 §4。若启用需处理:未知语言降级、流式增量着色节流、深色主题 token 化(不引入散落色值)。
- [ ] B3 行号(可选):streamdown 已支持 `lineNumbers`(当前显式关闭)。默认关闭(对话场景非编辑器),提供设置/偏好开关的可行性标注即可,不强推。
- [ ] B4 表格增强:网格边框(弱化)+ 表头底色 + hover 行、粘性表头容器?——对话表格通常短小,做「圆角容器 + 细网格 + 表头 5–8% 底」即可,不引入复杂表格库;列多时滚动容器保留并补滚动提示(可选)。
- [ ] B5 行内图片:markdown `![alt](url)` 渲染为受限尺寸圆角卡片(`max-height` 约束、`object-fit: cover/contain` 由比例定)、点击进入既有预览 Modal(复用生成结果预览组件);加载失败占位(alt 文案 + 破损图标);懒加载。流式期间图片未收尾时的处理与正文一致(不闪跳)。
- [ ] B6 消息级操作簇(如可行且不喧宾夺主):assistant 消息 hover 出现「复制全文/朗读(如已有能力)」等,参照 BoardUI 显示规则(hover 显露、focus-within 保留、流式隐藏);与现有消息头操作区不重复。
- [ ] B7 渲染一致性小修:标题层级字号用 em 但整体应随正文 1em 缩放核验;行内代码与代码块在流式未闭合时的处理(streamdown 已处理,人工验收确认);引用块与代码块间距节奏(`0.8em` 段落间距)核对。
验收:向模型提问触发含代码块/表格/列表/引用内容,肉眼核对明暗主题;代码块复制可用且键盘可达;图片点击预览;流式中无布局跳动;`tsc` 通过;浏览器人工验收。
### Phase C — 代码质量改进(自研中发现的不合理点)
伴随 A/B 落地顺手治理,不单独立项大改:
- [ ] C1 消息正文样式(15206–15297)与代码块新样式统一收口到创作页样式节或提升为共享组件类;新组件(代码块/图片/历史行菜单)优先页面级组件,出现第二处使用时再提升(遵循 AGENTS.md 组件归属规则)。
- [ ] C2 清理内联字面样式(如 `index.tsx` 内 `style={{display:"inline-flex",gap:8}}` 之类散落写法)→ 具名 CSS 类;磁贴/图标尺寸继续走 R3 统一族。
- [ ] C3 时间格式化工具核对:消息时间/会话分组时间/相对时间若存在多套近似实现,合并为一处(验证引用后再删,不臆测)。
- [ ] C4 无障碍核对(随 A/B 每项必查):新增按钮均有 `aria-label`/`aria-expanded`、焦点环、Esc/Enter 语义;`prefers-reduced-motion` 下逐词淡入与让位动画降级为直接切换(若 streamdown 动画类无降级则补 CSS)。
- [ ] C5 `index.tsx` 1897 行:本轮**不拆文件**(页面私有组件合法),但 A/B 新增块保持独立组件定义清晰;若后续页面文件再涨且出现跨页复用再议拆分。
## 3. BoardUI 关键规格速查(实施时对照)
| 能力 | BoardUI 配方 | 本站落点建议 |
| --- | --- | --- |
| rail 行圆角/hover | `rounded-2lg`,hover 与选中同 fill | 历史行 `--r-md`~`--r-lg` 家族,hover 即预览选中 |
| 未读点 | 6px `bg-button-primary` | 会话级未读(如可用 data 支持)否则标注「数据不支持」 |
| 行菜单 | 190px、`p-2`、删除 `text-text-error-primary` | 自制浮层或 AntD Dropdown 定制样式 |
| 时间徽标让位 | 相对时间 hover 淡出让位菜单 | CSS transition + reduced-motion 降级 |
| 用户气泡 | `max-w-[75%] px-3 py-[11px] rounded-2xl` | 已右对齐气泡,核对圆角/内边距/阴影一致性 |
| 消息 hover 操作 | 28px `rounded-md`、流式禁用隐藏 | 消息头已有操作区,评估是否需要消息尾簇 |
| 输入条 | 52px 胶囊 + 36px 圆钮 + 26px 状态行 | 现有 820 幽灵钮族已统一,仅核对与消息区衔接 |
| 空态 | 标题/说明/胶囊建议钮、思考占位 | 已对齐(R2/R3),微调即可 |
## 4. 已确认决策
1. **执行顺序**:Phase A(历史弹窗)先行,随后 Phase B(富内容)——用户已确认(2026-09-06)。
2. **代码高亮方案**:启用 `@streamdown/code`(官方流式配套、已装零新增依赖)——用户已确认(2026-09-06)。实施时:未知语言降级为无高亮;增量着色节流;颜色走主题 token。
3. 行号默认关闭、图片预览复用既有 Modal——按正文推荐默认执行,无异议。
## 5. 落地纪律
- 每个 Phase 独立提交(`feat/fix/refactor` 前缀按仓库规范),提交前 `bunx tsc --noEmit`,改动后同步 `docs/content/docs/progress/pending-test.mdx` 验收段落(含本次删除任务通知已记录的条目)。
- 所有改动保持工作树干净;本计划文档随首轮实施一并提交。
- BoardUI 只读参照;若其视觉与本站 token(明暗自适应)冲突,以本站 token 体系为准。