diff --git a/ios/BlueWallet.xcodeproj/project.pbxproj b/ios/BlueWallet.xcodeproj/project.pbxproj
index e9fe1ec13..d6414a3ba 100644
--- a/ios/BlueWallet.xcodeproj/project.pbxproj
+++ b/ios/BlueWallet.xcodeproj/project.pbxproj
@@ -1640,7 +1640,7 @@
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development io.bluewallet.bluewallet";
"PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "match AppStore io.bluewallet.bluewallet catalyst";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
- SUPPORTS_MACCATALYST = YES;
+ SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "BlueWallet-Bridging-Header.h";
@@ -1695,7 +1695,7 @@
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore io.bluewallet.bluewallet";
"PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "match AppStore io.bluewallet.bluewallet catalyst";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
- SUPPORTS_MACCATALYST = YES;
+ SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "BlueWallet-Bridging-Header.h";
diff --git a/loc/en.json b/loc/en.json
index 8f5f4e703..994086bb8 100644
--- a/loc/en.json
+++ b/loc/en.json
@@ -271,6 +271,7 @@
"encrypt_tstorage": "Storage",
"encrypt_use": "Use {type}",
"encrypt_use_expl": "{type} will be used to confirm your identity before making a transaction, unlocking, exporting, or deleting a wallet. {type} will not be used to unlock encrypted storage.",
+ "biometrics_fail": "If {type} is not enabled, or fails to unlock, you can use your device passcode as an alternative.",
"general": "General",
"general_adv_mode": "Advanced Mode",
"general_adv_mode_e": "When enabled, you will see advanced options such as different wallet types, the ability to specify the LNDHub instance you wish to connect to, and custom entropy during wallet creation.",
diff --git a/screen/settings/encryptStorage.js b/screen/settings/encryptStorage.js
index 8754f9949..b71277a34 100644
--- a/screen/settings/encryptStorage.js
+++ b/screen/settings/encryptStorage.js
@@ -1,8 +1,8 @@
import React, { useEffect, useState, useCallback, useContext } from 'react';
-import { View, ScrollView, Alert, TouchableOpacity, TouchableWithoutFeedback, Text, StyleSheet } from 'react-native';
+import { View, ScrollView, Alert, TouchableOpacity, TouchableWithoutFeedback, Text, StyleSheet, Platform } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import navigationStyle from '../../components/navigationStyle';
-import { BlueLoading, BlueSpacing20, BlueCard, BlueText } from '../../BlueComponents';
+import { BlueSpacing20, BlueCard, BlueText } from '../../BlueComponents';
import Biometric from '../../class/biometrics';
import loc from '../../loc';
import { BlueStorageContext } from '../../blue_modules/storage-context';
@@ -14,11 +14,11 @@ const prompt = require('../../helpers/prompt');
const EncryptStorage = () => {
const { isStorageEncrypted, encryptStorage, decryptStorage, saveToDisk } = useContext(BlueStorageContext);
- const [isLoading, setIsLoading] = useState(true);
const [biometrics, setBiometrics] = useState({ isDeviceBiometricCapable: false, isBiometricsEnabled: false, biometricsType: '' });
const [storageIsEncryptedSwitchEnabled, setStorageIsEncryptedSwitchEnabled] = useState(false);
const { navigate, popToTop } = useNavigation();
const { colors } = useTheme();
+ const [isLoading, setIsLoading] = useState({ encryptStorage: false, biometrics: false });
const styleHooks = StyleSheet.create({
root: {
backgroundColor: colors.background,
@@ -35,7 +35,6 @@ const EncryptStorage = () => {
const isStorageEncryptedSwitchEnabled = await isStorageEncrypted();
setStorageIsEncryptedSwitchEnabled(isStorageEncryptedSwitchEnabled);
setBiometrics({ isBiometricsEnabled, isDeviceBiometricCapable, biometricsType });
- setIsLoading(false);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
@@ -63,26 +62,26 @@ const EncryptStorage = () => {
};
const onEncryptStorageSwitch = async value => {
- setIsLoading(true);
+ setIsLoading(prev => ({ ...prev, encryptStorage: true }));
if (value === true) {
let p1 = await prompt(loc.settings.password, loc.settings.password_explain).catch(() => {
- setIsLoading(false);
+ setIsLoading(prev => ({ ...prev, encryptStorage: false }));
p1 = undefined;
});
if (!p1) {
- setIsLoading(false);
+ setIsLoading(prev => ({ ...prev, encryptStorage: false }));
return;
}
const p2 = await prompt(loc.settings.password, loc.settings.retype_password).catch(() => {
- setIsLoading(false);
+ setIsLoading(prev => ({ ...prev, encryptStorage: false }));
});
if (p1 === p2) {
await encryptStorage(p1);
- setIsLoading(false);
setStorageIsEncryptedSwitchEnabled(await isStorageEncrypted());
saveToDisk();
+ setIsLoading(prev => ({ ...prev, encryptStorage: false }));
} else {
- setIsLoading(false);
+ setIsLoading(prev => ({ ...prev, encryptStorage: false }));
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
presentAlert({ message: loc.settings.passwords_do_not_match });
}
@@ -94,7 +93,7 @@ const EncryptStorage = () => {
{
text: loc._.cancel,
style: 'cancel',
- onPress: () => setIsLoading(false),
+ onPress: () => setIsLoading(prev => ({ ...prev, encryptStorage: false })),
},
{
text: loc._.ok,
@@ -108,6 +107,7 @@ const EncryptStorage = () => {
};
const onUseBiometricSwitch = async value => {
+ setIsLoading(prev => ({ ...prev, biometrics: true }));
const isBiometricsEnabled = {
isDeviceBiometricCapable: biometrics.isDeviceBiometricCapable,
isBiometricsEnabled: biometrics.isBiometricsEnabled,
@@ -118,18 +118,35 @@ const EncryptStorage = () => {
await Biometric.setBiometricUseEnabled(value);
setBiometrics(isBiometricsEnabled);
}
+ setIsLoading(prev => ({ ...prev, biometrics: false }));
};
const navigateToPlausibleDeniability = () => {
navigate('PlausibleDeniability');
};
- return isLoading ? (
-
-
-
- ) : (
-
+ const renderPasscodeExplanation = () => {
+ let isCapable = true;
+ if (Platform.OS === 'android') {
+ if (Platform.Version < 30) {
+ isCapable = false;
+ }
+ }
+ return isCapable ? (
+ <>
+
+ {loc.formatString(loc.settings.biometrics_fail, { type: biometrics.biometricsType })}
+ >
+ ) : null;
+ };
+
+ return (
+
{biometrics.isDeviceBiometricCapable && (
<>
@@ -139,10 +156,17 @@ const EncryptStorage = () => {
{loc.formatString(loc.settings.encrypt_use_expl, { type: biometrics.biometricsType })}
+ {renderPasscodeExplanation()}
>
@@ -151,11 +175,17 @@ const EncryptStorage = () => {
{loc.settings.encrypt_tstorage}
{storageIsEncryptedSwitchEnabled && (
{
};
const styles = StyleSheet.create({
- root: {
- flex: 1,
- },
- paddingTop: { paddingTop: 19 },
+ paddingTop: { paddingTop: 36 },
headerText: {
fontWeight: 'bold',
fontSize: 30,
marginLeft: 17,
},
+ rowItemContainerStyle: {
+ minHeight: 60,
+ },
});
export default EncryptStorage;