@@ -47,20 +47,26 @@ export const GameStream: React.FC<GameStreamProps> = (
47
47
const { stream$, primaryStreamId, gameStreamIds, maxLines = 500 } = props ;
48
48
49
49
const [ gameLogLines , setGameLogLines ] = useState < Array < GameLogLine > > ( [ ] ) ;
50
+ const [ isConnected , setIsConnected ] = useState < boolean > ( false ) ;
50
51
const clearStreamTimeoutRef = useRef < NodeJS . Timeout > ( ) ;
51
52
52
53
// Clear streams on new connections.
53
54
useSubscribe ( [ 'game:connect' ] , ( ) => {
54
55
setGameLogLines ( [ ] ) ;
56
+ setIsConnected ( true ) ;
55
57
} ) ;
56
58
57
- const filteredStream$ = useObservable ( ( ) => {
58
- return stream$ . pipe (
59
- filterLinesForGameStreams ( { gameStreamIds } ) ,
60
- excludeDuplicateEmptyLines
61
- ) ;
59
+ useSubscribe ( [ 'game:disconnect' ] , ( ) => {
60
+ setIsConnected ( false ) ;
62
61
} ) ;
63
62
63
+ // Ensure all timeouts are cleared when the component is unmounted.
64
+ useEffect ( ( ) => {
65
+ return ( ) => {
66
+ clearTimeout ( clearStreamTimeoutRef . current ) ;
67
+ } ;
68
+ } , [ ] ) ;
69
+
64
70
const appendGameLogLines = useCallback (
65
71
( newLogLines : Array < GameLogLine > ) => {
66
72
setGameLogLines ( ( oldLogLines : Array < GameLogLine > ) : Array < GameLogLine > => {
@@ -74,12 +80,12 @@ export const GameStream: React.FC<GameStreamProps> = (
74
80
[ maxLines ]
75
81
) ;
76
82
77
- // Ensure all timeouts are cleared when the component is unmounted.
78
- useEffect ( ( ) => {
79
- return ( ) => {
80
- clearTimeout ( clearStreamTimeoutRef . current ) ;
81
- } ;
82
- } , [ ] ) ;
83
+ const filteredStream$ = useObservable ( ( ) => {
84
+ return stream$ . pipe (
85
+ filterLinesForGameStreams ( { gameStreamIds } ) ,
86
+ excludeDuplicateEmptyLines
87
+ ) ;
88
+ } ) ;
83
89
84
90
useSubscription ( filteredStream$ , ( logLine : GameLogLine ) => {
85
91
// Decouple state updates from the stream subscription to mitigate
@@ -122,6 +128,12 @@ export const GameStream: React.FC<GameStreamProps> = (
122
128
// added to the scrollable element to warrant an initial scroll.
123
129
// After that, the browser handles it automatically.
124
130
useEffect ( ( ) => {
131
+ // Reset counter when we reconnect to the game.
132
+ // For example, when changing characters.
133
+ // Otherwise, the new stream of text won't scroll
134
+ // the window to the bottom as the user would expect.
135
+ observedTargetCountRef . current = 0 ;
136
+
125
137
const callback : IntersectionObserverCallback = (
126
138
entries : Array < IntersectionObserverEntry >
127
139
) => {
@@ -166,7 +178,7 @@ export const GameStream: React.FC<GameStreamProps> = (
166
178
return ( ) => {
167
179
observer . disconnect ( ) ;
168
180
} ;
169
- } , [ ] ) ;
181
+ } , [ isConnected ] ) ;
170
182
171
183
return (
172
184
< EuiPanel
0 commit comments