From 7aeeabfb3a0e9ab4d2104c6aa18aae1dbd2e2c97 Mon Sep 17 00:00:00 2001 From: Ammar Ahmed Date: Tue, 27 Aug 2024 15:20:34 +0500 Subject: [PATCH] mobile: run sync on startup --- apps/mobile/app/hooks/use-app-events.tsx | 64 ++++++--------------- apps/mobile/app/services/background-sync.ts | 6 +- apps/mobile/app/services/sync.ts | 58 +++++++------------ 3 files changed, 40 insertions(+), 88 deletions(-) diff --git a/apps/mobile/app/hooks/use-app-events.tsx b/apps/mobile/app/hooks/use-app-events.tsx index 80f751076..c61a45d00 100644 --- a/apps/mobile/app/hooks/use-app-events.tsx +++ b/apps/mobile/app/hooks/use-app-events.tsx @@ -26,10 +26,7 @@ import { } from "@notesnook/core/dist/common"; import { EventManagerSubscription } from "@notesnook/core/dist/utils/event-manager"; import notifee from "@notifee/react-native"; -import NetInfo, { - NetInfoState, - NetInfoSubscription -} from "@react-native-community/netinfo"; +import NetInfo, { NetInfoSubscription } from "@react-native-community/netinfo"; import React, { useCallback, useEffect, useRef } from "react"; import { AppState, @@ -47,6 +44,7 @@ import { checkVersion } from "react-native-check-version"; import Config from "react-native-config"; import * as RNIap from "react-native-iap"; import { DatabaseLogger, db, setupDatabase } from "../common/database"; +import { initializeLogger } from "../common/database/logger"; import { MMKV } from "../common/database/mmkv"; import Migrate from "../components/sheets/migrate"; import NewFeature from "../components/sheets/new-feature"; @@ -97,7 +95,6 @@ import { import { getGithubVersion } from "../utils/github-version"; import { tabBarRef } from "../utils/global-refs"; import { sleep } from "../utils/time"; -import { initializeLogger } from "../common/database/logger"; const onCheckSyncStatus = async (type: SyncStatusEvent) => { const { disableSync, disableAutoSync } = SettingsService.get(); @@ -362,6 +359,7 @@ const initializeDatabase = async (password?: string) => { try { await setupDatabase(password); await db.init(); + Sync.run(); } catch (e) { DatabaseLogger.error(e as Error); ToastManager.error(e as Error, "Error initializing database", "global"); @@ -391,18 +389,15 @@ export const useAppEvents = () => { ]); const syncedOnLaunch = useRef(false); - const refValues = useRef< Partial<{ subsriptionSuccessListener: EmitterSubscription; subsriptionErrorListener: EmitterSubscription; - isUserReady: boolean; prevState: AppStateStatus; - showingDialog: boolean; removeInternetStateListener: NetInfoSubscription; - isReconnecting: boolean; initialUrl: string; backupDidWait: boolean; + isConnectingSSE: boolean; }> >({}); @@ -550,7 +545,6 @@ export const useAppEvents = () => { setRecoveryKeyMessage(); } if (!user?.isEmailConfirmed) setEmailVerifyMessage(); - refValues.current.isUserReady = true; syncedOnLaunch.current = true; if (!isLogin) { @@ -624,18 +618,19 @@ export const useAppEvents = () => { }, [onSyncComplete, onUserUpdated]); useEffect(() => { - const onInternetStateChanged = async (state: NetInfoState) => { + const onInternetStateChanged = async () => { if (!syncedOnLaunch.current) return; - reconnectSSE(state); + Sync.run("global", false, "full"); + reconnectSSE(); }; const onAppStateChanged = async (state: AppStateStatus) => { if (state === "active") { notifee.setBadgeCount(0); updateStatusBarColor(); - checkAutoBackup(); - await reconnectSSE(); + Sync.run("global", false, "full"); + reconnectSSE(); await checkForShareExtensionLaunchedInBackground(); MMKV.removeItem("appState"); let user = await db.user.getUser(); @@ -721,42 +716,15 @@ export const useAppEvents = () => { } }, [appLocked, syncing, checkAutoBackup]); - async function reconnectSSE(connection?: NetInfoState) { - if (refValues.current?.isReconnecting || !refValues.current?.isUserReady) - return; - - if (useSettingStore.getState().appDidEnterBackgroundForAction) { - useSettingStore.getState().setAppDidEnterBackgroundForAction(false); - console.log("AppDidEnterForegroundAfterAction"); - return; - } - - if (SettingsService.get().sessionExpired) { - refValues.current.isReconnecting = false; - return; - } - - refValues.current.isReconnecting = true; - let connectionState = connection; + async function reconnectSSE() { try { - if (!connectionState) { - connectionState = await NetInfo.fetch(); - } - - const user = await db.user.getUser(); - if ( - user && - connectionState.isConnected && - connectionState.isInternetReachable - ) { - await db.connectSSE(); - } else { - useUserStore.getState().setSyncing(false); - await db.syncer.stop(); - } - refValues.current.isReconnecting = false; + if (refValues.current?.isConnectingSSE) return; + refValues.current.isConnectingSSE = true; + await db.connectSSE(); + refValues.current.isConnectingSSE = false; } catch (e) { - refValues.current.isReconnecting = false; + refValues.current.isConnectingSSE = false; + DatabaseLogger.error(e as Error); } } diff --git a/apps/mobile/app/services/background-sync.ts b/apps/mobile/app/services/background-sync.ts index e7436f063..927c07fb3 100644 --- a/apps/mobile/app/services/background-sync.ts +++ b/apps/mobile/app/services/background-sync.ts @@ -27,6 +27,7 @@ import { AppState, AppRegistry } from "react-native"; import Notifications from "./notifications"; import SettingsService from "./settings"; import { deleteDCacheFiles } from "../common/filesystem/io"; +import Sync from "./sync"; async function doInBackground(callback: () => Promise) { if (Platform.OS === "ios") { @@ -116,10 +117,7 @@ async function onBackgroundSyncStarted() { } const user = await db.user?.getUser(); if (user) { - await db.sync({ - type: "full", - force: false - }); + Sync.run("global", false, "full"); } await Notifications.setupReminders(); deleteDCacheFiles(); diff --git a/apps/mobile/app/services/sync.ts b/apps/mobile/app/services/sync.ts index a136c4ffb..64ab727ff 100644 --- a/apps/mobile/app/services/sync.ts +++ b/apps/mobile/app/services/sync.ts @@ -30,7 +30,9 @@ export const ignoredMessages = [ "Sync already running", "Not allowed to start service intent", "WebSocket failed to connect", - "Failed to start the HttpConnection before" + "Failed to start the HttpConnection before", + "Could not connect to the Sync server", + "Network request failed" ]; let pendingSync: any = undefined; let syncTimer: NodeJS.Timeout; @@ -61,25 +63,18 @@ const run = async ( clearTimeout(syncTimer); syncTimer = setTimeout(async () => { - const status = await NetInfo.fetch(); const userstore = useUserStore.getState(); + userstore.setSyncing(true); const user = await db.user.getUser(); - if (!status.isInternetReachable) { - DatabaseLogger.warn("Internet not reachable"); - } - if ( - !user || - !status.isInternetReachable || - SettingsService.get().disableSync - ) { + if (!user || SettingsService.get().disableSync) { + userstore.setSyncing(false); initAfterSync(); pendingSync = undefined; return onCompleted?.(SyncStatus.Failed); } - userstore.setSyncing(true); - let error = null; + let error: Error | undefined = undefined; try { await BackgroundSync.doInBackground(async () => { @@ -90,30 +85,23 @@ const run = async ( offlineMode: SettingsService.get().offlineMode }); } catch (e) { - error = e; + error = e as Error; } }); - if (error) { - throw error; - } + if (error) throw error; } catch (e) { - error = e; + error = e as Error; + DatabaseLogger.error(error, "[Client] Failed to sync"); if ( - !ignoredMessages.find((message) => - (e as Error).message?.includes(message) - ) && - userstore.user && - status.isConnected && - status.isInternetReachable + !ignoredMessages.find((message) => error?.message?.includes(message)) && + userstore.user ) { - userstore.setSyncing(false, SyncStatus.Failed); + const status = await NetInfo.fetch(); if (status.isConnected && status.isInternetReachable) { ToastManager.error(e as Error, "Sync failed", context); } } - - DatabaseLogger.error(e, "[Client] Failed to sync"); } finally { initAfterSync(); userstore.setSyncing( @@ -121,16 +109,14 @@ const run = async ( error ? SyncStatus.Failed : SyncStatus.Passed ); onCompleted?.(error ? SyncStatus.Failed : SyncStatus.Passed); - setImmediate(() => { - if (pendingSync) - Sync.run( - pendingSync.context, - pendingSync.forced, - pendingSync.type, - pendingSync.onCompleted, - pendingSync.lastSyncTime - ); - }); + if (pendingSync) + Sync.run( + pendingSync.context, + pendingSync.forced, + pendingSync.type, + pendingSync.onCompleted, + pendingSync.lastSyncTime + ); } }, 300); };