@@ -465,26 +465,6 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
465465 }
466466 } , [ ] )
467467
468- useEffect ( ( ) => {
469- const prev = prevExpandedRowsRef . current
470- let wasAnyRowExpandedByUser = false
471- if ( prev ) {
472- // Check if any row transitioned from false/undefined to true
473- for ( const [ tsKey , isExpanded ] of Object . entries ( expandedRows ) ) {
474- const ts = Number ( tsKey )
475- if ( isExpanded && ! ( prev [ ts ] ?? false ) ) {
476- wasAnyRowExpandedByUser = true
477- break
478- }
479- }
480- }
481-
482- if ( wasAnyRowExpandedByUser ) {
483- disableAutoScrollRef . current = true
484- }
485- prevExpandedRowsRef . current = expandedRows // Store current state for next comparison
486- } , [ expandedRows ] )
487-
488468 const isStreaming = useMemo ( ( ) => {
489469 // Checking clineAsk isn't enough since messages effect may be called
490470 // again for a tool for example, set clineAsk to its value, and if the
@@ -529,6 +509,27 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
529509 return false
530510 } , [ modifiedMessages , clineAsk , enableButtons , primaryButtonText ] )
531511
512+ useEffect ( ( ) => {
513+ const prev = prevExpandedRowsRef . current
514+ let wasAnyRowExpandedByUser = false
515+ if ( prev ) {
516+ // Check if any row transitioned from false/undefined to true
517+ for ( const [ tsKey , isExpanded ] of Object . entries ( expandedRows ) ) {
518+ const ts = Number ( tsKey )
519+ if ( isExpanded && ! ( prev [ ts ] ?? false ) ) {
520+ wasAnyRowExpandedByUser = true
521+ break
522+ }
523+ }
524+ }
525+
526+ // Don't disable auto-scroll during streaming even if rows are expanded
527+ if ( wasAnyRowExpandedByUser && ! isStreaming ) {
528+ disableAutoScrollRef . current = true
529+ }
530+ prevExpandedRowsRef . current = expandedRows // Store current state for next comparison
531+ } , [ expandedRows , isStreaming ] )
532+
532533 const markFollowUpAsAnswered = useCallback ( ( ) => {
533534 const lastFollowUpMessage = messagesRef . current . findLast ( ( msg : ClineMessage ) => msg . ask === "followup" )
534535 if ( lastFollowUpMessage ) {
@@ -1390,26 +1391,32 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
13901391
13911392 useEffect ( ( ) => {
13921393 let timer : ReturnType < typeof setTimeout > | undefined
1393- if ( ! disableAutoScrollRef . current ) {
1394+ // Always scroll to bottom during streaming unless user explicitly scrolled up
1395+ if ( ! disableAutoScrollRef . current || isStreaming ) {
13941396 timer = setTimeout ( ( ) => scrollToBottomSmooth ( ) , 50 )
13951397 }
13961398 return ( ) => {
13971399 if ( timer ) {
13981400 clearTimeout ( timer )
13991401 }
14001402 }
1401- } , [ groupedMessages . length , scrollToBottomSmooth ] )
1403+ } , [ groupedMessages . length , scrollToBottomSmooth , isStreaming ] )
14021404
1403- const handleWheel = useCallback ( ( event : Event ) => {
1404- const wheelEvent = event as WheelEvent
1405+ const handleWheel = useCallback (
1406+ ( event : Event ) => {
1407+ const wheelEvent = event as WheelEvent
14051408
1406- if ( wheelEvent . deltaY && wheelEvent . deltaY < 0 ) {
1407- if ( scrollContainerRef . current ?. contains ( wheelEvent . target as Node ) ) {
1408- // User scrolled up
1409- disableAutoScrollRef . current = true
1409+ if ( wheelEvent . deltaY && wheelEvent . deltaY < 0 ) {
1410+ if ( scrollContainerRef . current ?. contains ( wheelEvent . target as Node ) ) {
1411+ // User scrolled up - but don't disable during streaming if we're near bottom
1412+ if ( ! isStreaming || ! isAtBottom ) {
1413+ disableAutoScrollRef . current = true
1414+ }
1415+ }
14101416 }
1411- }
1412- } , [ ] )
1417+ } ,
1418+ [ isStreaming , isAtBottom ] ,
1419+ )
14131420
14141421 useEvent ( "wheel" , handleWheel , window , { passive : true } ) // passive improves scrolling performance
14151422
@@ -1878,6 +1885,10 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
18781885 if ( isAtBottom ) {
18791886 disableAutoScrollRef . current = false
18801887 }
1888+ // During streaming, always keep auto-scroll enabled unless user explicitly scrolled
1889+ if ( isStreaming && isAtBottom ) {
1890+ disableAutoScrollRef . current = false
1891+ }
18811892 setShowScrollToBottom ( disableAutoScrollRef . current && ! isAtBottom )
18821893 } }
18831894 atBottomThreshold = { 10 }
0 commit comments