diff --git a/src/Expensify.tsx b/src/Expensify.tsx index a7dd389611b6..639404657c1b 100644 --- a/src/Expensify.tsx +++ b/src/Expensify.tsx @@ -18,7 +18,6 @@ import useIsAuthenticated from './hooks/useIsAuthenticated'; import useLocalize from './hooks/useLocalize'; import useOnyx from './hooks/useOnyx'; import {updateLastRoute} from './libs/actions/App'; -import {initReconnect} from './libs/actions/Reconnect'; import * as ActiveClientManager from './libs/ActiveClientManager'; import {isSafari} from './libs/Browser'; import Log from './libs/Log'; @@ -251,15 +250,6 @@ function Expensify() { // eslint-disable-next-line react-hooks/exhaustive-deps -- we don't want this effect to run again }, []); - const didInitReconnectRef = useRef(false); - useEffect(() => { - if (didInitReconnectRef.current) { - return; - } - didInitReconnectRef.current = true; - initReconnect(); - }, []); - useLayoutEffect(() => { if (!isNavigationReady || !lastRoute) { return; diff --git a/src/libs/actions/Reconnect.ts b/src/libs/actions/Reconnect.ts index 94b89499ace0..b0da80cc9540 100644 --- a/src/libs/actions/Reconnect.ts +++ b/src/libs/actions/Reconnect.ts @@ -60,27 +60,25 @@ onNetworkReachabilityConfirmed(() => { }); // Any offline→online transition — flush the sequential queue -let wasOffline: boolean; -const initReconnect = () => { - wasOffline = getIsOffline(); - subscribeNetworkState(() => { - const offline = getIsOffline(); - if (wasOffline && !offline) { - Log.info('[Reconnect] Offline→online, flushing queue'); - flush(); - } - wasOffline = offline; - }); - - // App came to foreground — sync data and flush queue - AppStateMonitor.addBecameActiveListener(() => { - Log.info('[Reconnect] App became active'); - if (getIsOffline()) { - refreshNetworkState(); - } - reconnect(); +let wasOffline = getIsOffline(); +subscribeNetworkState(() => { + const offline = getIsOffline(); + if (wasOffline && !offline) { + Log.info('[Reconnect] Offline→online, flushing queue'); flush(); - }); -}; + } + wasOffline = offline; +}); + +// App came to foreground — sync data and flush queue +AppStateMonitor.addBecameActiveListener(() => { + Log.info('[Reconnect] App became active'); + if (getIsOffline()) { + refreshNetworkState(); + } + reconnect(); + flush(); +}); -export {reconnect, initReconnect}; +// eslint-disable-next-line import/prefer-default-export -- single export is intentional; more reconnection helpers may be added here as the architecture evolves +export {reconnect}; diff --git a/tests/actions/ReportTest.ts b/tests/actions/ReportTest.ts index 6b7cb2cb4a05..2b107602fbda 100644 --- a/tests/actions/ReportTest.ts +++ b/tests/actions/ReportTest.ts @@ -22,7 +22,6 @@ import playSound, {SOUNDS} from '@libs/Sound'; import CONST from '@src/CONST'; import OnyxUpdateManager from '@src/libs/actions/OnyxUpdateManager'; import * as PersistedRequests from '@src/libs/actions/PersistedRequests'; -import {initReconnect} from '@src/libs/actions/Reconnect'; import * as Report from '@src/libs/actions/Report'; import * as User from '@src/libs/actions/User'; import DateUtils from '@src/libs/DateUtils'; @@ -174,7 +173,6 @@ jest.mock('react-native-blob-util', () => ({ const originalXHR = HttpUtils.xhr; OnyxUpdateManager(); -initReconnect(); // Define introSelected to use across all openReport tests const TEST_INTRO_SELECTED: OnyxTypes.IntroSelected = { diff --git a/tests/actions/SessionTest.ts b/tests/actions/SessionTest.ts index fac013420337..c72354545a73 100644 --- a/tests/actions/SessionTest.ts +++ b/tests/actions/SessionTest.ts @@ -7,7 +7,6 @@ import {confirmReadyToOpenApp, openApp, reconnectApp} from '@libs/actions/App'; import {buildOldDotURL, openExternalLink} from '@libs/actions/Link'; import OnyxUpdateManager from '@libs/actions/OnyxUpdateManager'; import {getAll as getAllPersistedRequests} from '@libs/actions/PersistedRequests'; -import {initReconnect} from '@libs/actions/Reconnect'; import * as SignInRedirect from '@libs/actions/SignInRedirect'; import {SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import asyncOpenURL from '@libs/asyncOpenURL'; @@ -58,7 +57,6 @@ Onyx.init({ }); OnyxUpdateManager(); -initReconnect(); beforeEach(() => { setHasRadio(true); return Onyx.clear().then(waitForBatchedUpdates); diff --git a/tests/unit/APITest.ts b/tests/unit/APITest.ts index 901a949e251d..4f25a136a795 100644 --- a/tests/unit/APITest.ts +++ b/tests/unit/APITest.ts @@ -1,6 +1,5 @@ import MockedOnyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; -import {initReconnect} from '@libs/actions/Reconnect'; import type {EnablePolicyFeatureCommand} from '@libs/actions/RequestConflictUtils'; import type {ApiRequestCommandParameters, ReadCommand, WriteCommand} from '@libs/API/types'; import CONST from '@src/CONST'; @@ -27,7 +26,6 @@ jest.mock('@src/libs/Log'); Onyx.init({ keys: ONYXKEYS, }); -initReconnect(); type Response = { ok?: boolean; diff --git a/tests/unit/ReconnectTest.ts b/tests/unit/ReconnectTest.ts index 8dbcaf49bc97..d011dd00cbb4 100644 --- a/tests/unit/ReconnectTest.ts +++ b/tests/unit/ReconnectTest.ts @@ -1,6 +1,6 @@ import Onyx from 'react-native-onyx'; import {openApp, reconnectApp} from '@libs/actions/App'; -import {initReconnect, reconnect} from '@libs/actions/Reconnect'; +import {reconnect} from '@libs/actions/Reconnect'; import type AppStateMonitorType from '@libs/AppStateMonitor'; import {flush} from '@libs/Network/SequentialQueue'; import {getIsOffline, setHasRadio, setSustainedFailures} from '@libs/NetworkState'; @@ -24,8 +24,7 @@ jest.mock('@libs/AppStateMonitor', () => ({ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access -- extracting callback captured during module load const AppStateMonitor: typeof AppStateMonitorType = require('@libs/AppStateMonitor').default; -initReconnect(); -const firstCall = jest.mocked(AppStateMonitor.addBecameActiveListener).mock.calls.at(-1); +const firstCall = jest.mocked(AppStateMonitor.addBecameActiveListener).mock.calls.at(0); if (!firstCall) { throw new Error('AppStateMonitor.addBecameActiveListener was not called during Reconnect.ts module load'); } @@ -100,7 +99,7 @@ describe('Reconnect', () => { test('sustained failure recovery notifies reachability listeners', () => { const {onReachabilityConfirmed} = require('@libs/NetworkState'); const listener = jest.fn(); - const unSub = onReachabilityConfirmed(listener); + const unsub = onReachabilityConfirmed(listener); setSustainedFailures(true); listener.mockClear(); @@ -113,7 +112,7 @@ describe('Reconnect', () => { jest.useRealTimers(); expect(listener).toHaveBeenCalledTimes(1); - unSub(); + unsub(); }); test('reachability confirmed triggers reconnect when sustained failures clear', async () => {