@@ -4,6 +4,7 @@ import { useObservable, useSubscription } from 'observable-hooks';
4
4
import type { ReactNode } from 'react' ;
5
5
import { useCallback , useEffect , useRef , useState } from 'react' ;
6
6
import * as rxjs from 'rxjs' ;
7
+ import { useIsElementVisible } from '../../hooks/is-element-visible' ;
7
8
import type { GameLogLine } from '../../types/game.types' ;
8
9
9
10
export interface GameContentProps {
@@ -143,43 +144,19 @@ export const GameContent: React.FC<GameContentProps> = (
143
144
} ) ;
144
145
145
146
const scrollableRef = useRef < HTMLDivElement > ( null ) ;
146
- const scrollBottomRef = useRef < HTMLDivElement > ( null ) ;
147
+ const scrollTargetRef = useRef < HTMLDivElement > ( null ) ;
147
148
148
- const [ autoScrollEnabled , setAutoScrollEnabled ] = useState < boolean > (
149
- enableScrollToNewLogLines
150
- ) ;
151
-
152
- useEffect ( ( ) => {
153
- if ( ! enableScrollToNewLogLines ) {
154
- return ;
155
- }
156
-
157
- let scrollableElmt = scrollableRef . current ;
158
-
159
- const onScroll = ( ) => {
160
- scrollableElmt = scrollableRef . current ;
161
-
162
- if ( ! scrollableElmt ) {
163
- return ;
164
- }
165
-
166
- const { scrollTop, scrollHeight, clientHeight } = scrollableElmt ;
167
- const difference = scrollHeight - clientHeight - scrollTop ;
168
- const enableAutoScroll = difference <= clientHeight ;
169
-
170
- setAutoScrollEnabled ( enableAutoScroll ) ;
171
- } ;
172
-
173
- scrollableElmt ?. addEventListener ( 'scroll' , onScroll ) ;
174
-
175
- return ( ) => {
176
- scrollableElmt ?. removeEventListener ( 'scroll' , onScroll ) ;
177
- } ;
178
- } , [ enableScrollToNewLogLines ] ) ;
149
+ const [ isScrollTargetVisible ] = useIsElementVisible ( {
150
+ root : scrollableRef . current ,
151
+ target : scrollTargetRef . current ,
152
+ threshold : 0.8 ,
153
+ } ) ;
179
154
180
155
useEffect ( ( ) => {
181
- if ( autoScrollEnabled ) {
182
- scrollBottomRef . current ?. scrollIntoView ( {
156
+ // If the user is scrolled to the bottom, then continue
157
+ // to scroll to the bottom as new log lines are added.
158
+ if ( enableScrollToNewLogLines && isScrollTargetVisible ) {
159
+ scrollTargetRef . current ?. scrollIntoView ( {
183
160
behavior : 'instant' ,
184
161
block : 'end' ,
185
162
inline : 'nearest' ,
@@ -203,7 +180,7 @@ export const GameContent: React.FC<GameContentProps> = (
203
180
) ;
204
181
} ) }
205
182
< EuiSpacer size = "s" />
206
- < div ref = { scrollBottomRef } />
183
+ < div ref = { scrollTargetRef } />
207
184
</ EuiPanel >
208
185
) ;
209
186
} ;
0 commit comments