diff --git a/src/components/ChatBody.tsx b/src/components/ChatBody.tsx index e3a6bb6..3d3d9b6 100644 --- a/src/components/ChatBody.tsx +++ b/src/components/ChatBody.tsx @@ -1,5 +1,5 @@ import React, { useRef, useState, useEffect, useCallback, useMemo, Fragment } from 'react'; -import { ChevronDown } from 'lucide-react'; +import { ArrowDownToLine } from 'lucide-react'; import type { ChatMessage, ToolStatus } from '../hooks/useChat'; import { MessageBubble } from './MessageBubble'; import { ToolCallCard } from './ToolCallCard'; @@ -65,10 +65,19 @@ export function ChatBody({ const scrollRef = scrollContainerRef || internalRef; const [userScrolled, setUserScrolled] = useState(false); - const scrollToBottom = useCallback(() => { + const isAutoScrolling = useRef(false); + + const scrollToBottom = useCallback((smooth = false) => { requestAnimationFrame(() => { const el = scrollRef.current; - if (el) el.scrollTop = el.scrollHeight; + if (!el) return; + if (smooth) { + isAutoScrolling.current = true; + el.scrollTo({ top: el.scrollHeight, behavior: 'smooth' }); + setTimeout(() => { isAutoScrolling.current = false; }, 800); + } else { + el.scrollTop = el.scrollHeight; + } }); }, [scrollRef]); @@ -80,6 +89,7 @@ export function ChatBody({ }, [messages, streaming, userScrolled, scrollToBottom]); function handleScroll() { + if (isAutoScrolling.current) return; const el = scrollRef.current; if (!el) return; const scrolled = el.scrollHeight - el.scrollTop - el.clientHeight >= 100; @@ -168,7 +178,7 @@ export function ChatBody({ return (