BlueWallet/screen/wallets/import.js

238 lines
7.1 KiB
JavaScript
Raw Normal View History

import { useRoute } from '@react-navigation/native';
import React, { useEffect, useState, useMemo, useCallback } from 'react';
import { Keyboard, Platform, StyleSheet, TouchableWithoutFeedback, View, ScrollView } from 'react-native';
2024-05-20 10:54:13 +01:00
import {
BlueButtonLink,
2019-08-29 00:18:32 -04:00
BlueDoneAndDismissKeyboardInputAccessory,
BlueFormLabel,
BlueFormMultiInput,
BlueSpacing20,
} from '../../BlueComponents';
2023-11-15 08:54:04 -04:00
import Button from '../../components/Button';
2024-05-20 10:54:13 +01:00
import { useTheme } from '../../components/themes';
import { requestCameraAuthorization } from '../../helpers/scan-qr';
2024-02-20 13:40:16 -04:00
import usePrivacy from '../../hooks/usePrivacy';
2024-05-20 10:54:13 +01:00
import loc from '../../loc';
import { Icon } from '@rneui/themed';
import { CommonToolTipActions } from '../../typings/CommonToolTipActions';
import { useKeyboard } from '../../hooks/useKeyboard';
import ToolTipMenu from '../../components/TooltipMenu';
import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
2019-12-26 20:21:07 -06:00
const WalletsImport = () => {
const navigation = useExtendedNavigation();
2020-07-15 13:32:59 -04:00
const { colors } = useTheme();
const route = useRoute();
const label = route?.params?.label ?? '';
const triggerImport = route?.params?.triggerImport ?? false;
2024-07-22 23:19:32 -04:00
const scannedData = route?.params?.scannedData ?? '';
const [importText, setImportText] = useState(label);
const [isToolbarVisibleForAndroid, setIsToolbarVisibleForAndroid] = useState(false);
const [, setSpeedBackdoor] = useState(0);
const [searchAccounts, setSearchAccounts] = useState(false);
const [askPassphrase, setAskPassphrase] = useState(false);
2024-02-20 13:40:16 -04:00
const { enableBlur, disableBlur } = usePrivacy();
// Styles
2020-07-15 13:32:59 -04:00
const styles = StyleSheet.create({
root: {
paddingTop: 10,
2020-07-15 13:32:59 -04:00
backgroundColor: colors.elevated,
flex: 1,
2020-07-15 13:32:59 -04:00
},
center: {
flex: 1,
marginHorizontal: 16,
2020-07-15 13:32:59 -04:00
backgroundColor: colors.elevated,
},
});
2021-11-14 10:51:39 -05:00
const onBlur = () => {
2021-11-16 11:18:58 -05:00
const valueWithSingleWhitespace = importText.replace(/^\s+|\s+$|\s+(?=\s)/g, '');
2021-11-10 15:17:43 -05:00
setImportText(valueWithSingleWhitespace);
2021-11-14 10:57:48 -05:00
return valueWithSingleWhitespace;
2021-11-10 15:17:43 -05:00
};
useKeyboard({
onKeyboardDidShow: () => {
setIsToolbarVisibleForAndroid(true);
},
onKeyboardDidHide: () => {
setIsToolbarVisibleForAndroid(false);
},
});
2019-12-26 20:21:07 -06:00
useEffect(() => {
2024-02-20 13:40:16 -04:00
enableBlur();
2020-04-27 03:11:33 -04:00
return () => {
2024-02-20 13:40:16 -04:00
disableBlur();
2020-04-27 03:11:33 -04:00
};
2024-02-20 13:40:16 -04:00
}, [disableBlur, enableBlur]);
useEffect(() => {
if (triggerImport) importButtonPressed();
// eslint-disable-next-line react-hooks/exhaustive-deps
2024-07-22 23:19:32 -04:00
}, [triggerImport]);
useEffect(() => {
if (scannedData) {
onBarScanned(scannedData);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [scannedData]);
2019-12-26 20:21:07 -06:00
const importButtonPressed = () => {
2021-11-14 10:57:48 -05:00
const textToImport = onBlur();
if (textToImport.trim().length === 0) {
2019-12-26 20:21:07 -06:00
return;
}
2021-11-14 10:57:48 -05:00
importMnemonic(textToImport);
2019-12-26 20:21:07 -06:00
};
const importMnemonic = text => {
navigation.navigate('ImportWalletDiscovery', { importText: text, askPassphrase, searchAccounts });
2019-12-26 20:21:07 -06:00
};
const onBarScanned = value => {
if (value && value.data) value = value.data + ''; // no objects here, only strings
2021-11-14 10:51:39 -05:00
setImportText(value);
setTimeout(() => importMnemonic(value), 500);
2019-12-26 20:21:07 -06:00
};
2020-05-31 18:27:26 -04:00
const importScan = () => {
2023-10-17 09:35:10 -04:00
requestCameraAuthorization().then(() =>
navigation.navigate('ScanQRCodeRoot', {
screen: 'ScanQRCode',
params: {
launchedBy: route.name,
showFileImportButton: true,
},
}),
);
};
const speedBackdoorTap = () => {
setSpeedBackdoor(v => {
v += 1;
if (v < 5) return v;
2024-05-08 17:41:13 -04:00
navigation.navigate('ImportSpeed');
return 0;
});
};
const toolTipOnPressMenuItem = useCallback(
menuItem => {
if (menuItem === CommonToolTipActions.Passphrase.id) {
setAskPassphrase(!askPassphrase);
} else if (menuItem === CommonToolTipActions.SearchAccount.id) {
setSearchAccounts(!searchAccounts);
}
},
[askPassphrase, searchAccounts],
);
// ToolTipMenu actions for advanced options
const toolTipActions = useMemo(() => {
const askPassphraseAction = CommonToolTipActions.Passphrase;
askPassphraseAction.menuState = askPassphrase;
const searchAccountsAction = CommonToolTipActions.SearchAccount;
searchAccountsAction.menuState = searchAccounts;
return [askPassphraseAction, searchAccountsAction];
}, [askPassphrase, searchAccounts]);
const HeaderRight = useMemo(
() => (
<ToolTipMenu
isButton
testID="HeaderRightButton"
isMenuPrimaryAction
onPressMenuItem={toolTipOnPressMenuItem}
actions={toolTipActions}
>
<Icon size={22} name="more-horiz" type="material" color={colors.foregroundColor} />
</ToolTipMenu>
),
[toolTipOnPressMenuItem, toolTipActions, colors.foregroundColor],
);
// Adding the ToolTipMenu to the header
useEffect(() => {
navigation.setOptions({
headerRight: () => HeaderRight,
});
}, [askPassphrase, searchAccounts, colors.foregroundColor, navigation, toolTipActions, HeaderRight]);
const renderOptionsAndImportButton = (
<>
2020-04-27 03:11:33 -04:00
<BlueSpacing20 />
<View style={styles.center}>
<>
2023-11-15 08:54:04 -04:00
<Button
disabled={importText.trim().length === 0}
title={loc.wallets.import_do_import}
testID="DoImport"
onPress={importButtonPressed}
/>
<BlueSpacing20 />
<BlueButtonLink title={loc.wallets.import_scan_qr} onPress={importScan} testID="ScanImport" />
</>
2020-04-27 03:11:33 -04:00
</View>
</>
);
return (
<ScrollView
contentContainerStyle={styles.root}
automaticallyAdjustContentInsets
automaticallyAdjustsScrollIndicatorInsets
keyboardShouldPersistTaps
automaticallyAdjustKeyboardInsets
contentInsetAdjustmentBehavior="automatic"
>
<BlueSpacing20 />
<TouchableWithoutFeedback accessibilityRole="button" onPress={speedBackdoorTap} testID="SpeedBackdoor">
<BlueFormLabel>{loc.wallets.import_explanation}</BlueFormLabel>
</TouchableWithoutFeedback>
<BlueSpacing20 />
<BlueFormMultiInput
value={importText}
2021-11-14 10:51:39 -05:00
onBlur={onBlur}
onChangeText={setImportText}
testID="MnemonicInput"
inputAccessoryViewID={BlueDoneAndDismissKeyboardInputAccessory.InputAccessoryViewID}
/>
{Platform.select({ android: !isToolbarVisibleForAndroid && renderOptionsAndImportButton, default: renderOptionsAndImportButton })}
2020-04-27 03:11:33 -04:00
{Platform.select({
ios: (
<BlueDoneAndDismissKeyboardInputAccessory
onClearTapped={() => {
2021-11-14 10:51:39 -05:00
setImportText('');
2020-04-27 03:11:33 -04:00
}}
onPasteTapped={text => {
setImportText(text);
Keyboard.dismiss();
}}
/>
2020-04-27 03:11:33 -04:00
),
android: isToolbarVisibleForAndroid && (
<BlueDoneAndDismissKeyboardInputAccessory
onClearTapped={() => {
2021-11-14 10:51:39 -05:00
setImportText('');
2020-04-27 03:11:33 -04:00
Keyboard.dismiss();
}}
onPasteTapped={text => {
2021-11-14 10:51:39 -05:00
setImportText(text);
2020-04-27 03:11:33 -04:00
Keyboard.dismiss();
}}
/>
2020-04-27 03:11:33 -04:00
),
})}
</ScrollView>
2019-12-26 20:21:07 -06:00
);
};
2019-12-26 20:21:07 -06:00
export default WalletsImport;