From 268343be3e39b92e0df934e4d4b5ffd279dcfcc3 Mon Sep 17 00:00:00 2001 From: Ammar Ahmed Date: Thu, 12 Sep 2024 11:35:56 +0500 Subject: [PATCH] mobile: fix android crash when app removed from recents --- apps/mobile/app/hooks/use-app-events.tsx | 7 ++++--- .../mobile/app/screens/editor/tiptap/utils.ts | 5 +++-- apps/mobile/app/services/notifications.ts | 13 +++++------- apps/mobile/app/utils/notesnook-module.ts | 6 +++++- .../notesnook/OnClearFromRecentService.java | 20 ++++++------------- .../notesnook/RCTNNativeModule.java | 18 +++++++++++++++++ 6 files changed, 41 insertions(+), 28 deletions(-) diff --git a/apps/mobile/app/hooks/use-app-events.tsx b/apps/mobile/app/hooks/use-app-events.tsx index c61a45d00..e6399334b 100644 --- a/apps/mobile/app/hooks/use-app-events.tsx +++ b/apps/mobile/app/hooks/use-app-events.tsx @@ -95,6 +95,7 @@ import { import { getGithubVersion } from "../utils/github-version"; import { tabBarRef } from "../utils/global-refs"; import { sleep } from "../utils/time"; +import { NotesnookModule } from "../utils/notesnook-module"; const onCheckSyncStatus = async (type: SyncStatusEvent) => { const { disableSync, disableAutoSync } = SettingsService.get(); @@ -254,9 +255,9 @@ async function saveEditorState() { movedAway: editorState().movedAway, timestamp: Date.now() }); - MMKV.setString("appState", state); + NotesnookModule.setAppState(state); } else { - MMKV.removeItem("appState"); + NotesnookModule.setAppState(""); } } @@ -632,7 +633,7 @@ export const useAppEvents = () => { Sync.run("global", false, "full"); reconnectSSE(); await checkForShareExtensionLaunchedInBackground(); - MMKV.removeItem("appState"); + NotesnookModule.setAppState(""); let user = await db.user.getUser(); if (user && !user?.isEmailConfirmed) { try { diff --git a/apps/mobile/app/screens/editor/tiptap/utils.ts b/apps/mobile/app/screens/editor/tiptap/utils.ts index a6b241e63..42373e8bf 100644 --- a/apps/mobile/app/screens/editor/tiptap/utils.ts +++ b/apps/mobile/app/screens/editor/tiptap/utils.ts @@ -31,6 +31,7 @@ import { useTabStore } from "./use-tab-store"; import { parseInternalLink } from "@notesnook/core"; import { eOnLoadNote } from "../../../utils/events"; import { db } from "../../../common/database"; +import { NotesnookModule } from "../../../utils/notesnook-module"; export const textInput = createRef(); export const editorController = createRef() as MutableRefObject; @@ -165,7 +166,7 @@ const canRestoreAppState = (appState: AppState) => { let appState: AppState | undefined; export function getAppState() { if (appState && canRestoreAppState(appState)) return appState as AppState; - const json = MMKV.getString("appState"); + const json = NotesnookModule.getAppState(); if (json) { appState = JSON.parse(json) as AppState; if (canRestoreAppState(appState)) { @@ -180,7 +181,7 @@ export function getAppState() { export function clearAppState() { appState = undefined; - MMKV.removeItem("appState"); + NotesnookModule.setAppState(""); } export async function openInternalLink(url: string) { diff --git a/apps/mobile/app/services/notifications.ts b/apps/mobile/app/services/notifications.ts index 498d72602..3f0109a1d 100644 --- a/apps/mobile/app/services/notifications.ts +++ b/apps/mobile/app/services/notifications.ts @@ -35,22 +35,21 @@ import dayjs, { Dayjs } from "dayjs"; import { encodeNonAsciiHTML } from "entities"; import { Platform } from "react-native"; import { db, setupDatabase } from "../common/database"; -import { MMKV } from "../common/database/mmkv"; import { presentDialog } from "../components/dialog/functions"; +import { useTabStore } from "../screens/editor/tiptap/use-tab-store"; import { editorState } from "../screens/editor/tiptap/utils"; import { useRelationStore } from "../stores/use-relation-store"; import { useReminderStore } from "../stores/use-reminder-store"; import { useSettingStore } from "../stores/use-setting-store"; -import { eOnLoadNote } from "../utils/events"; +import { useUserStore } from "../stores/use-user-store"; import { tabBarRef } from "../utils/global-refs"; import { convertNoteToText } from "../utils/note-to-text"; +import { NotesnookModule } from "../utils/notesnook-module"; import { sleep } from "../utils/time"; import { DDS } from "./device-detection"; import { eSendEvent } from "./event-manager"; import Navigation from "./navigation"; import SettingsService from "./settings"; -import { useUserStore } from "../stores/use-user-store"; -import { useTabStore } from "../screens/editor/tiptap/use-tab-store"; let pinned: DisplayedNotification[] = []; @@ -126,7 +125,7 @@ const onEvent = async ({ type, detail }: Event) => { if (type === EventType.PRESS) { notifee.decrementBadgeCount(); if (notification?.data?.type === "quickNote") return; - MMKV.removeItem("appState"); + NotesnookModule.setAppState(""); if (notification?.data?.type === "reminder" && notification?.id) { const reminder = await db.reminders?.reminder( notification.id?.split("_")[0] @@ -410,9 +409,7 @@ async function loadNote(id: string, jump: boolean) { if (!DDS.isTab && jump) { tabBarRef.current?.goToPage(1); } - - MMKV.setString( - "appState", + NotesnookModule.setAppState( JSON.stringify({ editing: true, movedAway: false, diff --git a/apps/mobile/app/utils/notesnook-module.ts b/apps/mobile/app/utils/notesnook-module.ts index a2ceb7202..f81be1942 100644 --- a/apps/mobile/app/utils/notesnook-module.ts +++ b/apps/mobile/app/utils/notesnook-module.ts @@ -23,13 +23,17 @@ interface NotesnookModuleInterface { getActivityName: () => Promise; setBackgroundColor: (color: string) => void; setSecureMode: (enabled: boolean) => void; + setAppState: (appState: string) => void; + getAppState: () => string; } export const NotesnookModule: NotesnookModuleInterface = Platform.select({ ios: { getActivityName: () => {}, setBackgroundColor: () => {}, - setSecureMode: () => {} + setSecureMode: () => {}, + setAppState: () => {}, + getAppState: () => {} }, android: NativeModules.NNativeModule }); diff --git a/apps/mobile/native/android/app/src/main/java/com/streetwriters/notesnook/OnClearFromRecentService.java b/apps/mobile/native/android/app/src/main/java/com/streetwriters/notesnook/OnClearFromRecentService.java index 76c478dd4..11e8d8443 100644 --- a/apps/mobile/native/android/app/src/main/java/com/streetwriters/notesnook/OnClearFromRecentService.java +++ b/apps/mobile/native/android/app/src/main/java/com/streetwriters/notesnook/OnClearFromRecentService.java @@ -1,17 +1,12 @@ package com.streetwriters.notesnook; import android.app.Service; import android.content.Intent; +import android.content.SharedPreferences; import android.os.IBinder; import android.util.Log; -import com.ammarahmed.mmkv.MMKV; - public class OnClearFromRecentService extends Service { - static { - System.loadLibrary("rnmmkv"); - } - @Override public IBinder onBind(Intent intent) { return null; @@ -30,15 +25,12 @@ public class OnClearFromRecentService extends Service { @Override public void onTaskRemoved(Intent rootIntent) { try { - MMKV.initialize(getApplicationContext()); - MMKV mmkv = MMKV.mmkvWithID("default",MMKV.SINGLE_PROCESS_MODE); - mmkv.removeValueForKey("appState"); + SharedPreferences appStateDetails = getApplicationContext().getSharedPreferences("appStateDetails", MODE_PRIVATE); + SharedPreferences.Editor edit = appStateDetails.edit(); + edit.remove("appState"); + edit.apply(); stopSelf(); - } catch (UnsatisfiedLinkError e) { - - } catch (Exception e) { - + } catch (UnsatisfiedLinkError | Exception e) { } - //System.exit(0); } } \ No newline at end of file diff --git a/apps/mobile/native/android/app/src/main/java/com/streetwriters/notesnook/RCTNNativeModule.java b/apps/mobile/native/android/app/src/main/java/com/streetwriters/notesnook/RCTNNativeModule.java index 8d5803981..8bf1f97a8 100644 --- a/apps/mobile/native/android/app/src/main/java/com/streetwriters/notesnook/RCTNNativeModule.java +++ b/apps/mobile/native/android/app/src/main/java/com/streetwriters/notesnook/RCTNNativeModule.java @@ -1,7 +1,10 @@ package com.streetwriters.notesnook; +import android.content.Context; +import android.content.SharedPreferences; import android.graphics.Color; +import android.util.Log; import android.view.WindowManager; import com.facebook.react.bridge.Promise; @@ -67,6 +70,21 @@ public class RCTNNativeModule extends ReactContextBaseJavaModule { } } + @ReactMethod + public void setAppState(final String appState) { + SharedPreferences appStateDetails = getReactApplicationContext().getSharedPreferences("appStateDetails", Context.MODE_PRIVATE); + SharedPreferences.Editor edit = appStateDetails.edit(); + edit.putString("appState", appState); + edit.apply(); + } + + @ReactMethod(isBlockingSynchronousMethod = true) + public String getAppState() { + SharedPreferences appStateDetails = getReactApplicationContext().getSharedPreferences("appStateDetails", Context.MODE_PRIVATE); + String appStateValue = appStateDetails.getString("appState", ""); + return appStateValue.isEmpty() ? null : appStateValue; + } + }