fix(chat): 对话区接近底部时正文突然上跳:去掉回贴区吸附并修正末端锚定口径 - #812
Open
AlphaCatMeow wants to merge 4 commits into
Open
AlphaCatMeow wants to merge 4 commits into
AlphaCatMeow wants to merge 4 commits into
Conversation
resizeItem 的 wasAtEnd 此前用 getVirtualDistanceFromEnd()(列表局部坐标)判 "在末端"。宿主在虚拟列表下方还渲染了 18px shell padding 与 194px 底部占位, 列表末端离真实 clamp 约 212px,于是脱离跟随、停在距底 220px 内的读者都被 当成"在末端",任何底部行尺寸变化都经 applyScrollAdjustment 直写 scrollTop: AskUserQuestion 卡片到达视觉位移 305px,审批请求 63px,末行流式增高 302px。 改用 getDistanceFromEnd()(DOM scrollHeight 口径,与 _willUpdate 里 followOnAppend 的 isAtEnd 一致)并加 scrollElement 判空;删除不再使用的私有 getVirtualDistanceFromEnd,types 同步并为 scrollEndThreshold 补口径说明。 测试:harness 新增 extraScrollHeight / maxScrollOffset 模拟列表下方的非虚拟 高度;end-anchor-distance 4 例覆盖带内不写、带边不写、真实 clamp 仍钉底、 默认 harness 语义不变。 Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
主转写区的 useScrollFollow 沿用默认 192px 回贴区:滚轮下行进入该区间的那一 tick 直接 pin 到底,读者看到正文突然上跳(复现页实测单 tick 231px)。改为 reattachZonePx: 0,只在真正到达底部(8px 容差)时恢复跟随;到达底部后向下 滚轮、手势落底、指针在底部释放仍会重新贴底。 工作台背景 Pane 原本手写一套贴底:距底不足 48px 即视为跟随,行数或 revision 一变就写 scrollTop,读者停在底部附近会被每次流式增量吸回,且与主 Pane、 桌面端各 Pane 的引擎语义不一致。换成同一 useScrollFollow(zone 0,会话切换 stickToBottom),ScrollArea 根与视口经 callback ref 接入,删除三处 scrollTop 写入。 新增 transcript-scroll-follow-contract 源码契约测试锁住两处配置。 Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
scroll-follow-probe.html 挂真实 ScrollArea + GatewayTranscript + useScrollFollow, 拦截 scrollTop/scrollTo 写入并按调用栈归因(follow-engine / virtualizer / base-ui),用视口顶部那一行的屏幕位移衡量肉眼可见的跳动;?zone= 试回贴区, ?ask=1|2 与 ?approval=1|2 构造挂起的询问卡片与审批请求。 scroll-follow-probe.cdp.mjs 用 Node 内建 WebSocket 直连无头 Chromium 的 CDP, 逐 tick 发滚轮事件记录每步位移与写入方;scroll-follow-probe.eval.mjs 对已 打开的页面即时求值。 Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
桌面端 ChatTranscript 的 useScrollFollow 显式传 reattachZonePx: BOTTOM_REATTACH_ZONE_PX, 滚轮下行进入距底 192px 的那一 tick 直接 pin 到底,从本分支起的开发版上仍能看到 "快到最新回复结尾时上跳一下"。与 WebUI 同口径改为 0:只在真正到达底部(8px 容差) 时恢复跟随,到达底部后向下滚轮、手势落底、指针在底部释放仍会重新贴底。 BOTTOM_REATTACH_ZONE_PX 保留:它仍是桌面端底部预留带与 WebUI spacer 的最小值, scrollFollowCore 的注释改写为现状说明。chat-transcript-scroller 契约测试新增一例 锁住零回贴区配置与预留带取值。 Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
AlphaCatMeow
marked this pull request as ready for review
September 14, 2026 14:55
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linked issue
Closes #811
Summary
WebUI 对话区在接近底部时正文会突然上跳,触发询问用户卡片或工具审批请求时更明显。三处原因,本 PR 逐一处理:
reattachZonePx: 0,只在真正到达底部时恢复跟随;到达底部后向下滚轮、手势落底、指针在底部释放三条路径仍会重新贴底。virtual-core的wasAtEnd用列表局部距离判"在末端",不含转写 shell 的 18px 顶部 padding 与 194px 底部占位,于是距真实 clamp 约 220px 内都算"在末端",脱离跟随的读者会被任何底部行增高拖走(询问卡片到达 305px、审批请求 63px、流式增高 302px)。改为按 DOM 的getDistanceFromEnd()判定,与followOnAppend已用的口径一致;两端共用该 fork,桌面端同样受益。Change scope
crates/agent-gateway/web/src/app/GatewayApp.tsxcrates/agent-gateway/web/src/app/workbench/GatewayConversationPaneHost.tsxcrates/agent-gui/src/pages/chat/transcript/ChatTranscript.tsx、crates/agent-ui/src/lib/chat-scroll/scrollFollowCore.ts(注释)crates/virtual-core/src/index.ts、crates/virtual-core/types/index.d.tscrates/virtual-core/test/end-anchor-distance.test.mjs(harness 新增extraScrollHeight/maxScrollOffset)、crates/agent-gateway/web/test/transcript-scroll-follow-contract.test.mjs、crates/agent-gui/test/chat/chat-transcript-scroller.test.mjs(新增 1 例)crates/agent-gateway/web/test/browser/scroll-follow-probe.{html,cdp.mjs,eval.mjs}Screenshots / preview
复现页测得的视觉位移(px,负值为内容上移;无头 Chromium,关闭平滑滚动,合成对话):
Verification
pnpm typecheck:virtual-core、pnpm test:virtual-core:27/27 通过(含新增 4 例)crates/agent-gateway/web:tsc --noEmit通过;pnpm test:webui720/720 通过;改动文件biome check通过crates/agent-gui:tsc --noEmit通过;chat-transcript-scroller、scroll-follow-core、use-scroll-follow-native-scrollbar、thinking-disclosure44/44 通过;改动文件biome check通过pnpm exec vite --port 5173+msedge --headless=new --remote-debugging-port=9333,node test/browser/scroll-follow-probe.cdp.mjs all|arrive|approve|ask(URL 加?zone=0、?ask=2、?approval=2)check:ui-boundaries在基线上已有 3 处与本 PR 无关的报错Depends-On: none
Stack-Root: #812
Pre-submit checklist