From 2c9870419851543c41b3faf2fe6e9c65d73c79a5 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:17:30 +0100 Subject: [PATCH] fix: chat scroll-to-bottom on channel open and bottom spacing Consolidated two competing scroll effects into one to fix an effect ordering bug where prevMessagesLength was updated before the initial scroll check could read it. Channel switch now resets tracking state so the snap-to-bottom fires reliably via requestAnimationFrame. Increased message list bottom padding to clear the glass input bubble. --- .../web/src/components/chat/MessageList.tsx | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/packages/web/src/components/chat/MessageList.tsx b/packages/web/src/components/chat/MessageList.tsx index 5e5bf58e..79b7ac95 100644 --- a/packages/web/src/components/chat/MessageList.tsx +++ b/packages/web/src/components/chat/MessageList.tsx @@ -64,21 +64,33 @@ export function MessageList({ channelId }: MessageListProps) { return () => clearTimeout(ackTimerRef.current); }, [channelId, messages.length, isNearBottom, ackChannel]); - // Auto-scroll to bottom on new messages (if near bottom) + // Reset scroll tracking on channel switch so initial-load scroll fires useEffect(() => { - if (messages.length > prevMessagesLength.current && isNearBottom) { + prevMessagesLength.current = 0; + setIsNearBottom(true); + }, [channelId]); + + // Handle scrolling: initial load snaps to bottom, new messages smooth-scroll if near bottom + useEffect(() => { + const prev = prevMessagesLength.current; + prevMessagesLength.current = messages.length; + + if (messages.length === 0) return; + + if (prev === 0) { + // Initial load / channel switch — snap to bottom + requestAnimationFrame(() => { + const container = containerRef.current; + if (container) { + container.scrollTop = container.scrollHeight; + } + }); + } else if (messages.length > prev && isNearBottom) { + // New messages arrived while near bottom — smooth scroll bottomRef.current?.scrollIntoView({ behavior: 'smooth' }); } - prevMessagesLength.current = messages.length; }, [messages.length, isNearBottom]); - // Scroll to bottom on initial load - useEffect(() => { - if (messages.length > 0 && prevMessagesLength.current === 0) { - bottomRef.current?.scrollIntoView(); - } - }, [messages.length]); - const handleScroll = useCallback(async () => { const container = containerRef.current; if (!container) return; @@ -124,7 +136,7 @@ export function MessageList({ channelId }: MessageListProps) { {!hasMore && } -
+
{messages.map((msg, i) => { const prevMsg = messages[i - 1]; const showDate = shouldShowDateDivider(prevMsg, msg);