Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
30 lines
2.4 KiB
Markdown
30 lines
2.4 KiB
Markdown
# TASK · 滚动锚两处老问题:直接打开会话时监听未挂上 + 校正长回答被拉到底(2026-09-26)
|
||
|
||
## 基线
|
||
|
||
- BUG-1042 修复单(`080ea5ca`,按钮间距)合入后的 `origin/staging`。分支 `codex/scroll-anchor-hook-fixes-20260926`。
|
||
- 只改 `frontend/src/hooks/use-conversation-scroll-anchor.ts` 与其调用处;与 `TASK-rectification-dup-question-20260926` 不交叉,可并行。
|
||
|
||
## 事故实证(BUG-1042 执行方用 CDP 实测发现)
|
||
|
||
- **BUG-1043(普通咨询)**:页面直接打开一个已有消息的会话(刷新、`?c=` 深链、启动落到最近会话)时,hook 的 scroll 监听与 `ResizeObserver` 从未挂上(插桩计数 0)。表现:短回答也显示「跳到最新」,滚动不更新它,点了也不跟随。先开 `/?new=1` 再点进同一会话则正常。疑似原因:加载屏期间容器为 null,effect 提前返回;揭幕后 `active` / `resetKey` 未变,effect 不重跑。
|
||
- **BUG-1044(生时校正长回答)**:钉顶后视口距底部 94 px,落在 hook 的 96 px「已回到底部」阈值内,`measure()` 把它当作读者回到底部 → 释放 `holdUnpin`、`anchored = true` → 长回答被拉到底。普通咨询停在约 198 px,不受影响。改前改后行为一致(非 BUG-1042 引入)。
|
||
|
||
## 决策记录
|
||
|
||
- D1 BUG-1043:监听挂载必须在滚动容器真正出现后发生(容器 ref 变化时重新挂载,或以 callback ref 驱动),不依赖 `active` / `resetKey` 变化。
|
||
- D2 BUG-1044:钉顶后在用户**主动**滚动之前,不得因"距底部小于阈值"自动恢复贴底;判断"回到底部"必须来自用户滚动事件,而不是钉顶 / 留白造成的几何位置。
|
||
- D3 BUG-930 / 931 / 932 / 1042 的全部行为与测试不得弱化。
|
||
|
||
## 硬红线
|
||
|
||
1. 真实 React 生命周期测试:以"加载屏 → 揭幕"的方式挂载已有消息的会话,断言监听已挂上、短回答不显示「跳到最新」;校正面长回答钉顶后不被拉到底,用户手动滚到底后恢复跟随。
|
||
2. 真实浏览器(CDP 假数据)复测两个场景并截图。
|
||
3. 全量测试与基线逐条一致、新增 0;改动断言三栏;更新 DESIGN 对应说明。
|
||
|
||
## 任务分解
|
||
|
||
- T1 BUG-1043(D1)+ 测试。
|
||
- T2 BUG-1044(D2)+ 测试。
|
||
- T3 记录:更新 BUG-1043 / 1044(BUG-1042 单已建号,状态 investigating → 修复后按部署结果改);PROGRESS;`docs/testing/` 清单。
|