mobile: run sync on startup

This commit is contained in:
Ammar Ahmed
2024-08-27 15:20:34 +05:00
committed by Abdullah Atta
parent 6641d3e625
commit 7aeeabfb3a
3 changed files with 40 additions and 88 deletions

View File

@@ -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);
}
}

View File

@@ -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<void>) {
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();

View File

@@ -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);
};