refactor(chat): share composer, scroll follow and jump control across both chat surfaces
The rectification session rendered its own textarea (no length ceiling, no count), its own rAF scroll follow with a sticky-scroll helper, and its own jump chip styled differently from the main chat's inline Tailwind button, while the main chat re-ran scrollTo on every streamed token and added a smooth scroll on settle. ChatComposer now accepts a controlled value so the rectification surface reuses it without touching the main draft store; useConversationScrollAnchor owns the follow through a ResizeObserver, one frame per content change, for both surfaces; a single JumpToLatestButton replaces both chips; the 720px transcript override is gone. DESIGN.md records the shared composer, the jump control, the reading width and the two shadow tokens. BUG-477 BUG-478 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
This commit is contained in:
@@ -7330,3 +7330,35 @@
|
||||
- 相关记录:BUG-474、BUG-475
|
||||
- 复发自:无
|
||||
- 修复版本:待发布
|
||||
|
||||
## BUG-477 | 生时校正会话的输入框没有字数上限,也没有接近上限的计数
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-09-01
|
||||
- 最近更新:2026-09-02
|
||||
- 影响面:`rectification-agentic-chat.tsx`、`chat-composer.tsx`
|
||||
- 用户现象:校正会话里可以无限输入;主对话在剩余 50 字时会出现计数并在到顶时变红(BUG-447),校正会话什么都没有。停止按钮、发送按钮、textarea 也是另一份手写的。
|
||||
- 触发条件:任何一次校正会话输入。
|
||||
- 根因:校正面用裸 `<Textarea>` + 两个 `<Button>` 自己拼输入框,没有 `maxLength`,也没有接 `CharacterRemaining`;`ChatComposer` 只会读主会话的 `composer-draft` 外部 store,校正面有自己的 `draft` state,所以一直没复用。
|
||||
- 修复:`ChatComposer` 新增可选受控 `value` 与 `remainingId`:有 `value` 时以其为准(store 订阅仍在组件内,不改主会话行为),校正面传 `value={draft}`,不写主会话 store。校正面渲染 `ChatComposer`(`maxLength=500`,与主对话同上限)并在 `composer-footer` 放 `CharacterRemaining`;三段 placeholder、Enter/Shift+Enter/`isComposing` 处理、停止按钮文案原样保留。
|
||||
- 验证:`composer-isolation-contract`(校正传 `value`、不 import `composer-draft`)、`character-remaining-contract`、`composer-ime-contract`、`rectification-agentic-entry`。
|
||||
- 防复发:不得再手写第二个聊天输入框;新增会话面一律渲染 `ChatComposer`,自有草稿走 `value`。
|
||||
- 相关记录:BUG-447、BUG-478
|
||||
- 复发自:无
|
||||
- 修复版本:待发布
|
||||
|
||||
## BUG-478 | 滚动跟随与「跳到最新」在两个会话面各写一份,主会话每个 token 都触发一次 scrollTo
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-09-01
|
||||
- 最近更新:2026-09-02
|
||||
- 影响面:`use-conversation-scroll-anchor.ts`、`page.tsx`、`rectification-agentic-chat.tsx`、`rectification-sticky-scroll.ts`(删除)、`globals.css`
|
||||
- 用户现象:主会话流式期间每个 token 触发一次 `scrollTo`,回答结束瞬间再补一次 smooth 滚动,看起来"先跳到底再滑一下";校正面是另一套 rAF 跟随;「跳到最新」按钮两份不同样式(主会话内联 Tailwind `shadow-md`、校正面 `--shadow-soft`,文案一个「跳到最新」一个「回到最新」)。
|
||||
- 触发条件:任意流式回答;向上翻阅历史。
|
||||
- 根因:`page.tsx` 的滚动 effect 以 `activeStreamingText` 为依赖;校正面自带 `followTailRef` / `followLatestContent` / `rectification-sticky-scroll.ts`;按钮各写各的。
|
||||
- 修复:跟随并入 `useConversationScrollAnchor`:`ResizeObserver` 观察滚动容器的子元素、`MutationObserver` 跟踪子元素增删,anchored 时下一帧 `scrollTop = scrollHeight`;`resetKey` 变化立即落底;不再在结算时补 smooth 滚动。`page.tsx` 的滚动 effect 删除;校正面接入同一 hook(`resetKey = caseId`),删除 `rectification-sticky-scroll.ts` 及其全部胶水。新增 `JumpToLatestButton`(`.jump-to-latest`,`--shadow-elevated`、44px、focus ring),两面共用,文案统一「跳到最新」带箭头;`page.tsx` 内联 Tailwind 版与 `.rectification-jump-latest` 删除。校正 `.message-list` 720px 覆写删除,与主会话同 900px。
|
||||
- 验证:`chat-notice-and-scroll-contract`(follow 在 hook 内、anchored 守卫在赋值前、`page.tsx` 无 `scrollTo`)、`chat-navigation-a11y-contract`、`chat-stream-layout`、`rectification-agentic-entry`、`rectification-answer-choice`。
|
||||
- 防复发:任何会话面不得自行监听 scroll 或按内容变化调 `scrollTo`;跟随只经 `useConversationScrollAnchor`,跳到最新只经 `JumpToLatestButton`。
|
||||
- 相关记录:BUG-477
|
||||
- 复发自:无
|
||||
- 修复版本:待发布
|
||||
|
||||
Reference in New Issue
Block a user