From 6082a6a7904cb19300a2fe30e72cb6bab28958a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Espino=20Garc=C3=ADa?= Date: Wed, 11 Jan 2023 20:37:09 +0100 Subject: [PATCH] Fix connection banner showing when not needed (#6948) * Fix connection banner showing when not needed * Fix some issues and some refactoring --- app/client/websocket/index.ts | 12 ++++++-- .../connection_banner/connection_banner.tsx | 12 +++----- app/managers/websocket_manager.ts | 28 +++++++++++-------- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/app/client/websocket/index.ts b/app/client/websocket/index.ts index b5fb3c5605..80ec319559 100644 --- a/app/client/websocket/index.ts +++ b/app/client/websocket/index.ts @@ -33,6 +33,7 @@ export default class WebSocketClient { private firstConnectCallback?: () => void; private missedEventsCallback?: () => void; private reconnectCallback?: () => void; + private reliableReconnectCallback?: () => void; private errorCallback?: Function; private closeCallback?: (connectFailCount: number, lastDisconnect: number) => void; private connectingCallback?: () => void; @@ -148,8 +149,11 @@ export default class WebSocketClient { logInfo('websocket re-established connection to', this.url); if (!reliableWebSockets && this.reconnectCallback) { this.reconnectCallback(); - } else if (reliableWebSockets && this.serverSequence && this.missedEventsCallback) { - this.missedEventsCallback(); + } else if (reliableWebSockets) { + this.reliableReconnectCallback?.(); + if (this.serverSequence && this.missedEventsCallback) { + this.missedEventsCallback(); + } } } else if (this.firstConnectCallback) { logInfo('websocket connected to', this.url); @@ -295,6 +299,10 @@ export default class WebSocketClient { this.reconnectCallback = callback; } + public setReliableReconnectCallback(callback: () => void) { + this.reliableReconnectCallback = callback; + } + public setErrorCallback(callback: Function) { this.errorCallback = callback; } diff --git a/app/components/connection_banner/connection_banner.tsx b/app/components/connection_banner/connection_banner.tsx index 44604ff32d..7b958a45e7 100644 --- a/app/components/connection_banner/connection_banner.tsx +++ b/app/components/connection_banner/connection_banner.tsx @@ -106,6 +106,7 @@ const ConnectionBanner = ({ } return () => { clearTimeoutRef(openTimeout); + clearTimeoutRef(closeTimeout); }; }, []); @@ -125,7 +126,7 @@ const ConnectionBanner = ({ } }, [isConnected]); - useEffect(() => { + useDidUpdate(() => { if (appState === 'active') { if (!isConnected && !visible) { if (!openTimeout.current) { @@ -138,10 +139,11 @@ const ConnectionBanner = ({ } } } else { + setVisible(false); clearTimeoutRef(openTimeout); clearTimeoutRef(closeTimeout); } - }, [appState]); + }, [appState === 'active']); useEffect(() => { height.value = withTiming(visible ? ANNOUNCEMENT_BAR_HEIGHT : 0, { @@ -149,12 +151,6 @@ const ConnectionBanner = ({ }); }, [visible]); - useEffect(() => { - return () => { - clearTimeoutRef(closeTimeout); - }; - }); - const bannerStyle = useAnimatedStyle(() => ({ height: height.value, })); diff --git a/app/managers/websocket_manager.ts b/app/managers/websocket_manager.ts index 1e44a3da2c..5358df848e 100644 --- a/app/managers/websocket_manager.ts +++ b/app/managers/websocket_manager.ts @@ -30,12 +30,12 @@ class WebsocketManager { private connectionTimerIDs: Record void>> = {}; private isBackgroundTimerRunning = false; private netConnected = false; - private previousAppState: AppStateStatus; + private previousActiveState: boolean; private statusUpdatesIntervalIDs: Record = {}; private backgroundIntervalId: number | undefined; constructor() { - this.previousAppState = AppState.currentState; + this.previousActiveState = AppState.currentState === 'active'; } public init = async (serverCredentials: ServerCredential[]) => { @@ -81,6 +81,7 @@ class WebsocketManager { //client.setMissedEventsCallback(() => {}) Nothing to do on missedEvents callback client.setReconnectCallback(() => this.onReconnect(serverUrl)); + client.setReliableReconnectCallback(() => this.onReliableReconnect(serverUrl)); client.setCloseCallback((connectFailCount: number, lastDisconnect: number) => this.onWebsocketClose(serverUrl, connectFailCount, lastDisconnect)); if (this.netConnected && ['unknown', 'active'].includes(AppState.currentState)) { @@ -153,23 +154,27 @@ class WebsocketManager { private onFirstConnect = (serverUrl: string) => { this.startPeriodicStatusUpdates(serverUrl); - handleFirstConnect(serverUrl); this.getConnectedSubject(serverUrl).next('connected'); + handleFirstConnect(serverUrl); }; private onReconnect = async (serverUrl: string) => { this.startPeriodicStatusUpdates(serverUrl); + this.getConnectedSubject(serverUrl).next('connected'); await handleReconnect(serverUrl); + }; + + private onReliableReconnect = async (serverUrl: string) => { this.getConnectedSubject(serverUrl).next('connected'); }; private onWebsocketClose = async (serverUrl: string, connectFailCount: number, lastDisconnect: number) => { + this.getConnectedSubject(serverUrl).next('not_connected'); if (connectFailCount <= 1) { // First fail await setCurrentUserStatusOffline(serverUrl); await handleClose(serverUrl, lastDisconnect); this.stopPeriodicStatusUpdates(serverUrl); - this.getConnectedSubject(serverUrl).next('not_connected'); } }; @@ -205,14 +210,15 @@ class WebsocketManager { } private onAppStateChange = async (appState: AppStateStatus) => { - if (appState === this.previousAppState) { + const isActive = appState === 'active'; + if (isActive === this.previousActiveState) { return; } const isMain = isMainActivity(); this.cancelAllConnections(); - if (appState !== 'active' && !this.isBackgroundTimerRunning) { + if (!isActive && !this.isBackgroundTimerRunning) { this.isBackgroundTimerRunning = true; this.cancelAllConnections(); this.backgroundIntervalId = BackgroundTimer.setInterval(() => { @@ -221,22 +227,22 @@ class WebsocketManager { this.isBackgroundTimerRunning = false; }, WAIT_TO_CLOSE); - this.previousAppState = appState; + this.previousActiveState = isActive; return; } - if (appState === 'active' && this.netConnected && isMain) { // Reopen the websockets only if there is connection + if (isActive && this.netConnected && isMain) { // Reopen the websockets only if there is connection if (this.backgroundIntervalId) { BackgroundTimer.clearInterval(this.backgroundIntervalId); } this.isBackgroundTimerRunning = false; this.openAll(); - this.previousAppState = appState; + this.previousActiveState = isActive; return; } if (isMain) { - this.previousAppState = appState; + this.previousActiveState = isActive; } }; @@ -248,7 +254,7 @@ class WebsocketManager { this.netConnected = newState; - if (this.netConnected && this.previousAppState === 'active') { // Reopen the websockets only if the app is active + if (this.netConnected && this.previousActiveState) { // Reopen the websockets only if the app is active this.openAll(); return; }