@@ -32,14 +32,17 @@ export function useAutoScroll<T extends Message>({
3232 const userScrolledAtRef = useRef ( 0 )
3333 const userDisengagedRef = useRef ( false )
3434 const pointerStartYRef = useRef < number | null > ( null )
35+ const onScrollStateChangeRef = useRef ( onScrollStateChange )
36+
37+ onScrollStateChangeRef . current = onScrollStateChange
3538
3639 const scrollToBottom = useCallback ( ( ) => {
3740 if ( ! containerRef ?. current ) return
3841 userScrolledAtRef . current = 0
3942 userDisengagedRef . current = false
4043 containerRef . current . scrollTop = containerRef . current . scrollHeight
41- onScrollStateChange ?.( false )
42- } , [ containerRef , onScrollStateChange ] )
44+ onScrollStateChangeRef . current ?.( false )
45+ } , [ containerRef ] )
4346
4447 useEffect ( ( ) => {
4548 lastMessageCountRef . current = 0
@@ -49,14 +52,13 @@ export function useAutoScroll<T extends Message>({
4952 } , [ sessionId ] )
5053
5154 useEffect ( ( ) => {
52- if ( ! containerRef ?. current ) return
53-
54- const container = containerRef . current
55+ const container = containerRef ?. current
56+ if ( ! container ) return
5557
5658 const markDisengaged = ( ) => {
5759 userScrolledAtRef . current = Date . now ( )
5860 userDisengagedRef . current = true
59- onScrollStateChange ?.( true )
61+ onScrollStateChangeRef . current ?.( true )
6062 }
6163
6264 const handlePointerDown = ( e : PointerEvent ) => {
@@ -85,13 +87,31 @@ export function useAutoScroll<T extends Message>({
8587 markDisengaged ( )
8688 }
8789 }
90+
91+ const handleScroll = ( ) => {
92+ const { scrollTop, scrollHeight, clientHeight } = container
93+ const isAtBottom = scrollHeight - scrollTop - clientHeight < 50
94+
95+ if ( isAtBottom ) {
96+ if ( userDisengagedRef . current ) {
97+ userScrolledAtRef . current = 0
98+ userDisengagedRef . current = false
99+ onScrollStateChangeRef . current ?.( false )
100+ }
101+ } else if ( ! userDisengagedRef . current ) {
102+ userScrolledAtRef . current = Date . now ( )
103+ userDisengagedRef . current = true
104+ onScrollStateChangeRef . current ?.( true )
105+ }
106+ }
88107
89108 container . addEventListener ( 'pointerdown' , handlePointerDown , { passive : true } )
90109 container . addEventListener ( 'pointermove' , handlePointerMove , { passive : true } )
91110 container . addEventListener ( 'pointerup' , handlePointerUp , { passive : true } )
92111 container . addEventListener ( 'pointercancel' , handlePointerUp , { passive : true } )
93112 container . addEventListener ( 'wheel' , handleWheel , { passive : true } )
94113 container . addEventListener ( 'keydown' , handleKeyDown )
114+ container . addEventListener ( 'scroll' , handleScroll , { passive : true } )
95115
96116 return ( ) => {
97117 container . removeEventListener ( 'pointerdown' , handlePointerDown )
@@ -100,8 +120,9 @@ export function useAutoScroll<T extends Message>({
100120 container . removeEventListener ( 'pointercancel' , handlePointerUp )
101121 container . removeEventListener ( 'wheel' , handleWheel )
102122 container . removeEventListener ( 'keydown' , handleKeyDown )
123+ container . removeEventListener ( 'scroll' , handleScroll )
103124 }
104- } , [ containerRef , onScrollStateChange ] )
125+ } , [ containerRef , sessionId , messages ] )
105126
106127 useEffect ( ( ) => {
107128 if ( ! containerRef ?. current || ! messages ) return
0 commit comments