diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 7f0afb58f..e132e6270 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -23,7 +23,7 @@
-
+
-
-
+
+
@@ -95,11 +95,23 @@
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:windowSoftInputMode="adjustResize"
android:exported="true">
+
+
+
+
+
+
+
+
+
+
+
+
@@ -111,7 +123,16 @@
+
+
+
+
+
+
+
+
+
@@ -119,7 +140,7 @@
android:mimeType="application/octet-stream"
android:pathPattern=".*\\.psbt" />
-
+
@@ -142,4 +163,4 @@
-
+
\ No newline at end of file
diff --git a/blue_modules/notifications.js b/blue_modules/notifications.js
index 3fbb66c96..e9618d776 100644
--- a/blue_modules/notifications.js
+++ b/blue_modules/notifications.js
@@ -147,7 +147,7 @@ function Notifications(props) {
ActionSheet.showActionSheetWithOptions(
{
title: loc.settings.notifications,
- message: loc.notifications.would_you_like_to_receive_notifications,
+ message: `${loc.notifications.would_you_like_to_receive_notifications}\n${loc.settings.push_notifications_explanation}`,
options,
cancelButtonIndex: 0, // Assuming 'no and don't ask' is still treated as the cancel action
anchor: anchor ? findNodeHandle(anchor.current) : undefined,
diff --git a/ios/BlueWallet/Info.plist b/ios/BlueWallet/Info.plist
index d813525db..53b493a5e 100644
--- a/ios/BlueWallet/Info.plist
+++ b/ios/BlueWallet/Info.plist
@@ -2,369 +2,322 @@
- LSMinimumSystemVersion
- 11
- BGTaskSchedulerPermittedIdentifiers
-
- io.bluewallet.bluewallet.fetchTxsForWallet
-
- CADisableMinimumFrameDurationOnPhone
-
- CFBundleDevelopmentRegion
- en
- CFBundleDisplayName
- BlueWallet
- CFBundleDocumentTypes
-
-
- CFBundleTypeIconFiles
-
- CFBundleTypeName
- PSBT
- CFBundleTypeRole
- Editor
- LSHandlerRank
- Owner
- LSItemContentTypes
-
- io.bluewallet.psbt
-
-
-
- CFBundleTypeIconFiles
-
- CFBundleTypeName
- TXN
- CFBundleTypeRole
- Editor
- LSHandlerRank
- Owner
- LSItemContentTypes
-
- io.bluewallet.psbt.txn
-
-
-
- CFBundleTypeIconFiles
-
- CFBundleTypeName
- ELECTRUMBACKUP
- CFBundleTypeRole
- Editor
- LSHandlerRank
- Owner
- LSItemContentTypes
-
- io.bluewallet.backup
-
-
-
- CFBundleTypeIconFiles
-
- CFBundleTypeName
- BW COSIGNER
- CFBundleTypeRole
- Editor
- LSHandlerRank
- Owner
- LSItemContentTypes
-
- io.bluewallet.bwcosigner
-
-
-
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- $(PRODUCT_NAME)
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- $(MARKETING_VERSION)
- CFBundleSignature
- ????
- CFBundleURLTypes
-
-
- CFBundleTypeRole
- Editor
- CFBundleURLSchemes
-
- bitcoin
- lightning
- bluewallet
- lapp
- blue
-
-
-
- CFBundleVersion
- $(CURRENT_PROJECT_VERSION)
- ITSAppUsesNonExemptEncryption
-
- LSApplicationCategoryType
- public.app-category.finance
- LSApplicationQueriesSchemes
-
- https
- http
-
- LSRequiresIPhoneOS
-
- LSSupportsOpeningDocumentsInPlace
-
- NSAppTransportSecurity
-
- NSAllowsArbitraryLoads
-
- NSAllowsLocalNetworking
-
- NSExceptionDomains
-
- localhost
-
- NSExceptionAllowsInsecureHTTPLoads
-
-
- onion
-
- NSExceptionAllowsInsecureHTTPLoads
-
- NSIncludesSubdomains
-
-
- tailscale.net
-
- NSExceptionAllowsInsecureHTTPLoads
-
- NSIncludesSubdomains
-
-
- ts.net
-
- NSExceptionAllowsInsecureHTTPLoads
-
- NSIncludesSubdomains
-
-
-
-
- NSCameraUsageDescription
- In order to quickly scan the recipient's address, we need your permission to use the camera to scan their QR Code.
- NSFaceIDUsageDescription
- In order to use FaceID please confirm your permission.
- NSPhotoLibraryAddUsageDescription
- Your authorization is required to save this image.
- NSPhotoLibraryUsageDescription
- In order to import an image for scanning, we need your permission to access your photo library.
- NSUserActivityTypes
-
- io.bluewallet.bluewallet.receiveonchain
- io.bluewallet.bluewallet.xpub
-
- UIAppFonts
-
- Entypo.ttf
- FontAwesome.ttf
- FontAwesome5_Brands.ttf
- FontAwesome5_Regular.ttf
- FontAwesome5_Solid.ttf
- Ionicons.ttf
- MaterialIcons.ttf
- Octicons.ttf
-
- UIBackgroundModes
-
- fetch
- processing
- remote-notification
-
- UIFileSharingEnabled
-
- UILaunchStoryboardName
- LaunchScreen
- UIRequiredDeviceCapabilities
-
- arm64
-
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
-
- UISupportedInterfaceOrientations~ipad
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
- UIInterfaceOrientationPortraitUpsideDown
-
- UIViewControllerBasedStatusBarAppearance
-
- UTExportedTypeDeclarations
-
-
- UTTypeConformsTo
-
- public.data
-
- UTTypeDescription
- Partially Signed Bitcoin Transaction
- UTTypeIconFiles
-
- UTTypeIdentifier
- io.bluewallet.psbt
- UTTypeTagSpecification
-
- public.filename-extension
-
- psbt
-
-
-
-
- UTTypeDescription
- BW COSIGNER
- UTTypeIconFiles
-
- UTTypeIdentifier
- io.bluewallet.bwcosigner
- UTTypeTagSpecification
-
- public.filename-extension
-
- bwcosigner
-
-
-
-
- UTTypeConformsTo
-
- public.data
-
- UTTypeDescription
- Bitcoin Transaction
- UTTypeIconFiles
-
- UTTypeIdentifier
- io.bluewallet.psbt.txn
- UTTypeTagSpecification
-
- public.filename-extension
-
- txn
-
-
-
-
- UTImportedTypeDeclarations
-
-
- UTTypeConformsTo
-
- public.text
-
- UTTypeDescription
- JSON File
- UTTypeIconFiles
-
- UTTypeTagSpecification
-
- public.filename-extension
-
- json
-
- public.mime-type
-
- application/json
-
-
-
-
- UTTypeConformsTo
-
- public.data
-
- UTTypeDescription
- Partially Signed Bitcoin Transaction
- UTTypeIconFiles
-
- UTTypeIdentifier
- io.bluewallet.psbt
- UTTypeTagSpecification
-
- public.filename-extension
-
- psbt
-
-
-
-
- UTTypeConformsTo
-
- public.data
-
- UTTypeDescription
- Bitcoin Transaction
- UTTypeIconFiles
-
- UTTypeIdentifier
- io.bluewallet.psbt.txn
- UTTypeTagSpecification
-
- public.filename-extension
-
- txn
-
-
-
-
- UTTypeConformsTo
-
- public.data
-
- UTTypeDescription
- Electrum Backup
- UTTypeIconFiles
-
- UTTypeIdentifier
- io.bluewallet.backup
- UTTypeTagSpecification
-
- public.filename-extension
-
- backup
-
-
-
-
- UTTypeDescription
- BW COSIGNER
- UTTypeIconFiles
-
- UTTypeIdentifier
- io.bluewallet.bwcosigner
- UTTypeTagSpecification
-
- public.filename-extension
-
- bwcosigner
-
-
-
-
- bugsnag
-
- apiKey
- 17ba9059f676f1cc4f45d98182388b01
-
- FIREBASE_ANALYTICS_COLLECTION_ENABLED
-
-FIREBASE_MESSAGING_AUTO_INIT_ENABLED
-
+ LSMinimumSystemVersion
+ 11
+ BGTaskSchedulerPermittedIdentifiers
+
+ io.bluewallet.bluewallet.fetchTxsForWallet
+
+ CADisableMinimumFrameDurationOnPhone
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleDisplayName
+ BlueWallet
+ CFBundleDocumentTypes
+
+
+
+ CFBundleTypeIconFiles
+
+ CFBundleTypeName
+ PSBT
+ CFBundleTypeRole
+ Editor
+ LSHandlerRank
+ Owner
+ LSItemContentTypes
+
+ io.bluewallet.psbt
+
+
+
+
+ CFBundleTypeIconFiles
+
+ CFBundleTypeName
+ TXN
+ CFBundleTypeRole
+ Editor
+ LSHandlerRank
+ Owner
+ LSItemContentTypes
+
+ io.bluewallet.psbt.txn
+
+
+
+
+ CFBundleTypeIconFiles
+
+ CFBundleTypeName
+ ELECTRUMBACKUP
+ CFBundleTypeRole
+ Editor
+ LSHandlerRank
+ Owner
+ LSItemContentTypes
+
+ io.bluewallet.backup
+
+
+
+
+ CFBundleTypeIconFiles
+
+ CFBundleTypeName
+ BW COSIGNER
+ CFBundleTypeRole
+ Editor
+ LSHandlerRank
+ Owner
+ LSItemContentTypes
+
+ io.bluewallet.bwcosigner
+
+
+
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(MARKETING_VERSION)
+ CFBundleSignature
+ ????
+ CFBundleURLTypes
+
+
+ CFBundleTypeRole
+ Editor
+ CFBundleURLSchemes
+
+ bitcoin
+ lightning
+ bluewallet
+ lapp
+ blue
+
+
+
+ CFBundleVersion
+ $(CURRENT_PROJECT_VERSION)
+ ITSAppUsesNonExemptEncryption
+
+ LSApplicationCategoryType
+ public.app-category.finance
+ LSApplicationQueriesSchemes
+
+ https
+ http
+
+ LSRequiresIPhoneOS
+
+ LSSupportsOpeningDocumentsInPlace
+
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+ NSAllowsLocalNetworking
+
+ NSExceptionDomains
+
+ localhost
+
+ NSExceptionAllowsInsecureHTTPLoads
+
+
+ onion
+
+ NSExceptionAllowsInsecureHTTPLoads
+
+ NSIncludesSubdomains
+
+
+ tailscale.net
+
+ NSExceptionAllowsInsecureHTTPLoads
+
+ NSIncludesSubdomains
+
+
+ ts.net
+
+ NSExceptionAllowsInsecureHTTPLoads
+
+ NSIncludesSubdomains
+
+
+
+
+ NSCameraUsageDescription
+ In order to quickly scan the recipient's address, we need your permission to use the camera to scan their QR Code.
+ NSFaceIDUsageDescription
+ In order to use FaceID please confirm your permission.
+ NSPhotoLibraryAddUsageDescription
+ Your authorization is required to save this image.
+ NSPhotoLibraryUsageDescription
+ In order to import an image for scanning, we need your permission to access your photo library.
+ NSUserActivityTypes
+
+ io.bluewallet.bluewallet.receiveonchain
+ io.bluewallet.bluewallet.xpub
+
+ UIAppFonts
+
+ Entypo.ttf
+ FontAwesome.ttf
+ FontAwesome5_Brands.ttf
+ FontAwesome5_Regular.ttf
+ FontAwesome5_Solid.ttf
+ Ionicons.ttf
+ MaterialIcons.ttf
+ Octicons.ttf
+
+ UIBackgroundModes
+
+ fetch
+ processing
+ remote-notification
+
+ UIFileSharingEnabled
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIRequiredDeviceCapabilities
+
+ arm64
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+ UIInterfaceOrientationPortraitUpsideDown
+
+ UIViewControllerBasedStatusBarAppearance
+
+
+
+ UTExportedTypeDeclarations
+
+
+
+ UTTypeConformsTo
+
+ public.data
+
+ UTTypeDescription
+ Partially Signed Bitcoin Transaction
+ UTTypeIdentifier
+ io.bluewallet.psbt
+ UTTypeTagSpecification
+
+ public.filename-extension
+
+ psbt
+
+
+
+
+
+ UTTypeDescription
+ BW COSIGNER
+ UTTypeIdentifier
+ io.bluewallet.bwcosigner
+ UTTypeTagSpecification
+
+ public.filename-extension
+
+ bwcosigner
+
+
+
+
+
+ UTTypeConformsTo
+
+ public.data
+
+ UTTypeDescription
+ Bitcoin Transaction
+ UTTypeIdentifier
+ io.bluewallet.psbt.txn
+ UTTypeTagSpecification
+
+ public.filename-extension
+
+ txn
+
+
+
+
+
+ UTTypeConformsTo
+
+ public.data
+
+ UTTypeDescription
+ Electrum Backup
+ UTTypeIdentifier
+ io.bluewallet.backup
+ UTTypeTagSpecification
+
+ public.filename-extension
+
+ backup
+
+
+
+
+
+
+ UTImportedTypeDeclarations
+
+
+ UTTypeConformsTo
+
+ public.text
+
+ UTTypeDescription
+ JSON File
+ UTTypeIdentifier
+ public.json
+ UTTypeTagSpecification
+
+ public.filename-extension
+
+ json
+
+ public.mime-type
+
+ application/json
+
+
+
+
+
+ bugsnag
+
+ apiKey
+ 17ba9059f676f1cc4f45d98182388b01
+
+
+ FIREBASE_ANALYTICS_COLLECTION_ENABLED
+
+ FIREBASE_MESSAGING_AUTO_INIT_ENABLED
+
diff --git a/loc/de_de.json b/loc/de_de.json
index 6d050c8d5..17cb7c1ff 100644
--- a/loc/de_de.json
+++ b/loc/de_de.json
@@ -10,6 +10,7 @@
"never": "nie",
"of": "{number} von {total}",
"ok": "OK",
+ "enter_url": "URL eingeben",
"storage_is_encrypted": "Zum Entschlüsseln des Speichers das Passwort eingeben.",
"yes": "Ja",
"no": "Nein",
@@ -25,7 +26,8 @@
"pick_file": "Datei auswählen",
"enter_amount": "Betrag eingeben",
"qr_custom_input_button": "10x antippen für individuelle Eingabe",
- "unlock": "Entsperren"
+ "unlock": "Entsperren",
+ "suggested": "Vorgeschlagen"
},
"azteco": {
"codeIs": "Dein Gutscheincode lautet",
@@ -206,8 +208,10 @@
"performance_score": "Leistungskennzahl: {num}",
"run_performance_test": "Leistung testen",
"about_selftest": "Selbsttest ausführen",
+ "block_explorer_invalid_custom_url": "Ungültige URL. Geben Sie eine gültige URL ein, die mit http:// oder https:// beginnt.",
"about_selftest_electrum_disabled": "Deaktiviere den Electrum Offline-Modus, um den Selbsttest durchführen zu können.",
"about_selftest_ok": "Alle internen Tests verliefen erfolgreich. Das Wallet funktioniert gut.",
+
"about_sm_github": "GitHub",
"about_sm_discord": "Discord Server",
"about_sm_telegram": "Telegram-Channel",
@@ -259,6 +263,9 @@
"encrypt_storage_explanation_description_line1": "Die Aktivierung der Speicherverschlüsselung fügt Ihrer App ein zusätzlicher Schutz hinzu. Die Art und Weise, wie die Daten auf Ihrem Gerät gespeichert werden, macht es anderen damit schwieriger, ohne Erlaubnis darauf zuzugreifen.",
"encrypt_storage_explanation_description_line2": "Diese Verschlüsselung betrifft den Zugriff auf die im Gerät gespeicherten Schlüssel, schützt also die Wallets. Die Wallet selbst werden dabei nicht mit einem Passwort oder einem anderen zusätzlichen Schutz versehen.",
"i_understand": "Ich habe verstanden",
+ "block_explorer": "Block-Explorer",
+ "block_explorer_preferred": "Bevorzugten Block-Explorer verwenden",
+ "block_explorer_error_saving_custom": "Fehler beim Speichern des bevorzugten Block-Explorers.",
"encrypt_title": "Sicherheit",
"encrypt_tstorage": "Speicher",
"encrypt_use": "Benutze {type}",
diff --git a/loc/en.json b/loc/en.json
index 2233e3b43..d78e86602 100644
--- a/loc/en.json
+++ b/loc/en.json
@@ -301,8 +301,8 @@
"privacy_clipboard_explanation": "Provide shortcuts if an address or invoice is found in your clipboard.",
"privacy_do_not_track": "Disable Analytics",
"privacy_do_not_track_explanation": "Performance and reliability information will not be submitted for analysis.",
- "push_notifications": "Push Notifications",
"rate": "Rate",
+ "push_notifications_explanation": "By enabling notifications, your device token will be sent to the server, along with wallet addresses and transaction IDs for all wallets and transactions made after enabling notifications. The device token is used to send notifications, and the wallet information allows us to notify you about incoming Bitcoin or transaction confirmations.\n\nOnly information from after you enable notifications is transmitted—nothing from before is collected.\n\nDisabling notifications will remove all of this information from the server. Additionally, deleting a wallet from the app will also remove its associated information from the server.",
"selfTest": "Self-Test",
"save": "Save",
"saved": "Saved",
@@ -314,6 +314,7 @@
},
"notifications": {
"would_you_like_to_receive_notifications": "Would you like to receive notifications when you get incoming payments?",
+ "notifications_subtitle": "Incoming payments and transaction confirmations",
"no_and_dont_ask": "No, and do not ask me again.",
"ask_me_later": "Ask me later."
},
diff --git a/navigation/LazyLoadSettingsStack.tsx b/navigation/LazyLoadSettingsStack.tsx
index bb9781ecc..4a1652c1a 100644
--- a/navigation/LazyLoadSettingsStack.tsx
+++ b/navigation/LazyLoadSettingsStack.tsx
@@ -14,7 +14,7 @@ const DefaultView = lazy(() => import('../screen/settings/DefaultView'));
const ElectrumSettings = lazy(() => import('../screen/settings/ElectrumSettings'));
const EncryptStorage = lazy(() => import('../screen/settings/EncryptStorage'));
const LightningSettings = lazy(() => import('../screen/settings/LightningSettings'));
-const NotificationSettings = lazy(() => import('../screen/settings/notificationSettings'));
+const NotificationSettings = lazy(() => import('../screen/settings/NotificationSettings'));
const SelfTest = lazy(() => import('../screen/settings/SelfTest'));
const ReleaseNotes = lazy(() => import('../screen/settings/ReleaseNotes'));
const Tools = lazy(() => import('../screen/settings/tools'));
diff --git a/package-lock.json b/package-lock.json
index 6a14d8b47..e0062da45 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,7 +20,7 @@
"@react-native-async-storage/async-storage": "1.24.0",
"@react-native-clipboard/clipboard": "1.14.2",
"@react-native-community/push-notification-ios": "1.11.0",
- "@react-native-menu/menu": "https://github.com/BlueWallet/menu.git#8c6004b",
+ "@react-native-menu/menu": "https://github.com/BlueWallet/menu.git#a33379d",
"@react-native/gradle-plugin": "^0.75.4",
"@react-native/metro-config": "0.75.4",
"@react-navigation/drawer": "6.7.2",
@@ -89,7 +89,7 @@
"react-native-quick-actions": "0.3.13",
"react-native-randombytes": "3.6.1",
"react-native-rate": "1.2.12",
- "react-native-reanimated": "3.15.4",
+ "react-native-reanimated": "3.15.5",
"react-native-safe-area-context": "4.11.0",
"react-native-screens": "3.34.0",
"react-native-secure-key-store": "github:BlueWallet/react-native-secure-key-store#2076b4849e88aa0a78e08bfbb4ce3923e0925cbc",
@@ -5601,8 +5601,8 @@
}
},
"node_modules/@react-native-menu/menu": {
- "version": "1.1.2",
- "resolved": "git+ssh://git@github.com/BlueWallet/menu.git#8c6004bae317e00ea8f163612af96dddb9cdf7e9",
+ "version": "1.1.3",
+ "resolved": "git+ssh://git@github.com/BlueWallet/menu.git#a33379d2bf2349066488ab9726c7d52bf76c49ac",
"license": "MIT",
"peerDependencies": {
"react": "*",
@@ -20882,9 +20882,9 @@
}
},
"node_modules/react-native-reanimated": {
- "version": "3.15.4",
- "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.15.4.tgz",
- "integrity": "sha512-jcpHE+MnsvSbClhHgAFoken7SnaHrUJ5gVA8BUw8S1j6rkrw2VzRpht6cxn14NlqYx5ytjfG9IXJDOzq8tFvfw==",
+ "version": "3.15.5",
+ "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.15.5.tgz",
+ "integrity": "sha512-admqeZ0w235vQqYPy+IUgmHu5gwKi9+b7AQRV1yIK3MbAMLYx+RY+tTUtx1CNE5X+rNZ6eSQssW5z77yTwIusg==",
"license": "MIT",
"dependencies": {
"@babel/plugin-transform-arrow-functions": "^7.0.0-0",
diff --git a/package.json b/package.json
index 6851f9a72..17d13c151 100644
--- a/package.json
+++ b/package.json
@@ -84,7 +84,7 @@
"@react-native-async-storage/async-storage": "1.24.0",
"@react-native-clipboard/clipboard": "1.14.2",
"@react-native-community/push-notification-ios": "1.11.0",
- "@react-native-menu/menu": "https://github.com/BlueWallet/menu.git#8c6004b",
+ "@react-native-menu/menu": "https://github.com/BlueWallet/menu.git#a33379d",
"@react-native/gradle-plugin": "^0.75.4",
"@react-native/metro-config": "0.75.4",
"@react-navigation/drawer": "6.7.2",
@@ -153,7 +153,7 @@
"react-native-quick-actions": "0.3.13",
"react-native-randombytes": "3.6.1",
"react-native-rate": "1.2.12",
- "react-native-reanimated": "3.15.4",
+ "react-native-reanimated": "3.15.5",
"react-native-safe-area-context": "4.11.0",
"react-native-screens": "3.34.0",
"react-native-secure-key-store": "github:BlueWallet/react-native-secure-key-store#2076b4849e88aa0a78e08bfbb4ce3923e0925cbc",
diff --git a/screen/settings/NotificationSettings.tsx b/screen/settings/NotificationSettings.tsx
new file mode 100644
index 000000000..b955bdf0e
--- /dev/null
+++ b/screen/settings/NotificationSettings.tsx
@@ -0,0 +1,231 @@
+import React, { useCallback, useEffect, useState } from 'react';
+import { I18nManager, Linking, ScrollView, StyleSheet, TextInput, View, Pressable } from 'react-native';
+import { Button as ButtonRNElements } from '@rneui/themed';
+// @ts-ignore: no declaration file
+import Notifications from '../../blue_modules/notifications';
+import { BlueCard, BlueSpacing20, BlueText } from '../../BlueComponents';
+import presentAlert from '../../components/Alert';
+import { Button } from '../../components/Button';
+import CopyToClipboardButton from '../../components/CopyToClipboardButton';
+import ListItem, { PressableWrapper } from '../../components/ListItem';
+import { useTheme } from '../../components/themes';
+import loc from '../../loc';
+import { Divider } from '@rneui/base';
+
+const NotificationSettings: React.FC = () => {
+ const [isLoading, setIsLoading] = useState(true);
+ const [isNotificationsEnabled, setNotificationsEnabled] = useState(false);
+ const [tokenInfo, setTokenInfo] = useState('');
+ const [URI, setURI] = useState();
+ const [tapCount, setTapCount] = useState(0);
+ const { colors } = useTheme();
+ const stylesWithThemeHook = {
+ root: {
+ backgroundColor: colors.background,
+ },
+ scroll: {
+ backgroundColor: colors.background,
+ },
+ scrollBody: {
+ backgroundColor: colors.background,
+ },
+ uri: {
+ borderColor: colors.formBorder,
+ borderBottomColor: colors.formBorder,
+ backgroundColor: colors.inputBackgroundColor,
+ },
+ };
+
+ const handleTap = () => {
+ setTapCount(prevCount => prevCount + 1);
+ };
+
+ const onNotificationsSwitch = async (value: boolean) => {
+ try {
+ setNotificationsEnabled(value);
+ if (value) {
+ // User is enabling notifications
+ // @ts-ignore: refactor later
+ await Notifications.cleanUserOptOutFlag();
+ // @ts-ignore: refactor later
+ if (await Notifications.getPushToken()) {
+ // we already have a token, so we just need to reenable ALL level on groundcontrol:
+ // @ts-ignore: refactor later
+ await Notifications.setLevels(true);
+ } else {
+ // ok, we dont have a token. we need to try to obtain permissions, configure callbacks and save token locally:
+ // @ts-ignore: refactor later
+ await Notifications.tryToObtainPermissions();
+ }
+ } else {
+ // User is disabling notifications
+ // @ts-ignore: refactor later
+ await Notifications.setLevels(false);
+ }
+
+ // @ts-ignore: refactor later
+ setNotificationsEnabled(await Notifications.isNotificationsEnabled());
+ } catch (error) {
+ console.error(error);
+ presentAlert({ message: (error as Error).message });
+ }
+ };
+
+ useEffect(() => {
+ (async () => {
+ try {
+ // @ts-ignore: refactor later
+ setNotificationsEnabled(await Notifications.isNotificationsEnabled());
+ // @ts-ignore: refactor later
+ setURI(await Notifications.getSavedUri());
+ // @ts-ignore: refactor later
+ setTokenInfo(
+ 'token: ' +
+ // @ts-ignore: refactor later
+ JSON.stringify(await Notifications.getPushToken()) +
+ ' permissions: ' +
+ // @ts-ignore: refactor later
+ JSON.stringify(await Notifications.checkPermissions()) +
+ ' stored notifications: ' +
+ // @ts-ignore: refactor later
+ JSON.stringify(await Notifications.getStoredNotifications()),
+ );
+ } catch (e) {
+ console.error(e);
+ presentAlert({ message: (e as Error).message });
+ } finally {
+ setIsLoading(false);
+ }
+ })();
+ }, []);
+
+ const save = useCallback(async () => {
+ setIsLoading(true);
+ try {
+ if (URI) {
+ // validating only if its not empty. empty means use default
+ // @ts-ignore: refactor later
+ if (await Notifications.isGroundControlUriValid(URI)) {
+ // @ts-ignore: refactor later
+ await Notifications.saveUri(URI);
+ presentAlert({ message: loc.settings.saved });
+ } else {
+ presentAlert({ message: loc.settings.not_a_valid_uri });
+ }
+ } else {
+ // @ts-ignore: refactor later
+ await Notifications.saveUri('');
+ presentAlert({ message: loc.settings.saved });
+ }
+ } catch (error) {
+ console.warn(error);
+ }
+ setIsLoading(false);
+ }, [URI]);
+
+ return (
+
+
+
+
+
+ {loc.settings.push_notifications_explanation}
+
+
+
+ {tapCount >= 10 && (
+ <>
+
+
+ {loc.settings.groundcontrol_explanation}
+
+
+ Linking.openURL('https://github.com/BlueWallet/GroundControl')}
+ titleStyle={{ color: colors.buttonAlternativeTextColor }}
+ title="github.com/BlueWallet/GroundControl"
+ color={colors.buttonTextColor}
+ buttonStyle={styles.buttonStyle}
+ />
+
+
+
+
+
+
+
+ setTapCount(tapCount + 1)}>
+ ♪ Ground Control to Major Tom ♪
+
+ setTapCount(tapCount + 1)}>
+ ♪ Commencing countdown, engines on ♪
+
+
+
+
+
+
+
+
+
+ >
+ )}
+
+ );
+};
+
+const styles = StyleSheet.create({
+ uri: {
+ flexDirection: 'row',
+ borderWidth: 1,
+ borderBottomWidth: 0.5,
+ minHeight: 44,
+ height: 44,
+ alignItems: 'center',
+ borderRadius: 4,
+ },
+ centered: {
+ textAlign: 'center',
+ },
+ uriText: {
+ flex: 1,
+ color: '#81868e',
+ marginHorizontal: 8,
+ minHeight: 36,
+ height: 36,
+ },
+ buttonStyle: {
+ backgroundColor: 'transparent',
+ flexDirection: I18nManager.isRTL ? 'row-reverse' : 'row',
+ },
+ multilineText: {
+ textAlign: 'left',
+ lineHeight: 20,
+ paddingBottom: 10,
+ },
+});
+
+export default NotificationSettings;
diff --git a/screen/settings/notificationSettings.js b/screen/settings/notificationSettings.js
deleted file mode 100644
index 366a77c79..000000000
--- a/screen/settings/notificationSettings.js
+++ /dev/null
@@ -1,195 +0,0 @@
-import React, { useCallback, useEffect, useState } from 'react';
-import { I18nManager, Linking, ScrollView, StyleSheet, TextInput, TouchableWithoutFeedback, View } from 'react-native';
-import { Button as ButtonRNElements } from '@rneui/themed';
-
-import Notifications from '../../blue_modules/notifications';
-import { BlueCard, BlueLoading, BlueSpacing20, BlueText } from '../../BlueComponents';
-import presentAlert from '../../components/Alert';
-import { Button } from '../../components/Button';
-import CopyToClipboardButton from '../../components/CopyToClipboardButton';
-import ListItem from '../../components/ListItem';
-import { BlueCurrentTheme, useTheme } from '../../components/themes';
-import loc from '../../loc';
-
-const NotificationSettings = () => {
- const [isLoading, setIsLoading] = useState(true);
- const [isNotificationsEnabled, setNotificationsEnabled] = useState(false);
- const [isShowTokenInfo, setShowTokenInfo] = useState(0);
- const [tokenInfo, setTokenInfo] = useState('');
- const [URI, setURI] = useState();
-
- const { colors } = useTheme();
-
- const onNotificationsSwitch = async value => {
- setNotificationsEnabled(value); // so the slider is not 'jumpy'
- if (value) {
- // user is ENABLING notifications
- await Notifications.cleanUserOptOutFlag();
- if (await Notifications.getPushToken()) {
- // we already have a token, so we just need to reenable ALL level on groundcontrol:
- await Notifications.setLevels(true);
- } else {
- // ok, we dont have a token. we need to try to obtain permissions, configure callbacks and save token locally:
- await Notifications.tryToObtainPermissions();
- }
- } else {
- // user is DISABLING notifications
- await Notifications.setLevels(false);
- }
-
- setNotificationsEnabled(await Notifications.isNotificationsEnabled());
- };
-
- useEffect(() => {
- (async () => {
- try {
- setNotificationsEnabled(await Notifications.isNotificationsEnabled());
- setURI(await Notifications.getSavedUri());
- setTokenInfo(
- 'token: ' +
- JSON.stringify(await Notifications.getPushToken()) +
- ' permissions: ' +
- JSON.stringify(await Notifications.checkPermissions()) +
- ' stored notifications: ' +
- JSON.stringify(await Notifications.getStoredNotifications()),
- );
- } catch (e) {
- console.debug(e);
- presentAlert({ message: e.message });
- } finally {
- setIsLoading(false);
- }
- })();
- }, []);
-
- const stylesWithThemeHook = {
- root: {
- ...styles.root,
- backgroundColor: colors.background,
- },
- scroll: {
- ...styles.scroll,
- backgroundColor: colors.background,
- },
- scrollBody: {
- ...styles.scrollBody,
- backgroundColor: colors.background,
- },
- };
-
- const save = useCallback(async () => {
- setIsLoading(true);
- try {
- if (URI) {
- // validating only if its not empty. empty means use default
- if (await Notifications.isGroundControlUriValid(URI)) {
- await Notifications.saveUri(URI);
- presentAlert({ message: loc.settings.saved });
- } else {
- presentAlert({ message: loc.settings.not_a_valid_uri });
- }
- } else {
- await Notifications.saveUri('');
- presentAlert({ message: loc.settings.saved });
- }
- } catch (error) {
- console.warn(error);
- }
- setIsLoading(false);
- }, [URI]);
-
- return isLoading ? (
-
- ) : (
-
-
-
-
- Linking.openURL('https://github.com/BlueWallet/GroundControl')}
- titleStyle={{ color: colors.buttonAlternativeTextColor }}
- title="github.com/BlueWallet/GroundControl"
- color={colors.buttonTextColor}
- buttonStyle={styles.buttonStyle}
- />
-
-
-
-
-
-
-
- setShowTokenInfo(isShowTokenInfo + 1)}>
- ♪ Ground Control to Major Tom ♪
-
- setShowTokenInfo(isShowTokenInfo + 1)}>
- ♪ Commencing countdown, engines on ♪
-
-
- {isShowTokenInfo >= 9 && (
-
-
-
- )}
-
-
-
-
-
- );
-};
-
-const styles = StyleSheet.create({
- root: {
- flex: 1,
- },
- uri: {
- flexDirection: 'row',
- borderColor: BlueCurrentTheme.colors.formBorder,
- borderBottomColor: BlueCurrentTheme.colors.formBorder,
- borderWidth: 1,
- borderBottomWidth: 0.5,
- backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
- minHeight: 44,
- height: 44,
- alignItems: 'center',
- borderRadius: 4,
- },
- centered: {
- textAlign: 'center',
- },
- uriText: {
- flex: 1,
- color: '#81868e',
- marginHorizontal: 8,
- minHeight: 36,
- height: 36,
- },
- buttonStyle: {
- backgroundColor: 'transparent',
- flexDirection: I18nManager.isRTL ? 'row-reverse' : 'row',
- },
-});
-
-export default NotificationSettings;