mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix(site): update sticky messages during streaming (#23577)
## Problem The sticky user message visual state (`--clip-h`, fade gradient, push-up positioning) is driven by an `update()` function that only ran on `scroll` events. The chat scroll container uses `flex-col-reverse`, where `scrollTop = 0` means "at bottom." When streaming content grows the transcript while the user is auto-scrolled to the bottom, `scrollTop` stays at `0` — no `scroll` event fires — so `update()` never runs and the sticky messages become visually stale until the user manually scrolls. ## Fix Add a `ResizeObserver` on the scroller's content wrapper inside the existing `useLayoutEffect` that sets up the scroll/resize listeners. When the content wrapper resizes (streaming growth), it fires the observer which calls `update()` through the same RAF-throttle pattern used by the scroll handler. Single observer per sticky message instance. Zero cost when nothing is resizing. Cleanup handled in the same effect teardown.
This commit is contained in:
@@ -856,6 +856,24 @@ const StickyUserMessage: FC<{
|
||||
});
|
||||
};
|
||||
|
||||
// Re-run the visual update when the scrollable content height
|
||||
// changes (e.g. streaming responses growing the transcript).
|
||||
// In flex-col-reverse, scrollTop stays at 0 when pinned to
|
||||
// bottom so no scroll event fires — but the content wrapper
|
||||
// resizes and this observer catches that.
|
||||
const contentEl = scroller.firstElementChild as HTMLElement | null;
|
||||
let contentRafId: number | null = null;
|
||||
const contentObserver = contentEl
|
||||
? new ResizeObserver(() => {
|
||||
if (contentRafId !== null) return;
|
||||
contentRafId = requestAnimationFrame(() => {
|
||||
contentRafId = null;
|
||||
update();
|
||||
});
|
||||
})
|
||||
: null;
|
||||
contentObserver?.observe(contentEl!);
|
||||
|
||||
scroller.addEventListener("scroll", onScroll, { passive: true });
|
||||
window.addEventListener("resize", onResize);
|
||||
update();
|
||||
@@ -866,8 +884,10 @@ const StickyUserMessage: FC<{
|
||||
return () => {
|
||||
scroller.removeEventListener("scroll", onScroll);
|
||||
window.removeEventListener("resize", onResize);
|
||||
contentObserver?.disconnect();
|
||||
container.style.removeProperty("--overlay-ready");
|
||||
if (rafId !== null) cancelAnimationFrame(rafId);
|
||||
if (contentRafId !== null) cancelAnimationFrame(contentRafId);
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user