From 7d69229cd76447b92ee66f472f760994d00817ae Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Sat, 07 Mar 2026 14:14:56 +0100
Subject: [PATCH] fix: reliable scroll-to-bottom, keyboard-aware project picker

---
 components/chat/MessageList.tsx |   21 ++++++++++++++-------
 1 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/components/chat/MessageList.tsx b/components/chat/MessageList.tsx
index 5ff7aea..c3eb13e 100644
--- a/components/chat/MessageList.tsx
+++ b/components/chat/MessageList.tsx
@@ -18,17 +18,17 @@
   // Track the last message's content so transcript reflections trigger a scroll
   const lastContent = messages.length > 0 ? messages[messages.length - 1].content : "";
 
+  // Flag: when true, every content size change triggers a scroll to bottom.
+  // Used for bulk loads (restart, session switch) where FlatList renders lazily.
+  const bulkScrollRef = useRef(false);
+
   useEffect(() => {
     if (messages.length > 0) {
       const delta = Math.abs(messages.length - prevLengthRef.current);
       if (delta > 1) {
-        // Bulk load (restart, session switch) — FlatList renders lazily,
-        // so fire multiple scroll attempts to catch late renders.
-        for (const delay of [100, 300, 700]) {
-          setTimeout(() => {
-            listRef.current?.scrollToEnd({ animated: false });
-          }, delay);
-        }
+        // Bulk load — let onContentSizeChange handle scrolling
+        bulkScrollRef.current = true;
+        setTimeout(() => { bulkScrollRef.current = false; }, 3000);
       } else {
         // Single new message — smooth scroll
         setTimeout(() => {
@@ -38,6 +38,12 @@
     }
     prevLengthRef.current = messages.length;
   }, [messages.length, isTyping, lastContent]);
+
+  const handleContentSizeChange = useCallback(() => {
+    if (bulkScrollRef.current) {
+      listRef.current?.scrollToEnd({ animated: false });
+    }
+  }, []);
 
   // Play from a voice message and auto-chain all consecutive assistant voice messages after it
   const handlePlayVoice = useCallback(async (messageId: string) => {
@@ -77,6 +83,7 @@
           onPlayVoice={handlePlayVoice}
         />
       )}
+      onContentSizeChange={handleContentSizeChange}
       contentContainerStyle={{ paddingVertical: 12 }}
       showsVerticalScrollIndicator={false}
       ListFooterComponent={

--
Gitblit v1.3.1