FIX: memory consumption bug by RN component

This commit is contained in:
Marcos Rodriguez Velez 2024-08-20 15:22:11 -04:00
parent 926e990046
commit 044f3089f8
9 changed files with 438 additions and 462 deletions

View file

@ -7,7 +7,6 @@ import {
I18nManager,
InputAccessoryView,
Keyboard,
KeyboardAvoidingView,
Platform,
StyleSheet,
TextInput,
@ -188,7 +187,7 @@ export const BlueDoneAndDismissKeyboardInputAccessory = props => {
if (Platform.OS === 'ios') {
return <InputAccessoryView nativeID={BlueDoneAndDismissKeyboardInputAccessory.InputAccessoryViewID}>{inputView}</InputAccessoryView>;
} else {
return <KeyboardAvoidingView>{inputView}</KeyboardAvoidingView>;
return inputView;
}
};

View file

@ -1,17 +1,6 @@
import { useFocusEffect, useNavigation, useRoute } from '@react-navigation/native';
import React, { useCallback, useEffect, useState } from 'react';
import {
ActivityIndicator,
I18nManager,
Keyboard,
KeyboardAvoidingView,
Platform,
ScrollView,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import { ActivityIndicator, I18nManager, Keyboard, Platform, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { Icon } from '@rneui/themed';
import { btcToSatoshi, fiatToBTC } from '../../blue_modules/currency';
@ -302,62 +291,67 @@ const ScanLndInvoice = () => {
return (
<SafeArea style={stylesHook.root}>
<View style={[styles.root, stylesHook.root]}>
<ScrollView contentContainerStyle={styles.scroll} keyboardShouldPersistTaps="handled">
<KeyboardAvoidingView enabled behavior="position" keyboardVerticalOffset={20}>
<View style={styles.scrollMargin}>
<AmountInput
pointerEvents={isAmountInitiallyEmpty ? 'auto' : 'none'}
isLoading={isLoading}
amount={amount}
onAmountUnitChange={setUnit}
onChangeText={setAmount}
disabled={!decoded || isLoading || decoded.num_satoshis > 0}
unit={unit}
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
/>
</View>
<ScrollView
contentContainerStyle={styles.scroll}
keyboardShouldPersistTaps="handled"
automaticallyAdjustContentInsets
automaticallyAdjustKeyboardInsets
contentInsetAdjustmentBehavior="automatic"
>
<View style={styles.scrollMargin}>
<AmountInput
pointerEvents={isAmountInitiallyEmpty ? 'auto' : 'none'}
isLoading={isLoading}
amount={amount}
onAmountUnitChange={setUnit}
onChangeText={setAmount}
disabled={!decoded || isLoading || decoded.num_satoshis > 0}
unit={unit}
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
/>
</View>
<BlueCard>
<AddressInput
onChangeText={text => {
text = text.trim();
setDestination(text);
}}
onBarScanned={data => processTextForInvoice(data.data)}
address={destination}
isLoading={isLoading}
placeholder={loc.lnd.placeholder}
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
launchedBy={name}
onBlur={onBlur}
keyboardType="email-address"
/>
<View style={styles.description}>
<Text numberOfLines={0} style={styles.descriptionText}>
{decoded !== undefined ? decoded.description : ''}
</Text>
<BlueCard>
<AddressInput
onChangeText={text => {
text = text.trim();
setDestination(text);
}}
onBarScanned={data => processTextForInvoice(data.data)}
address={destination}
isLoading={isLoading}
placeholder={loc.lnd.placeholder}
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
launchedBy={name}
onBlur={onBlur}
keyboardType="email-address"
/>
<View style={styles.description}>
<Text numberOfLines={0} style={styles.descriptionText}>
{decoded !== undefined ? decoded.description : ''}
</Text>
</View>
{expiresIn !== undefined && (
<View>
<Text style={styles.expiresIn}>{expiresIn}</Text>
{decoded && decoded.num_satoshis > 0 && (
<Text style={styles.expiresIn}>{loc.formatString(loc.lnd.potentialFee, { fee: getFees() })}</Text>
)}
</View>
{expiresIn !== undefined && (
)}
<BlueCard>
{isLoading ? (
<View>
<Text style={styles.expiresIn}>{expiresIn}</Text>
{decoded && decoded.num_satoshis > 0 && (
<Text style={styles.expiresIn}>{loc.formatString(loc.lnd.potentialFee, { fee: getFees() })}</Text>
)}
<ActivityIndicator />
</View>
) : (
<View>
<Button title={loc.lnd.payButton} onPress={pay} disabled={shouldDisablePayButton()} />
</View>
)}
<BlueCard>
{isLoading ? (
<View>
<ActivityIndicator />
</View>
) : (
<View>
<Button title={loc.lnd.payButton} onPress={pay} disabled={shouldDisablePayButton()} />
</View>
)}
</BlueCard>
</BlueCard>
</KeyboardAvoidingView>
</BlueCard>
{renderWalletSelectionButton()}
</ScrollView>
</View>

View file

@ -1,10 +1,9 @@
import React, { useState, useEffect } from 'react';
import { useRoute, RouteProp } from '@react-navigation/native';
import * as bitcoin from 'bitcoinjs-lib';
import { ActivityIndicator, Keyboard, KeyboardAvoidingView, Linking, Platform, StyleSheet, TextInput, View } from 'react-native';
import { ActivityIndicator, Keyboard, Linking, StyleSheet, TextInput, View } from 'react-native';
import * as BlueElectrum from '../../blue_modules/BlueElectrum';
import { isTablet } from '../../blue_modules/environment';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
import Notifications from '../../blue_modules/notifications';
import {
@ -125,44 +124,42 @@ const Broadcast: React.FC = () => {
return (
<SafeArea>
<KeyboardAvoidingView enabled={!isTablet} behavior={Platform.OS === 'ios' ? 'position' : undefined}>
<View style={styles.wrapper} testID="BroadcastView">
{BROADCAST_RESULT.success !== broadcastResult && (
<BlueCard style={styles.mainCard}>
<View style={styles.topFormRow}>
<BlueFormLabel>{status}</BlueFormLabel>
{BROADCAST_RESULT.pending === broadcastResult && <ActivityIndicator size="small" />}
</View>
<View style={styles.wrapper} testID="BroadcastView">
{BROADCAST_RESULT.success !== broadcastResult && (
<BlueCard style={styles.mainCard}>
<View style={styles.topFormRow}>
<BlueFormLabel>{status}</BlueFormLabel>
{BROADCAST_RESULT.pending === broadcastResult && <ActivityIndicator size="small" />}
</View>
<View style={[styles.input, stylesHooks.input]}>
<TextInput
style={styles.text}
multiline
editable
placeholderTextColor="#81868e"
value={txHex}
onChangeText={handleUpdateTxHex}
onSubmitEditing={Keyboard.dismiss}
testID="TxHex"
/>
</View>
<BlueSpacing20 />
<Button title={loc.multisig.scan_or_open_file} onPress={handleQRScan} />
<BlueSpacing20 />
<Button
title={loc.send.broadcastButton}
onPress={handleBroadcast}
disabled={broadcastResult === BROADCAST_RESULT.pending || txHex?.length === 0 || txHex === undefined}
testID="BroadcastButton"
<View style={[styles.input, stylesHooks.input]}>
<TextInput
style={styles.text}
multiline
editable
placeholderTextColor="#81868e"
value={txHex}
onChangeText={handleUpdateTxHex}
onSubmitEditing={Keyboard.dismiss}
testID="TxHex"
/>
<BlueSpacing20 />
</BlueCard>
)}
{BROADCAST_RESULT.success === broadcastResult && tx && <SuccessScreen tx={tx} />}
</View>
</KeyboardAvoidingView>
</View>
<BlueSpacing20 />
<Button title={loc.multisig.scan_or_open_file} onPress={handleQRScan} />
<BlueSpacing20 />
<Button
title={loc.send.broadcastButton}
onPress={handleBroadcast}
disabled={broadcastResult === BROADCAST_RESULT.pending || txHex?.length === 0 || txHex === undefined}
testID="BroadcastButton"
/>
<BlueSpacing20 />
</BlueCard>
)}
{BROADCAST_RESULT.success === broadcastResult && tx && <SuccessScreen tx={tx} />}
</View>
</SafeArea>
);
};

View file

@ -10,7 +10,6 @@ import {
FlatList,
I18nManager,
Keyboard,
KeyboardAvoidingView,
LayoutAnimation,
NativeScrollEvent,
NativeSyntheticEvent,
@ -50,7 +49,6 @@ import { TOptions } from 'bip21';
import assert from 'assert';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { SendDetailsStackParamList } from '../../navigation/SendDetailsStackParamList';
import { isTablet } from '../../blue_modules/environment';
import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
import { ContactList } from '../../class/contact-list';
import { useStorage } from '../../hooks/context/useStorage';
@ -1324,66 +1322,65 @@ const SendDetails = () => {
return (
<View style={[styles.root, stylesHook.root]} onLayout={e => setWidth(e.nativeEvent.layout.width)}>
<View>
<KeyboardAvoidingView enabled={!isTablet} behavior="position">
<FlatList
keyboardShouldPersistTaps="always"
scrollEnabled={addresses.length > 1}
data={addresses}
renderItem={renderBitcoinTransactionInfoFields}
horizontal
ref={scrollView}
pagingEnabled
removeClippedSubviews={false}
onMomentumScrollBegin={Keyboard.dismiss}
onScroll={handleRecipientsScroll}
scrollEventThrottle={16}
scrollIndicatorInsets={styles.scrollViewIndicator}
contentContainerStyle={styles.scrollViewContent}
getItemLayout={getItemLayout}
<FlatList
keyboardShouldPersistTaps="always"
scrollEnabled={addresses.length > 1}
data={addresses}
renderItem={renderBitcoinTransactionInfoFields}
horizontal
ref={scrollView}
automaticallyAdjustKeyboardInsets
pagingEnabled
removeClippedSubviews={false}
onMomentumScrollBegin={Keyboard.dismiss}
onScroll={handleRecipientsScroll}
scrollEventThrottle={16}
scrollIndicatorInsets={styles.scrollViewIndicator}
contentContainerStyle={styles.scrollViewContent}
getItemLayout={getItemLayout}
/>
<View style={[styles.memo, stylesHook.memo]}>
<TextInput
onChangeText={setTransactionMemo}
placeholder={loc.send.details_note_placeholder}
placeholderTextColor="#81868e"
value={transactionMemo}
numberOfLines={1}
style={styles.memoText}
editable={!isLoading}
onSubmitEditing={Keyboard.dismiss}
/* @ts-ignore marcos fixme */
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
/>
<View style={[styles.memo, stylesHook.memo]}>
<TextInput
onChangeText={setTransactionMemo}
placeholder={loc.send.details_note_placeholder}
placeholderTextColor="#81868e"
value={transactionMemo}
numberOfLines={1}
style={styles.memoText}
editable={!isLoading}
onSubmitEditing={Keyboard.dismiss}
/* @ts-ignore marcos fixme */
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
/>
</View>
<TouchableOpacity
testID="chooseFee"
accessibilityRole="button"
onPress={() => feeModalRef.current?.present()}
disabled={isLoading}
style={styles.fee}
>
<Text style={[styles.feeLabel, stylesHook.feeLabel]}>{loc.send.create_fee}</Text>
</View>
<TouchableOpacity
testID="chooseFee"
accessibilityRole="button"
onPress={() => feeModalRef.current?.present()}
disabled={isLoading}
style={styles.fee}
>
<Text style={[styles.feeLabel, stylesHook.feeLabel]}>{loc.send.create_fee}</Text>
{networkTransactionFeesIsLoading ? (
<ActivityIndicator />
) : (
<View style={[styles.feeRow, stylesHook.feeRow]}>
<Text style={stylesHook.feeValue}>
{feePrecalc.current ? formatFee(feePrecalc.current) : feeRate + ' ' + loc.units.sat_vbyte}
</Text>
</View>
)}
</TouchableOpacity>
{renderCreateButton()}
<SelectFeeModal
ref={feeModalRef}
networkTransactionFees={networkTransactionFees}
feePrecalc={feePrecalc}
feeRate={feeRate}
setCustomFee={setCustomFee}
setFeePrecalc={setFeePrecalc}
/>
</KeyboardAvoidingView>
{networkTransactionFeesIsLoading ? (
<ActivityIndicator />
) : (
<View style={[styles.feeRow, stylesHook.feeRow]}>
<Text style={stylesHook.feeValue}>
{feePrecalc.current ? formatFee(feePrecalc.current) : feeRate + ' ' + loc.units.sat_vbyte}
</Text>
</View>
)}
</TouchableOpacity>
{renderCreateButton()}
<SelectFeeModal
ref={feeModalRef}
networkTransactionFees={networkTransactionFees}
feePrecalc={feePrecalc}
feeRate={feeRate}
setCustomFee={setCustomFee}
setFeePrecalc={setFeePrecalc}
/>
</View>
<BlueDismissKeyboardInputAccessory />
{Platform.select({

View file

@ -4,7 +4,6 @@ import React, { Component } from 'react';
import {
Alert,
Keyboard,
KeyboardAvoidingView,
Platform,
Pressable,
ScrollView,
@ -284,113 +283,111 @@ export default class ElectrumSettings extends Component {
{this.state.config.host}:{this.state.config.port}
</BlueText>
</BlueCard>
<KeyboardAvoidingView>
<BlueCard>
<BlueCard>
<View style={styles.inputWrap}>
<TextInput
placeholder={loc.formatString(loc.settings.electrum_host, { example: '10.20.30.40' })}
value={this.state.host}
onChangeText={text => {
const host = text.trim();
this.setState({ host }, () => {
if (host.endsWith('.onion')) {
this.useSSLPortToggled(false);
}
});
}}
numberOfLines={1}
style={styles.inputText}
editable={!this.state.isLoading}
placeholderTextColor="#81868e"
autoCorrect={false}
autoCapitalize="none"
underlineColorAndroid="transparent"
inputAccessoryViewID={BlueDoneAndDismissKeyboardInputAccessory.InputAccessoryViewID}
testID="HostInput"
onFocus={() => this.setState({ isAndroidAddressKeyboardVisible: true })}
onBlur={() => this.setState({ isAndroidAddressKeyboardVisible: false })}
/>
</View>
<BlueSpacing20 />
<View style={styles.portWrap}>
<View style={styles.inputWrap}>
<TextInput
placeholder={loc.formatString(loc.settings.electrum_host, { example: '10.20.30.40' })}
value={this.state.host}
onChangeText={text => {
const host = text.trim();
this.setState({ host }, () => {
if (host.endsWith('.onion')) {
this.useSSLPortToggled(false);
placeholder={loc.formatString(loc.settings.electrum_port, { example: '50001' })}
value={this.state.sslPort?.trim() === '' || this.state.sslPort === null ? this.state.port : this.state.sslPort}
onChangeText={text =>
this.setState(prevState => {
if (prevState.sslPort?.trim() === '') {
return { port: text.trim(), sslPort: '' };
} else {
return { port: '', sslPort: text.trim() };
}
});
}}
})
}
numberOfLines={1}
style={styles.inputText}
editable={!this.state.isLoading}
placeholderTextColor="#81868e"
underlineColorAndroid="transparent"
autoCorrect={false}
autoCapitalize="none"
underlineColorAndroid="transparent"
inputAccessoryViewID={BlueDoneAndDismissKeyboardInputAccessory.InputAccessoryViewID}
testID="HostInput"
onFocus={() => this.setState({ isAndroidAddressKeyboardVisible: true })}
onBlur={() => this.setState({ isAndroidAddressKeyboardVisible: false })}
keyboardType="number-pad"
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
testID="PortInput"
onFocus={() => this.setState({ isAndroidNumericKeyboardFocused: true })}
onBlur={() => this.setState({ isAndroidNumericKeyboardFocused: false })}
/>
</View>
<BlueSpacing20 />
<View style={styles.portWrap}>
<View style={styles.inputWrap}>
<TextInput
placeholder={loc.formatString(loc.settings.electrum_port, { example: '50001' })}
value={this.state.sslPort?.trim() === '' || this.state.sslPort === null ? this.state.port : this.state.sslPort}
onChangeText={text =>
this.setState(prevState => {
if (prevState.sslPort?.trim() === '') {
return { port: text.trim(), sslPort: '' };
} else {
return { port: '', sslPort: text.trim() };
}
})
}
numberOfLines={1}
style={styles.inputText}
editable={!this.state.isLoading}
placeholderTextColor="#81868e"
underlineColorAndroid="transparent"
autoCorrect={false}
autoCapitalize="none"
keyboardType="number-pad"
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
testID="PortInput"
onFocus={() => this.setState({ isAndroidNumericKeyboardFocused: true })}
onBlur={() => this.setState({ isAndroidNumericKeyboardFocused: false })}
/>
</View>
<BlueText style={styles.usePort}>{loc.settings.use_ssl}</BlueText>
<Switch
testID="SSLPortInput"
value={this.state.sslPort?.trim() > 0}
onValueChange={this.useSSLPortToggled}
disabled={this.state.host?.endsWith('.onion') ?? false}
/>
</View>
<BlueSpacing20 />
<BlueText style={styles.usePort}>{loc.settings.use_ssl}</BlueText>
<Switch
testID="SSLPortInput"
value={this.state.sslPort?.trim() > 0}
onValueChange={this.useSSLPortToggled}
disabled={this.state.host?.endsWith('.onion') ?? false}
/>
</View>
<BlueSpacing20 />
<View style={styles.serverAddTitle}>
<BlueText style={styles.explain}>{loc.settings.electrum_settings_explain}</BlueText>
<TouchableOpacity accessibilityRole="button" testID="ResetToDefault" onPress={() => this.resetToDefault()}>
<BlueText>{loc.settings.electrum_reset}</BlueText>
</TouchableOpacity>
</View>
<BlueSpacing20 />
{this.state.isLoading ? <BlueLoading /> : <Button testID="Save" onPress={this.save} title={loc.settings.save} />}
<BlueSpacing20 />
<BlueButtonLink title={loc.wallets.import_scan_qr} onPress={this.importScan} />
<BlueSpacing20 />
</BlueCard>
{Platform.select({
ios: <BlueDismissKeyboardInputAccessory />,
android: this.state.isAndroidNumericKeyboardFocused && <BlueDismissKeyboardInputAccessory />,
})}
<View style={styles.serverAddTitle}>
<BlueText style={styles.explain}>{loc.settings.electrum_settings_explain}</BlueText>
<TouchableOpacity accessibilityRole="button" testID="ResetToDefault" onPress={() => this.resetToDefault()}>
<BlueText>{loc.settings.electrum_reset}</BlueText>
</TouchableOpacity>
</View>
<BlueSpacing20 />
{this.state.isLoading ? <BlueLoading /> : <Button testID="Save" onPress={this.save} title={loc.settings.save} />}
<BlueSpacing20 />
<BlueButtonLink title={loc.wallets.import_scan_qr} onPress={this.importScan} />
<BlueSpacing20 />
</BlueCard>
{Platform.select({
ios: <BlueDismissKeyboardInputAccessory />,
android: this.state.isAndroidNumericKeyboardFocused && <BlueDismissKeyboardInputAccessory />,
})}
{Platform.select({
ios: (
<BlueDoneAndDismissKeyboardInputAccessory
onClearTapped={() => this.setState({ host: '' })}
onPasteTapped={text => {
this.setState({ host: text });
Keyboard.dismiss();
}}
/>
),
android: this.state.isAndroidAddressKeyboardVisible && (
<BlueDoneAndDismissKeyboardInputAccessory
onClearTapped={() => {
this.setState({ host: '' });
Keyboard.dismiss();
}}
onPasteTapped={text => {
this.setState({ host: text });
Keyboard.dismiss();
}}
/>
),
})}
</KeyboardAvoidingView>
{Platform.select({
ios: (
<BlueDoneAndDismissKeyboardInputAccessory
onClearTapped={() => this.setState({ host: '' })}
onPasteTapped={text => {
this.setState({ host: text });
Keyboard.dismiss();
}}
/>
),
android: this.state.isAndroidAddressKeyboardVisible && (
<BlueDoneAndDismissKeyboardInputAccessory
onClearTapped={() => {
this.setState({ host: '' });
Keyboard.dismiss();
}}
onPasteTapped={text => {
this.setState({ host: text });
Keyboard.dismiss();
}}
/>
),
})}
{serverHistoryItems.length > 0 && !this.state.isLoading && (
<BlueCard>
<View style={styles.serverHistoryTitle}>
@ -408,7 +405,12 @@ export default class ElectrumSettings extends Component {
render() {
return (
<ScrollView keyboardShouldPersistTaps="always" automaticallyAdjustContentInsets contentInsetAdjustmentBehavior="automatic">
<ScrollView
keyboardShouldPersistTaps="always"
automaticallyAdjustContentInsets
contentInsetAdjustmentBehavior="automatic"
automaticallyAdjustKeyboardInsets
>
<ListItem
Component={Pressable}
title={loc.settings.electrum_offline_mode}

View file

@ -5,7 +5,6 @@ import {
ActivityIndicator,
Alert,
Keyboard,
KeyboardAvoidingView,
LayoutAnimation,
Platform,
ScrollView,
@ -351,131 +350,129 @@ const WalletsAdd: React.FC = () => {
};
return (
<ScrollView style={stylesHook.root} testID="ScrollView">
<ScrollView style={stylesHook.root} testID="ScrollView" automaticallyAdjustKeyboardInsets>
<BlueSpacing20 />
<KeyboardAvoidingView enabled behavior={Platform.OS === 'ios' ? 'padding' : undefined} keyboardVerticalOffset={62}>
<BlueFormLabel>{loc.wallets.add_wallet_name}</BlueFormLabel>
<View style={[styles.label, stylesHook.label]}>
<TextInput
testID="WalletNameInput"
value={label}
placeholderTextColor="#81868e"
placeholder={loc.wallets.add_placeholder}
onChangeText={setLabel}
style={styles.textInputCommon}
editable={!isLoading}
underlineColorAndroid="transparent"
/>
</View>
<BlueFormLabel>{loc.wallets.add_wallet_type}</BlueFormLabel>
<View style={styles.buttons}>
<WalletButton
buttonType="Bitcoin"
testID="ActivateBitcoinButton"
active={selectedWalletType === ButtonSelected.ONCHAIN}
onPress={handleOnBitcoinButtonPressed}
size={styles.button}
/>
<WalletButton
buttonType="Lightning"
active={selectedWalletType === ButtonSelected.OFFCHAIN}
onPress={handleOnLightningButtonPressed}
size={styles.button}
/>
<WalletButton
buttonType="Vault"
testID="ActivateVaultButton"
active={selectedWalletType === ButtonSelected.VAULT}
onPress={handleOnVaultButtonPressed}
size={styles.button}
/>
</View>
<BlueFormLabel>{loc.wallets.add_wallet_name}</BlueFormLabel>
<View style={[styles.label, stylesHook.label]}>
<TextInput
testID="WalletNameInput"
value={label}
placeholderTextColor="#81868e"
placeholder={loc.wallets.add_placeholder}
onChangeText={setLabel}
style={styles.textInputCommon}
editable={!isLoading}
underlineColorAndroid="transparent"
/>
</View>
<BlueFormLabel>{loc.wallets.add_wallet_type}</BlueFormLabel>
<View style={styles.buttons}>
<WalletButton
buttonType="Bitcoin"
testID="ActivateBitcoinButton"
active={selectedWalletType === ButtonSelected.ONCHAIN}
onPress={handleOnBitcoinButtonPressed}
size={styles.button}
/>
<WalletButton
buttonType="Lightning"
active={selectedWalletType === ButtonSelected.OFFCHAIN}
onPress={handleOnLightningButtonPressed}
size={styles.button}
/>
<WalletButton
buttonType="Vault"
testID="ActivateVaultButton"
active={selectedWalletType === ButtonSelected.VAULT}
onPress={handleOnVaultButtonPressed}
size={styles.button}
/>
</View>
<View style={styles.advanced}>
{(() => {
if (selectedWalletType === ButtonSelected.ONCHAIN && isAdvancedModeEnabled) {
return (
<View>
<BlueSpacing20 />
<Text style={[styles.advancedText, stylesHook.advancedText]}>{loc.settings.advanced_options}</Text>
<ListItem
containerStyle={[styles.noPadding, stylesHook.noPadding]}
bottomDivider={false}
onPress={() => setSelectedIndex(0)}
title={HDSegwitBech32Wallet.typeReadable}
checkmark={selectedIndex === 0}
/>
<ListItem
containerStyle={[styles.noPadding, stylesHook.noPadding]}
bottomDivider={false}
onPress={() => setSelectedIndex(1)}
title={SegwitP2SHWallet.typeReadable}
checkmark={selectedIndex === 1}
/>
<ListItem
containerStyle={[styles.noPadding, stylesHook.noPadding]}
bottomDivider={false}
onPress={() => setSelectedIndex(2)}
title={HDSegwitP2SHWallet.typeReadable}
checkmark={selectedIndex === 2}
<View style={styles.advanced}>
{(() => {
if (selectedWalletType === ButtonSelected.ONCHAIN && isAdvancedModeEnabled) {
return (
<View>
<BlueSpacing20 />
<Text style={[styles.advancedText, stylesHook.advancedText]}>{loc.settings.advanced_options}</Text>
<ListItem
containerStyle={[styles.noPadding, stylesHook.noPadding]}
bottomDivider={false}
onPress={() => setSelectedIndex(0)}
title={HDSegwitBech32Wallet.typeReadable}
checkmark={selectedIndex === 0}
/>
<ListItem
containerStyle={[styles.noPadding, stylesHook.noPadding]}
bottomDivider={false}
onPress={() => setSelectedIndex(1)}
title={SegwitP2SHWallet.typeReadable}
checkmark={selectedIndex === 1}
/>
<ListItem
containerStyle={[styles.noPadding, stylesHook.noPadding]}
bottomDivider={false}
onPress={() => setSelectedIndex(2)}
title={HDSegwitP2SHWallet.typeReadable}
checkmark={selectedIndex === 2}
/>
</View>
);
} else if (selectedWalletType === ButtonSelected.OFFCHAIN) {
return (
<>
<BlueSpacing20 />
<Text style={[styles.advancedText, stylesHook.advancedText]}>{loc.settings.advanced_options}</Text>
<BlueSpacing20 />
<BlueText>{loc.wallets.add_lndhub}</BlueText>
<View style={[styles.lndUri, stylesHook.lndUri]}>
<TextInput
value={walletBaseURI}
onChangeText={setWalletBaseURI}
onSubmitEditing={Keyboard.dismiss}
placeholder={loc.wallets.add_lndhub_placeholder}
clearButtonMode="while-editing"
autoCapitalize="none"
textContentType="URL"
autoCorrect={false}
placeholderTextColor="#81868e"
style={styles.textInputCommon}
editable={!isLoading}
underlineColorAndroid="transparent"
/>
</View>
);
} else if (selectedWalletType === ButtonSelected.OFFCHAIN) {
return (
<>
<BlueSpacing20 />
<Text style={[styles.advancedText, stylesHook.advancedText]}>{loc.settings.advanced_options}</Text>
<BlueSpacing20 />
<BlueText>{loc.wallets.add_lndhub}</BlueText>
<View style={[styles.lndUri, stylesHook.lndUri]}>
<TextInput
value={walletBaseURI}
onChangeText={setWalletBaseURI}
onSubmitEditing={Keyboard.dismiss}
placeholder={loc.wallets.add_lndhub_placeholder}
clearButtonMode="while-editing"
autoCapitalize="none"
textContentType="URL"
autoCorrect={false}
placeholderTextColor="#81868e"
style={styles.textInputCommon}
editable={!isLoading}
underlineColorAndroid="transparent"
/>
</View>
</>
);
}
})()}
{isAdvancedModeEnabled === true && selectedWalletType === ButtonSelected.ONCHAIN && !isLoading && (
<BlueButtonLink style={styles.import} title={entropyButtonText} onPress={navigateToEntropy} />
)}
<BlueSpacing20 />
{!isLoading ? (
<>
<Button
testID="Create"
title={loc.wallets.add_create}
disabled={
!selectedWalletType || (selectedWalletType === ButtonSelected.OFFCHAIN && (walletBaseURI ?? '').trim().length === 0)
}
onPress={createWallet}
/>
</>
);
}
})()}
{isAdvancedModeEnabled === true && selectedWalletType === ButtonSelected.ONCHAIN && !isLoading && (
<BlueButtonLink style={styles.import} title={entropyButtonText} onPress={navigateToEntropy} />
)}
<BlueSpacing20 />
{!isLoading ? (
<>
<Button
testID="Create"
title={loc.wallets.add_create}
disabled={
!selectedWalletType || (selectedWalletType === ButtonSelected.OFFCHAIN && (walletBaseURI ?? '').trim().length === 0)
}
onPress={createWallet}
/>
<BlueButtonLink
testID="ImportWallet"
style={styles.import}
title={loc.wallets.add_import_wallet}
onPress={navigateToImportWallet}
/>
<BlueSpacing40 />
</>
) : (
<ActivityIndicator />
)}
</View>
</KeyboardAvoidingView>
<BlueButtonLink
testID="ImportWallet"
style={styles.import}
title={loc.wallets.add_import_wallet}
onPress={navigateToImportWallet}
/>
<BlueSpacing40 />
</>
) : (
<ActivityIndicator />
)}
</View>
</ScrollView>
);
};

View file

@ -7,7 +7,6 @@ import {
FlatList,
InteractionManager,
Keyboard,
KeyboardAvoidingView,
LayoutAnimation,
ListRenderItemInfo,
Platform,
@ -17,7 +16,7 @@ import {
View,
} from 'react-native';
import { Badge, Icon } from '@rneui/themed';
import { isDesktop, isTablet } from '../../blue_modules/environment';
import { isDesktop } from '../../blue_modules/environment';
import { encodeUR } from '../../blue_modules/ur';
import {
BlueButtonLink,
@ -631,23 +630,19 @@ const ViewEditMultisigCosigners: React.FC = () => {
return (
<View style={[styles.root, stylesHook.root]} ref={discardChangesRef}>
<KeyboardAvoidingView
enabled={!isTablet}
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
keyboardVerticalOffset={62}
style={[styles.mainBlock, styles.root]}
>
<FlatList
ListHeaderComponent={tipKeys}
data={data.current}
extraData={vaultKeyData}
renderItem={_renderKeyItem}
keyExtractor={(_item, index) => `${index}`}
/>
<BlueSpacing10 />
{footer}
<BlueSpacing40 />
</KeyboardAvoidingView>
<FlatList
ListHeaderComponent={tipKeys}
data={data.current}
extraData={vaultKeyData}
renderItem={_renderKeyItem}
automaticallyAdjustKeyboardInsets
contentInsetAdjustmentBehavior="automatic"
automaticallyAdjustContentInsets
keyExtractor={(_item, index) => `${index}`}
/>
<BlueSpacing10 />
{footer}
<BlueSpacing40 />
{renderProvideMnemonicsModal()}
@ -689,7 +684,6 @@ const styles = StyleSheet.create({
marginBottom: 32,
},
headerText: { fontSize: 15, color: '#13244D' },
mainBlock: { marginHorizontal: 16 },
alignItemsCenter: { alignItems: 'center', justifyContent: 'space-between' },
shareModalHeight: { minHeight: 450 },
tipKeys: {

View file

@ -5,8 +5,6 @@ import {
I18nManager,
InteractionManager,
Keyboard,
KeyboardAvoidingView,
Platform,
ScrollView,
StyleSheet,
Switch,
@ -419,6 +417,7 @@ const WalletDetails = () => {
return (
<ScrollView
automaticallyAdjustKeyboardInsets
contentInsetAdjustmentBehavior="automatic"
centerContent={isLoading}
contentContainerStyle={styles.scrollViewContent}
@ -453,21 +452,19 @@ const WalletDetails = () => {
}
})()}
<Text style={[styles.textLabel2, stylesHook.textLabel2]}>{loc.wallets.add_wallet_name.toLowerCase()}</Text>
<KeyboardAvoidingView enabled={!Platform.isPad} behavior={Platform.OS === 'ios' ? 'position' : null}>
<View style={[styles.input, stylesHook.input]}>
<TextInput
value={walletName}
onChangeText={setWalletName}
onBlur={walletNameTextInputOnBlur}
numberOfLines={1}
placeholderTextColor="#81868e"
style={styles.inputText}
editable={!isLoading}
underlineColorAndroid="transparent"
testID="WalletNameInput"
/>
</View>
</KeyboardAvoidingView>
<View style={[styles.input, stylesHook.input]}>
<TextInput
value={walletName}
onChangeText={setWalletName}
onBlur={walletNameTextInputOnBlur}
numberOfLines={1}
placeholderTextColor="#81868e"
style={styles.inputText}
editable={!isLoading}
underlineColorAndroid="transparent"
testID="WalletNameInput"
/>
</View>
<BlueSpacing20 />
<Text style={[styles.textLabel1, stylesHook.textLabel1]}>{loc.wallets.details_type.toLowerCase()}</Text>
<Text style={[styles.textValue, stylesHook.textValue]}>{wallet.typeReadable}</Text>

View file

@ -1,12 +1,11 @@
import { useTheme } from '@react-navigation/native';
import React, { useState } from 'react';
import { Keyboard, KeyboardAvoidingView, Platform, StyleSheet, TextInput, View } from 'react-native';
import { Keyboard, ScrollView, StyleSheet, TextInput, View } from 'react-native';
import { generateChecksumWords } from '../../blue_modules/checksumWords';
import { BlueCard, BlueSpacing10, BlueSpacing20, BlueText } from '../../BlueComponents';
import { randomBytes } from '../../class/rng';
import Button from '../../components/Button';
import SafeArea from '../../components/SafeArea';
import loc from '../../loc';
const GenerateWord = () => {
@ -53,51 +52,51 @@ const GenerateWord = () => {
};
return (
<SafeArea style={styles.blueArea}>
<KeyboardAvoidingView
enabled={!Platform.isPad}
behavior={Platform.OS === 'ios' ? 'position' : null}
keyboardShouldPersistTaps="handled"
>
<View style={styles.wrapper}>
<BlueCard style={styles.mainCard}>
<View style={[styles.input, stylesHooks.input]}>
<TextInput
style={styles.text}
maxHeight={100}
minHeight={100}
maxWidth="100%"
minWidth="100%"
multiline
editable
placeholder={loc.autofill_word.enter}
placeholderTextColor="#81868e"
value={mnemonic}
onChangeText={handleUpdateMnemonic}
testID="MnemonicInput"
/>
</View>
<ScrollView
style={styles.blueArea}
keyboardShouldPersistTaps="handled"
automaticallyAdjustContentInsets
automaticallyAdjustKeyboardInsets
contentInsetAdjustmentBehavior="automatic"
>
<View style={styles.wrapper}>
<BlueCard style={styles.mainCard}>
<View style={[styles.input, stylesHooks.input]}>
<TextInput
style={styles.text}
maxHeight={100}
minHeight={100}
maxWidth="100%"
minWidth="100%"
multiline
editable
placeholder={loc.autofill_word.enter}
placeholderTextColor="#81868e"
value={mnemonic}
onChangeText={handleUpdateMnemonic}
testID="MnemonicInput"
/>
</View>
<BlueSpacing10 />
<Button title={loc.send.input_clear} onPress={clearMnemonicInput} />
<BlueSpacing20 />
<BlueText style={styles.center} testID="Result">
{result}
</BlueText>
<BlueSpacing20 />
<View>
<Button
disabled={mnemonic.trim().length === 0}
title={loc.autofill_word.generate_word}
onPress={checkMnemonic}
testID="GenerateWord"
/>
</View>
<BlueSpacing20 />
</BlueCard>
</View>
</KeyboardAvoidingView>
</SafeArea>
<BlueSpacing10 />
<Button title={loc.send.input_clear} onPress={clearMnemonicInput} />
<BlueSpacing20 />
<BlueText style={styles.center} testID="Result">
{result}
</BlueText>
<BlueSpacing20 />
<View>
<Button
disabled={mnemonic.trim().length === 0}
title={loc.autofill_word.generate_word}
onPress={checkMnemonic}
testID="GenerateWord"
/>
</View>
<BlueSpacing20 />
</BlueCard>
</View>
</ScrollView>
);
};