1- import { useEffect , useMemo , useRef , useState } from 'react'
1+ import { useCallback , useEffect , useMemo , useRef , useState } from 'react'
22import { useAppState } from './useAppState'
33import { useMessages } from './useMessages'
44import { useShallow } from 'zustand/react/shallow'
@@ -25,16 +25,16 @@ export const useThreadScrolling = (
2525
2626 const showScrollToBottomBtn = ! isAtBottom && hasScrollbar
2727
28- const scrollToBottom = ( smooth = false ) => {
28+ const scrollToBottom = useCallback ( ( smooth = false ) => {
2929 if ( scrollContainerRef . current ) {
3030 scrollContainerRef . current . scrollTo ( {
3131 top : scrollContainerRef . current . scrollHeight ,
3232 ...( smooth ? { behavior : 'smooth' } : { } ) ,
3333 } )
3434 }
35- }
35+ } , [ ] )
3636
37- const handleScroll = ( e : Event ) => {
37+ const handleScroll = useCallback ( ( e : Event ) => {
3838 const target = e . target as HTMLDivElement
3939 const { scrollTop, scrollHeight, clientHeight } = target
4040 // Use a small tolerance to better detect when we're at the bottom
@@ -53,17 +53,18 @@ export const useThreadScrolling = (
5353 setIsAtBottom ( isBottom )
5454 setHasScrollbar ( hasScroll )
5555 lastScrollTopRef . current = scrollTop
56- }
56+ } , [ streamingContent ] )
5757
5858 useEffect ( ( ) => {
59- if ( scrollContainerRef . current ) {
60- scrollContainerRef . current . addEventListener ( 'scroll' , handleScroll )
59+ const scrollContainer = scrollContainerRef . current
60+ if ( scrollContainer ) {
61+ scrollContainer . addEventListener ( 'scroll' , handleScroll )
6162 return ( ) =>
62- scrollContainerRef . current ? .removeEventListener ( 'scroll' , handleScroll )
63+ scrollContainer . removeEventListener ( 'scroll' , handleScroll )
6364 }
64- } , [ scrollContainerRef ] )
65+ } , [ handleScroll ] )
6566
66- const checkScrollState = ( ) => {
67+ const checkScrollState = useCallback ( ( ) => {
6768 const scrollContainer = scrollContainerRef . current
6869 if ( ! scrollContainer ) return
6970
@@ -73,7 +74,7 @@ export const useThreadScrolling = (
7374
7475 setIsAtBottom ( isBottom )
7576 setHasScrollbar ( hasScroll )
76- }
77+ } , [ ] )
7778
7879 // Single useEffect for all auto-scrolling logic
7980 useEffect ( ( ) => {
@@ -120,7 +121,7 @@ export const useThreadScrolling = (
120121 const interval = setInterval ( checkScrollState , 100 )
121122 return ( ) => clearInterval ( interval )
122123 }
123- } , [ streamingContent ] )
124+ } , [ streamingContent , checkScrollState ] )
124125
125126 // Auto-scroll to bottom when component mounts or thread content changes
126127 useEffect ( ( ) => {
@@ -138,7 +139,7 @@ export const useThreadScrolling = (
138139 checkScrollState ( )
139140 return
140141 }
141- } , [ ] )
142+ } , [ checkScrollState , scrollToBottom ] )
142143
143144 const handleDOMScroll = ( e : Event ) => {
144145 const target = e . target as HTMLDivElement
@@ -182,7 +183,7 @@ export const useThreadScrolling = (
182183 userIntendedPositionRef . current = null
183184 wasStreamingRef . current = false
184185 checkScrollState ( )
185- } , [ threadId ] )
186+ } , [ threadId , checkScrollState , scrollToBottom ] )
186187
187188 return useMemo (
188189 ( ) => ( { showScrollToBottomBtn, scrollToBottom, setIsUserScrolling } ) ,
0 commit comments