1- import { useCallback , useEffect , useMemo , useState } from 'react' ;
1+ import { useCallback , useEffect , useMemo , useRef , useState } from 'react' ;
22import { useTranslation } from 'react-i18next' ;
33
44import { APP_EVENTS } from '@/application/constants' ;
@@ -7,6 +7,7 @@ import { Button } from '@/components/ui/button';
77import { Progress } from '@/components/ui/progress' ;
88
99import { useAppHandlers } from './app.hooks' ;
10+ import { Log } from '@/utils/log' ;
1011
1112// WebSocket readyState enum
1213const READY_STATE = {
@@ -19,6 +20,7 @@ const READY_STATE = {
1920export function ConnectBanner ( ) {
2021 const [ readyState , setReadyState ] = useState < number > ( READY_STATE . CONNECTING ) ;
2122 const [ isStableConnection , setIsStableConnection ] = useState ( false ) ;
23+ const autoReconnectAttemptedRef = useRef ( false ) ;
2224 const { eventEmitter } = useAppHandlers ( ) ;
2325 const { t } = useTranslation ( ) ;
2426
@@ -65,6 +67,48 @@ export function ConnectBanner() {
6567 return readyState === READY_STATE . CLOSED ;
6668 } , [ readyState ] ) ;
6769
70+ useEffect ( ( ) => {
71+ if ( ! isClosed ) {
72+ autoReconnectAttemptedRef . current = false ;
73+ }
74+ } , [ isClosed ] ) ;
75+
76+ // Automatically trigger reconnect when the user returns to the page and the socket is closed
77+ useEffect ( ( ) => {
78+ if ( ! isClosed || isLoading ) return ;
79+ if ( typeof window === 'undefined' || typeof document === 'undefined' ) return ;
80+
81+ const tryAutoReconnect = ( ) => {
82+ if ( autoReconnectAttemptedRef . current ) return ;
83+ if ( ! isClosed || isLoading ) return ;
84+ if ( typeof navigator !== 'undefined' && navigator . onLine === false ) return ;
85+ if ( document . visibilityState !== 'visible' ) return ;
86+
87+ autoReconnectAttemptedRef . current = true ;
88+
89+ Log . debug ( 'Trying to auto reconnect' ) ;
90+ handleReconnect ( ) ;
91+ } ;
92+
93+ const handleVisibilityChange = ( ) => {
94+ if ( document . visibilityState === 'visible' ) {
95+ tryAutoReconnect ( ) ;
96+ }
97+ } ;
98+
99+ window . addEventListener ( 'focus' , tryAutoReconnect ) ;
100+ window . addEventListener ( 'online' , tryAutoReconnect ) ;
101+ document . addEventListener ( 'visibilitychange' , handleVisibilityChange ) ;
102+
103+ tryAutoReconnect ( ) ;
104+
105+ return ( ) => {
106+ window . removeEventListener ( 'focus' , tryAutoReconnect ) ;
107+ window . removeEventListener ( 'online' , tryAutoReconnect ) ;
108+ document . removeEventListener ( 'visibilitychange' , handleVisibilityChange ) ;
109+ } ;
110+ } , [ handleReconnect , isClosed , isLoading ] ) ;
111+
68112 // Only hide the banner when the connection is stable
69113 if ( isStableConnection && readyState === READY_STATE . OPEN ) {
70114 return (
0 commit comments