diff --git a/apps/mobile/app/app.tsx b/apps/mobile/app/app.tsx index f936316bb..22e6e1bae 100644 --- a/apps/mobile/app/app.tsx +++ b/apps/mobile/app/app.tsx @@ -44,6 +44,7 @@ import { useUserStore } from "./stores/use-user-store"; import RNBootSplash from "react-native-bootsplash"; import AppLocked from "./components/app-lock"; import { useSettingStore } from "./stores/use-setting-store"; +import ScreenGuardModule from "react-native-screenguard"; I18nManager.allowRTL(false); I18nManager.forceRTL(false); I18nManager.swapLeftAndRightInRTL(false); @@ -51,6 +52,7 @@ const { appLockEnabled, appLockMode } = SettingsService.get(); if (appLockEnabled || appLockMode !== "none") { useUserStore.getState().lockApp(true); } +ScreenGuardModule.initSettings(); RNBootSplash.hide({ fade: true }); @@ -66,6 +68,9 @@ const App = (props: { configureMode: "note-preview" }) => { useEffect(() => { SettingsService.onFirstLaunch(); changeSystemBarColors(); + SettingsService.setPrivacyScreen( + SettingsService.getProperty("privacyScreen") + ); setTimeout(async () => { await Notifications.get(); if (SettingsService.get().notifNotes) { diff --git a/apps/mobile/app/components/dialogs/applock-password/index.tsx b/apps/mobile/app/components/dialogs/applock-password/index.tsx index 1c98ebfda..fea4c13e2 100644 --- a/apps/mobile/app/components/dialogs/applock-password/index.tsx +++ b/apps/mobile/app/components/dialogs/applock-password/index.tsx @@ -201,12 +201,14 @@ export const AppLockPassword = () => { accountPass ? strings.enterAccountPassword() : mode === "change" - ? keyboardType === "pin" - ? strings.newPin() - : strings.newPassword() - : `${ - keyboardType === "pin" ? strings.pin() : strings.password() - }` + ? keyboardType === "pin" + ? strings.newPin() + : strings.newPassword() + : `${ + keyboardType === "pin" + ? strings.pin() + : strings.password() + }` } /> @@ -364,7 +366,9 @@ export const AppLockPassword = () => { SettingsService.getProperty("biometricsAuthEnabled") === false ) { SettingsService.setProperty("appLockEnabled", false); - SettingsService.setPrivacyScreen(SettingsService.get()); + SettingsService.setPrivacyScreen( + SettingsService.getProperty("privacyScreen") + ); ToastManager.show({ message: strings.applockDisabled(), type: "success" @@ -383,8 +387,8 @@ export const AppLockPassword = () => { mode === "remove" ? strings.remove() : mode === "change" - ? strings.change() - : strings.save() + ? strings.change() + : strings.save() } negativeTitle={strings.cancel()} positiveType="transparent" diff --git a/apps/mobile/app/screens/settings/settings-data.tsx b/apps/mobile/app/screens/settings/settings-data.tsx index 1357c3626..c2369337c 100644 --- a/apps/mobile/app/screens/settings/settings-data.tsx +++ b/apps/mobile/app/screens/settings/settings-data.tsx @@ -32,8 +32,6 @@ import React from "react"; import { Appearance, Linking, Platform } from "react-native"; import { getVersion } from "react-native-device-info"; import * as RNIap from "react-native-iap"; -//@ts-ignore -import { enabled } from "react-native-privacy-snapshot"; import ScreenGuardModule from "react-native-screenguard"; import { DatabaseLogger, db } from "../../common/database"; import filesystem from "../../common/filesystem"; @@ -206,15 +204,15 @@ export const settingsGroups: SettingSection[] = [ return status === SubscriptionStatus.TRIAL ? strings.trialOnGoing(trialEndDate) : status === SubscriptionStatus.ACTIVE - ? strings.subRenewOn(expiryDate) - : status === SubscriptionStatus.CANCELED || - status === SubscriptionStatus.PAUSED - ? strings.subEndsOn(expiryDate) - : status === SubscriptionStatus.EXPIRED - ? subscriptionDaysLeft.time < -3 - ? strings.subEnded() - : strings.accountDowngradedIn(3) - : strings.neverHesitate(); + ? strings.subRenewOn(expiryDate) + : status === SubscriptionStatus.CANCELED || + status === SubscriptionStatus.PAUSED + ? strings.subEndsOn(expiryDate) + : status === SubscriptionStatus.EXPIRED + ? subscriptionDaysLeft.time < -3 + ? strings.subEnded() + : strings.accountDowngradedIn(3) + : strings.neverHesitate(); } return strings.neverHesitate(); @@ -1054,19 +1052,7 @@ export const settingsGroups: SettingSection[] = [ description: strings.privacyModeDesc(), modifer: () => { const settings = SettingsService.get(); - if (Platform.OS === "ios") { - enabled(!settings.privacyScreen); - if (settings.privacyScreen) { - ScreenGuardModule.unregister(); - } else { - ScreenGuardModule.register({ - backgroundColor: "#000000" - }); - } - } else { - NotesnookModule.setSecureMode(!settings.privacyScreen); - } - + SettingsService.setPrivacyScreen(!settings.privacyScreen); SettingsService.set({ privacyScreen: !settings.privacyScreen }); }, property: "privacyScreen" @@ -1087,11 +1073,13 @@ export const settingsGroups: SettingSection[] = [ type: "switch", property: "appLockEnabled", featureId: "appLock", - onChange: () => { - SettingsService.set({ - privacyScreen: true - }); - SettingsService.setPrivacyScreen(SettingsService.get()); + onChange: (property) => { + if (property) { + SettingsService.set({ + privacyScreen: true + }); + SettingsService.setPrivacyScreen(true); + } }, onVerify: async () => { const verified = await verifyUserWithApplock(); diff --git a/apps/mobile/app/services/settings.ts b/apps/mobile/app/services/settings.ts index 2d242bdb4..598b38ac9 100644 --- a/apps/mobile/app/services/settings.ts +++ b/apps/mobile/app/services/settings.ts @@ -18,8 +18,6 @@ along with this program. If not, see . */ import { NativeModules, Platform } from "react-native"; -//@ts-ignore -import { enabled } from "react-native-privacy-snapshot"; import { MMKV } from "../common/database/mmkv"; import { SettingStore, @@ -126,28 +124,21 @@ function init() { updateSize(); useSettingStore.getState().setSettings({ ...settings }); migrateAppLock(); - setPrivacyScreen(settings); } -function setPrivacyScreen(settings: SettingStore["settings"]) { - if (settings.privacyScreen) { +function setPrivacyScreen(enabled?: boolean) { + if (enabled) { if (Platform.OS === "android") { NotesnookModule.setSecureMode(true); + ScreenGuardModule.registerWithoutEffect(); } else { - enabled(true); - if (NativeModules.ScreenGuard) { - ScreenGuardModule.register({ backgroundColor: "#000000" }); - } + ScreenGuardModule.register({ backgroundColor: "#000000" }); } } else { if (Platform.OS === "android") { NotesnookModule.setSecureMode(false); - } else { - enabled(false); - if (NativeModules.ScreenGuard) { - ScreenGuardModule.unregister(); - } } + ScreenGuardModule.unregister(); } } diff --git a/apps/mobile/package-lock.json b/apps/mobile/package-lock.json index 017f6dfa9..2433ed923 100644 --- a/apps/mobile/package-lock.json +++ b/apps/mobile/package-lock.json @@ -105,7 +105,6 @@ "react-native-notification-sounds": "0.5.5", "react-native-orientation-locker": "^1.7.0", "react-native-pdf": "^7.0.3", - "react-native-privacy-snapshot": "github:standardnotes/react-native-privacy-snapshot", "react-native-progress": "5.0.0", "react-native-qrcode-svg": "^6.0.6", "react-native-quick-sqlite": "^8.2.7", @@ -113,7 +112,7 @@ "react-native-reanimated-progress-bar": "1.0.1", "react-native-safe-area-context": "^5.6.1", "react-native-scoped-storage": "^1.9.5", - "react-native-screenguard": "1.0.0", + "react-native-screenguard": "^2.0.0-beta5", "react-native-screens": "^4.19.0", "react-native-securerandom": "^1.0.1", "react-native-share": "^12.0.3", @@ -15884,15 +15883,6 @@ "prop-types": "*" } }, - "node_modules/react-native-privacy-snapshot": { - "version": "1.0.0", - "resolved": "git+ssh://git@github.com/standardnotes/react-native-privacy-snapshot.git#653e904c90fc6f2b578da59138f2bfe5d7f942fe", - "license": "MIT", - "peerDependencies": { - "react": "^16.13.1", - "react-native": "^0.62.0" - } - }, "node_modules/react-native-progress": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/react-native-progress/-/react-native-progress-5.0.0.tgz", @@ -15993,16 +15983,23 @@ } }, "node_modules/react-native-screenguard": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/react-native-screenguard/-/react-native-screenguard-1.0.0.tgz", - "integrity": "sha512-fqtoJI8TxszKqrntnHW48EMb4gNVA9VCAg5UG1FcIXEyv2W70kWoMxRRFoWuCRYlBWSAWqiXO+R6Xfk/0um0cw==", + "version": "2.0.0-beta5", + "resolved": "https://registry.npmjs.org/react-native-screenguard/-/react-native-screenguard-2.0.0-beta5.tgz", + "integrity": "sha512-v8Lnv2am+COzEGKvj6J4UbpQsjHixkSqSJ+tgJtDvwck2Dil1vwOhEJBbngXYgj63x4iFlV9gE4gAOWG60avAg==", + "hasInstallScript": true, "license": "MIT", "engines": { "node": ">= 16.0.0" }, "peerDependencies": { - "react": "*", - "react-native": "*" + "expo": ">=36.0.0", + "react": ">=16.8.3", + "react-native": ">=0.59.0" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + } } }, "node_modules/react-native-screens": { diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 8219edca4..c91654cf4 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -123,7 +123,6 @@ "react-native-notification-sounds": "0.5.5", "react-native-orientation-locker": "^1.7.0", "react-native-pdf": "^7.0.3", - "react-native-privacy-snapshot": "github:standardnotes/react-native-privacy-snapshot", "react-native-progress": "5.0.0", "react-native-qrcode-svg": "^6.0.6", "react-native-quick-sqlite": "^8.2.7", @@ -131,7 +130,7 @@ "react-native-reanimated-progress-bar": "1.0.1", "react-native-safe-area-context": "^5.6.1", "react-native-scoped-storage": "^1.9.5", - "react-native-screenguard": "1.0.0", + "react-native-screenguard": "^2.0.0-beta5", "react-native-screens": "^4.19.0", "react-native-securerandom": "^1.0.1", "react-native-share": "^12.0.3", @@ -202,4 +201,4 @@ "engines": { "node": ">=20" } -} \ No newline at end of file +} diff --git a/apps/mobile/patches/react-native-screenguard+1.0.0.patch b/apps/mobile/patches/react-native-screenguard+1.0.0.patch deleted file mode 100644 index f0c9937d4..000000000 --- a/apps/mobile/patches/react-native-screenguard+1.0.0.patch +++ /dev/null @@ -1,54 +0,0 @@ -diff --git a/node_modules/react-native-screenguard/ios/ScreenGuard.mm b/node_modules/react-native-screenguard/ios/ScreenGuard.mm -index 9fa7d33..d2e6d68 100644 ---- a/node_modules/react-native-screenguard/ios/ScreenGuard.mm -+++ b/node_modules/react-native-screenguard/ios/ScreenGuard.mm -@@ -11,7 +11,7 @@ - @implementation ScreenGuard - RCT_EXPORT_MODULE(ScreenGuard) - --bool hasListeners; -+bool hasListeners_; - - UITextField *textField; - UIImageView *imageView; -@@ -22,11 +22,11 @@ @implementation ScreenGuard - } - - - (void)startObserving { -- hasListeners = YES; -+ hasListeners_ = YES; - } - - - (void)stopObserving { -- hasListeners = NO; -+ hasListeners_ = NO; - } - - - (void)secureViewWithBackgroundColor: (NSString *)color { -@@ -335,7 +335,7 @@ - (UIImage *)convertViewToImage:(UIView *)view { - queue:mainQueue - usingBlock:^(NSNotification *notification) { - -- if (hasListeners && getScreenShotPath) { -+ if (hasListeners_ && getScreenShotPath) { - UIViewController *presentedViewController = RCTPresentedViewController(); - - UIImage *image = [self convertViewToImage:presentedViewController.view.superview]; -@@ -359,7 +359,7 @@ - (UIImage *)convertViewToImage:(UIView *)view { - result = @{@"path": filePath, @"name": fileName, @"type": @"PNG"}; - } - [self emit:SCREENSHOT_EVT body: result]; -- } else if (hasListeners) { -+ } else if (hasListeners_) { - [self emit:SCREENSHOT_EVT body: nil]; - } - }]; -@@ -376,7 +376,7 @@ - (UIImage *)convertViewToImage:(UIView *)view { - queue:mainQueue - usingBlock:^(NSNotification *notification) { - -- if (hasListeners) { -+ if (hasListeners_) { - [self emit:SCREEN_RECORDING_EVT body:nil]; - } - }]; diff --git a/apps/mobile/react-native.config.js b/apps/mobile/react-native.config.js index da55fdd91..93906b0aa 100644 --- a/apps/mobile/react-native.config.js +++ b/apps/mobile/react-native.config.js @@ -11,12 +11,6 @@ config.dependencies["react-native-vector-icons"] = { } }; -config.dependencies["react-native-screenguard"] = { - platforms: { - android: null - } -}; - if (isGithubRelease) { config.dependencies["react-native-iap"] = { platforms: {