authorgravatar for me@t3.ggTheo Browne <me@t3.gg> 2026-02-13 18:46:10-08:00
committergravatar for me@t3.ggTheo Browne <me@t3.gg> 2026-02-13 18:46:10-08:00
logfa3cccc3f9ec880d0054f1f4f14f0fe7880185d3
tree26af15fcfab64eb1eb374d4f72eb62b84bb641f9
parent54e7dd96f73163a46f5ee6d0db652a7c55ee1d41
signature Commit is signed but in an unrecognized format.

fix message scrolling and update todo


2 files changed, 11 insertions(+), 3 deletions(-)

TODO.md+2-2
......@@ -12,5 +12,5 @@
1212- [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)
1313- [ ] Insta focus input on new thread creation
1414- [ ] Disable "streaming" (wait until whole paragraph/step finishes before showing it
15- [ ] Making new thread should auto-focus input box
16- [ ] Threads should be scrolled to bottom on open (they currently start near top and "scroll down" after rendering, it's jank)
15- [x] Making new thread should auto-focus input box
16- [x] Threads should be scrolled to bottom on open (they currently start near top and "scroll down" after rendering, it's jank)
apps/web/src/components/ChatView.tsx+9-1
......@@ -13,6 +13,7 @@ import {
1313 type KeyboardEvent,
1414 useCallback,
1515 useEffect,
16 useLayoutEffect,
1617 useMemo,
1718 useRef,
1819 useState,
......@@ -131,6 +132,7 @@ export default function ChatView() {
131132 const [expandedWorkGroups, setExpandedWorkGroups] = useState<Record<string, boolean>>({});
132133 const [nowTick, setNowTick] = useState(() => Date.now());
133134 const [terminalFocusRequestId, setTerminalFocusRequestId] = useState(0);
135 const messagesScrollRef = useRef<HTMLDivElement>(null);
134136 const messagesEndRef = useRef<HTMLDivElement>(null);
135137 const textareaRef = useRef<HTMLTextAreaElement>(null);
136138 const composerImagesRef = useRef<ComposerImageAttachment[]>([]);
......@@ -345,6 +347,12 @@ export default function ChatView() {
345347 // Auto-scroll on new messages
346348 const messageCount = activeThread?.messages.length ?? 0;
347349 const workLogCount = workLogEntries.length;
350 useLayoutEffect(() => {
351 if (!activeThread?.id) return;
352 const scrollContainer = messagesScrollRef.current;
353 if (!scrollContainer) return;
354 scrollContainer.scrollTop = scrollContainer.scrollHeight;
355 }, [activeThread?.id]);
348356 useEffect(() => {
349357 messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
350358 }, [messageCount]);
......@@ -1014,7 +1022,7 @@ export default function ChatView() {
10141022 )}
10151023
10161024 {/* Messages */}
1017 <div className="min-h-0 flex-1 overflow-y-auto px-5 py-4">
1025 <div ref={messagesScrollRef} className="min-h-0 flex-1 overflow-y-auto px-5 py-4">
10181026 {activeThread.messages.length === 0 && !isWorking ? (
10191027 <div className="flex h-full items-center justify-center">
10201028 <p className="text-sm text-muted-foreground/30">