Files
Jyotisha/docs/tasks/TASK-scroll-anchor-hook-fixes-20260926.md
T

30 lines
2.4 KiB
Markdown
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.
# 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/` 清单。