mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix(site/src/pages/AgentsPage): fix scroll-to-bottom pin starvation in agents chat (#23778)
scheduleBottomPin() cancelled any in-flight pin and restarted the double-RAF chain on every ResizeObserver notification. When content height changes on consecutive frames (e.g. during streaming where SmoothText reveals characters each frame and markdown re-rendering occasionally changes block height), the inner RAF that actually sets scrollTop is perpetually cancelled before it fires. The scroll falls behind the growing content. Two fixes: 1. Make scheduleBottomPin() idempotent: if a pin is already in-flight, skip. The inner RAF reads scrollHeight at execution time so it always targets the latest bottom. User-interrupt paths (wheel, touch) still cancel via cancelPendingPins(). 2. Add overscroll-behavior:contain to the scroll container. Prevents elastic overscroll from generating extra scroll events that could flip autoScrollRef to false.
This commit is contained in:
@@ -792,7 +792,16 @@ const ScrollAnchoredContainer: FC<{
|
||||
};
|
||||
|
||||
const scheduleBottomPin = () => {
|
||||
cancelPendingPins();
|
||||
// If a pin is already in-flight, let it complete. The
|
||||
// inner RAF reads scrollHeight at execution time so it
|
||||
// always targets the latest bottom. Cancelling and
|
||||
// rescheduling on every ResizeObserver notification
|
||||
// starves the pin on Safari, where sticky-element
|
||||
// repositioning generates extra resize events that
|
||||
// perpetually restart the double-RAF chain.
|
||||
if (pinOuterRafId !== null || pinInnerRafId !== null) {
|
||||
return;
|
||||
}
|
||||
pendingWheelPinRef.current = false;
|
||||
isRestoringScrollRef.current = true;
|
||||
// Double-RAF lets React's commit phase and the browser's
|
||||
@@ -1149,7 +1158,7 @@ const ScrollAnchoredContainer: FC<{
|
||||
<div
|
||||
ref={scrollContainerRef}
|
||||
data-testid="scroll-container"
|
||||
className="flex min-h-0 flex-1 flex-col overflow-y-auto [overflow-anchor:none] [scrollbar-gutter:stable] [scrollbar-width:thin] [scrollbar-color:hsl(var(--surface-quaternary))_transparent]"
|
||||
className="flex min-h-0 flex-1 flex-col overflow-y-auto [overflow-anchor:none] [overscroll-behavior:contain] [scrollbar-gutter:stable] [scrollbar-width:thin] [scrollbar-color:hsl(var(--surface-quaternary))_transparent]"
|
||||
>
|
||||
<div ref={contentRef}>
|
||||
{hasMoreMessages && (
|
||||
|
||||
Reference in New Issue
Block a user