diff --git a/TODO.md b/TODO.md index 1d33686b467ac80c904e97059e1caf711ecd99fa..3573b48ec9b854d052d9782567e6af9465099f67 100644 --- a/TODO.md +++ b/TODO.md @@ -12,5 +12,5 @@ - [x] Reduce noise of tool calls (combine "command run" and "command completed", make tool calls a "box" with limited # of calls shown at a time, etc) - [ ] Insta focus input on new thread creation - [ ] Disable "streaming" (wait until whole paragraph/step finishes before showing it -- [ ] Making new thread should auto-focus input box -- [ ] Threads should be scrolled to bottom on open (they currently start near top and "scroll down" after rendering, it's jank) +- [x] Making new thread should auto-focus input box +- [x] Threads should be scrolled to bottom on open (they currently start near top and "scroll down" after rendering, it's jank) diff --git a/apps/web/src/components/ChatView.tsx b/apps/web/src/components/ChatView.tsx index 727ce8fb044b7ef2c5ff9a12dd68b0f3ebb758a4..ba027e16905883504b667850e5ecf429faffb078 100644 --- a/apps/web/src/components/ChatView.tsx +++ b/apps/web/src/components/ChatView.tsx @@ -13,6 +13,7 @@ import { type KeyboardEvent, useCallback, useEffect, + useLayoutEffect, useMemo, useRef, useState, @@ -131,6 +132,7 @@ export default function ChatView() { const [expandedWorkGroups, setExpandedWorkGroups] = useState>({}); const [nowTick, setNowTick] = useState(() => Date.now()); const [terminalFocusRequestId, setTerminalFocusRequestId] = useState(0); + const messagesScrollRef = useRef(null); const messagesEndRef = useRef(null); const textareaRef = useRef(null); const composerImagesRef = useRef([]); @@ -345,6 +347,12 @@ export default function ChatView() { // Auto-scroll on new messages const messageCount = activeThread?.messages.length ?? 0; const workLogCount = workLogEntries.length; + useLayoutEffect(() => { + if (!activeThread?.id) return; + const scrollContainer = messagesScrollRef.current; + if (!scrollContainer) return; + scrollContainer.scrollTop = scrollContainer.scrollHeight; + }, [activeThread?.id]); useEffect(() => { messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); }, [messageCount]); @@ -1014,7 +1022,7 @@ export default function ChatView() { )} {/* Messages */} -
+
{activeThread.messages.length === 0 && !isWorking ? (