mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-03-13 19:16:52 +01:00
REF: Reuse AddressInput component
This commit is contained in:
parent
d68b806b60
commit
1c15ae0a0c
6 changed files with 23 additions and 160 deletions
|
@ -11,9 +11,7 @@ interface AddressInputProps {
|
|||
address?: string;
|
||||
placeholder?: string;
|
||||
onChangeText: (text: string) => void;
|
||||
onBarScanned: (ret: { data?: any }) => void;
|
||||
scanButtonTapped?: () => void;
|
||||
launchedBy?: string;
|
||||
editable?: boolean;
|
||||
inputAccessoryViewID?: string;
|
||||
onFocus?: () => void;
|
||||
|
@ -43,9 +41,7 @@ const AddressInput = ({
|
|||
testID = 'AddressInput',
|
||||
placeholder = loc.send.details_address,
|
||||
onChangeText,
|
||||
onBarScanned,
|
||||
scanButtonTapped = () => {},
|
||||
launchedBy,
|
||||
editable = true,
|
||||
inputAccessoryViewID,
|
||||
onFocus = () => {},
|
||||
|
@ -108,15 +104,7 @@ const AddressInput = ({
|
|||
keyboardType={keyboardType}
|
||||
{...(skipValidation ? { onBlur } : { onBlur: onBlurEditing })}
|
||||
/>
|
||||
{editable ? (
|
||||
<AddressInputScanButton
|
||||
isLoading={isLoading}
|
||||
launchedBy={launchedBy}
|
||||
scanButtonTapped={scanButtonTapped}
|
||||
onBarScanned={onBarScanned}
|
||||
onChangeText={onChangeText}
|
||||
/>
|
||||
) : null}
|
||||
{editable ? <AddressInputScanButton isLoading={isLoading} scanButtonTapped={scanButtonTapped} onChangeText={onChangeText} /> : null}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useCallback, useEffect, useMemo } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { Image, Keyboard, Platform, StyleSheet, Text } from 'react-native';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import ToolTipMenu from './TooltipMenu';
|
||||
|
@ -9,33 +9,19 @@ import { useTheme } from './themes';
|
|||
import RNQRGenerator from 'rn-qr-generator';
|
||||
import { CommonToolTipActions } from '../typings/CommonToolTipActions';
|
||||
import { useSettings } from '../hooks/context/useSettings';
|
||||
import { useRoute } from '@react-navigation/native';
|
||||
import { useExtendedNavigation } from '../hooks/useExtendedNavigation';
|
||||
|
||||
interface AddressInputScanButtonProps {
|
||||
isLoading: boolean;
|
||||
launchedBy?: string;
|
||||
scanButtonTapped: () => void;
|
||||
onBarScanned: (ret: { data?: any }) => void;
|
||||
onChangeText: (text: string) => void;
|
||||
}
|
||||
|
||||
interface RouteParams {
|
||||
onBarScanned?: any;
|
||||
}
|
||||
|
||||
export const AddressInputScanButton = ({
|
||||
isLoading,
|
||||
launchedBy,
|
||||
scanButtonTapped,
|
||||
onBarScanned,
|
||||
onChangeText,
|
||||
}: AddressInputScanButtonProps) => {
|
||||
export const AddressInputScanButton = ({ isLoading, scanButtonTapped, onChangeText }: AddressInputScanButtonProps) => {
|
||||
const { colors } = useTheme();
|
||||
const { isClipboardGetContentEnabled } = useSettings();
|
||||
|
||||
const navigation = useExtendedNavigation();
|
||||
const params = useRoute().params as RouteParams;
|
||||
const stylesHook = StyleSheet.create({
|
||||
scan: {
|
||||
backgroundColor: colors.scanLabel,
|
||||
|
@ -67,17 +53,8 @@ export const AddressInputScanButton = ({
|
|||
return availableActions;
|
||||
}, [isClipboardGetContentEnabled]);
|
||||
|
||||
useEffect(() => {
|
||||
const data = params.onBarScanned;
|
||||
if (data) {
|
||||
onBarScanned({ data });
|
||||
navigation.setParams({ onBarScanned: undefined });
|
||||
}
|
||||
});
|
||||
|
||||
const onMenuItemPressed = useCallback(
|
||||
async (action: string) => {
|
||||
if (onBarScanned === undefined) throw new Error('onBarScanned is required');
|
||||
switch (action) {
|
||||
case CommonToolTipActions.ScanQR.id:
|
||||
scanButtonTapped();
|
||||
|
@ -147,7 +124,7 @@ export const AddressInputScanButton = ({
|
|||
}
|
||||
Keyboard.dismiss();
|
||||
},
|
||||
[navigation, onBarScanned, onChangeText, scanButtonTapped],
|
||||
[navigation, onChangeText, scanButtonTapped],
|
||||
);
|
||||
|
||||
const buttonStyle = useMemo(() => [styles.scan, stylesHook.scan], [stylesHook.scan]);
|
||||
|
|
|
@ -81,7 +81,6 @@ const SendDetails = () => {
|
|||
const selectedDataProcessor = useRef<ToolTipAction | undefined>();
|
||||
const setParams = navigation.setParams;
|
||||
const route = useRoute<RouteProps>();
|
||||
const name = route.name;
|
||||
const feeUnit = route.params?.feeUnit ?? BitcoinUnit.BTC;
|
||||
const amountUnit = route.params?.amountUnit ?? BitcoinUnit.BTC;
|
||||
const frozenBalance = route.params?.frozenBalance ?? 0;
|
||||
|
@ -1312,11 +1311,9 @@ const SendDetails = () => {
|
|||
setIsLoading(false);
|
||||
setParams({ payjoinUrl: pjUrl });
|
||||
}}
|
||||
onBarScanned={processAddressData}
|
||||
address={item.address}
|
||||
isLoading={isLoading}
|
||||
inputAccessoryViewID={DismissKeyboardInputAccessoryViewID}
|
||||
launchedBy={name}
|
||||
editable={isEditable}
|
||||
style={styles.addressInput}
|
||||
/>
|
||||
|
|
|
@ -416,10 +416,6 @@ const ElectrumSettings: React.FC = () => {
|
|||
}
|
||||
};
|
||||
|
||||
const importScan = async () => {
|
||||
navigation.navigate('ScanQRCode');
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const data = params.onBarScanned;
|
||||
if (data) {
|
||||
|
@ -494,7 +490,6 @@ const ElectrumSettings: React.FC = () => {
|
|||
address={host}
|
||||
onChangeText={text => setHost(text.trim())}
|
||||
editable={!isLoading}
|
||||
onBarScanned={importScan}
|
||||
keyboardType="default"
|
||||
skipValidation
|
||||
onBlur={() => setIsAndroidAddressKeyboardVisible(false)}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { RouteProp, useRoute } from '@react-navigation/native';
|
||||
import { Alert, I18nManager, Linking, ScrollView, StyleSheet, TextInput, View } from 'react-native';
|
||||
import { Alert, I18nManager, Linking, ScrollView, StyleSheet } from 'react-native';
|
||||
import { Button as ButtonRNElements } from '@rneui/themed';
|
||||
import DefaultPreference from 'react-native-default-preference';
|
||||
import { BlueButtonLink, BlueCard, BlueLoading, BlueSpacing20, BlueText } from '../../BlueComponents';
|
||||
import { BlueCard, BlueLoading, BlueSpacing40, BlueText } from '../../BlueComponents';
|
||||
import DeeplinkSchemaMatch from '../../class/deeplink-schema-match';
|
||||
import { LightningCustodianWallet } from '../../class/wallets/lightning-custodian-wallet';
|
||||
import presentAlert, { AlertType } from '../../components/Alert';
|
||||
|
@ -15,24 +15,9 @@ import { GROUP_IO_BLUEWALLET } from '../../blue_modules/currency';
|
|||
import { clearLNDHub, getLNDHub, setLNDHub } from '../../helpers/lndHub';
|
||||
import { DetailViewStackParamList } from '../../navigation/DetailViewStackParamList';
|
||||
import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
|
||||
import AddressInput from '../../components/AddressInput';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
uri: {
|
||||
flexDirection: 'row',
|
||||
borderWidth: 1,
|
||||
borderBottomWidth: 0.5,
|
||||
minHeight: 44,
|
||||
height: 44,
|
||||
alignItems: 'center',
|
||||
borderRadius: 4,
|
||||
},
|
||||
uriText: {
|
||||
flex: 1,
|
||||
color: '#81868e',
|
||||
marginHorizontal: 8,
|
||||
minHeight: 36,
|
||||
height: 36,
|
||||
},
|
||||
buttonStyle: {
|
||||
backgroundColor: 'transparent',
|
||||
flexDirection: I18nManager.isRTL ? 'row-reverse' : 'row',
|
||||
|
@ -46,14 +31,7 @@ const LightningSettings: React.FC = () => {
|
|||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [URI, setURI] = useState<string>();
|
||||
const { colors } = useTheme();
|
||||
const { navigate, setParams } = useExtendedNavigation();
|
||||
const styleHook = StyleSheet.create({
|
||||
uri: {
|
||||
borderColor: colors.formBorder,
|
||||
borderBottomColor: colors.formBorder,
|
||||
backgroundColor: colors.inputBackgroundColor,
|
||||
},
|
||||
});
|
||||
const { setParams } = useExtendedNavigation();
|
||||
|
||||
useEffect(() => {
|
||||
const fetchURI = async () => {
|
||||
|
@ -123,12 +101,6 @@ const LightningSettings: React.FC = () => {
|
|||
setIsLoading(false);
|
||||
}, [URI]);
|
||||
|
||||
const importScan = () => {
|
||||
navigate('ScanQRCode', {
|
||||
showFileImportButton: true,
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const data = params?.onBarScanned;
|
||||
if (data) {
|
||||
|
@ -158,25 +130,15 @@ const LightningSettings: React.FC = () => {
|
|||
/>
|
||||
|
||||
<BlueCard>
|
||||
<View style={[styles.uri, styleHook.uri]}>
|
||||
<TextInput
|
||||
value={URI}
|
||||
placeholder={loc.formatString(loc.settings.lndhub_uri, { example: 'https://10.20.30.40:3000' })}
|
||||
onChangeText={setLndhubURI}
|
||||
numberOfLines={1}
|
||||
style={styles.uriText}
|
||||
placeholderTextColor="#81868e"
|
||||
editable={!isLoading}
|
||||
textContentType="URL"
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
underlineColorAndroid="transparent"
|
||||
testID="URIInput"
|
||||
/>
|
||||
</View>
|
||||
<BlueSpacing20 />
|
||||
<BlueButtonLink title={loc.wallets.import_scan_qr} testID="ImportScan" onPress={importScan} />
|
||||
<BlueSpacing20 />
|
||||
<AddressInput
|
||||
isLoading={isLoading}
|
||||
address={URI}
|
||||
placeholder={loc.formatString(loc.settings.lndhub_uri, { example: 'https://10.20.30.40:3000' })}
|
||||
onChangeText={setLndhubURI}
|
||||
testID="URIInput"
|
||||
editable={!isLoading}
|
||||
/>
|
||||
<BlueSpacing40 />
|
||||
{isLoading ? <BlueLoading /> : <Button testID="Save" onPress={save} title={loc.settings.save} />}
|
||||
</BlueCard>
|
||||
</ScrollView>
|
||||
|
|
|
@ -13,22 +13,17 @@ import {
|
|||
} from 'react-native';
|
||||
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
||||
import { useFocusEffect, useNavigation } from '@react-navigation/native';
|
||||
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
|
||||
import { useTheme } from '../../components/themes';
|
||||
import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
|
||||
import loc, { formatBalanceWithoutSuffix } from '../../loc';
|
||||
import loc from '../../loc';
|
||||
import { useStorage } from '../../hooks/context/useStorage';
|
||||
import useDebounce from '../../hooks/useDebounce';
|
||||
import { TTXMetadata } from '../../class';
|
||||
import { ExtendedTransaction, LightningTransaction, Transaction, TWallet } from '../../class/wallets/types';
|
||||
import useBounceAnimation from '../../hooks/useBounceAnimation';
|
||||
import { unlockWithBiometrics, useBiometrics } from '../../hooks/useBiometrics';
|
||||
import presentAlert from '../../components/Alert';
|
||||
import prompt from '../../helpers/prompt';
|
||||
import HeaderRightButton from '../../components/HeaderRightButton';
|
||||
import { useSettings } from '../../hooks/context/useSettings';
|
||||
import DragList, { DragListRenderItemInfo } from 'react-native-draglist';
|
||||
import { BitcoinUnit } from '../../models/bitcoinUnits';
|
||||
|
||||
const ManageWalletsListItem = lazy(() => import('../../components/ManageWalletsListItem'));
|
||||
|
||||
|
@ -199,7 +194,6 @@ const ManageWallets: React.FC = () => {
|
|||
const walletsRef = useRef<TWallet[]>(deepCopyWallets(storedWallets)); // Create a deep copy of wallets for the DraggableFlatList
|
||||
const { navigate, setOptions, goBack } = useExtendedNavigation();
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
const { isBiometricUseCapableAndEnabled } = useBiometrics();
|
||||
const navigation = useNavigation();
|
||||
const debouncedSearchQuery = useDebounce(state.searchQuery, 300);
|
||||
const bounceAnim = useBounceAnimation(state.searchQuery);
|
||||
|
@ -365,64 +359,14 @@ const ManageWallets: React.FC = () => {
|
|||
[bounceAnim],
|
||||
);
|
||||
|
||||
const presentWalletHasBalanceAlert = useCallback(async (wallet: TWallet) => {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationWarning);
|
||||
try {
|
||||
const balance = formatBalanceWithoutSuffix(wallet.getBalance(), BitcoinUnit.SATS, true);
|
||||
const walletBalanceConfirmation = await prompt(
|
||||
loc.wallets.details_delete_wallet,
|
||||
loc.formatString(loc.wallets.details_del_wb_q, { balance }),
|
||||
true,
|
||||
'numeric',
|
||||
true,
|
||||
loc.wallets.details_delete,
|
||||
);
|
||||
const cleanedConfirmation = (walletBalanceConfirmation || '').replace(/[^0-9]/g, '');
|
||||
|
||||
if (Number(cleanedConfirmation) === wallet.getBalance()) {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
|
||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
||||
dispatch({ type: REMOVE_WALLET, payload: wallet.getID() });
|
||||
} else {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
||||
presentAlert({ message: loc.wallets.details_del_wb_err });
|
||||
}
|
||||
} catch (_) {}
|
||||
}, []);
|
||||
|
||||
const handleDeleteWallet = useCallback(
|
||||
async (wallet: TWallet) => {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationWarning);
|
||||
presentAlert({
|
||||
title: loc.wallets.details_delete_wallet,
|
||||
message: loc.wallets.details_are_you_sure,
|
||||
buttons: [
|
||||
{
|
||||
text: loc.wallets.details_yes_delete,
|
||||
onPress: async () => {
|
||||
const isBiometricsEnabled = await isBiometricUseCapableAndEnabled();
|
||||
if (isBiometricsEnabled && !(await unlockWithBiometrics())) {
|
||||
return;
|
||||
}
|
||||
if (wallet.getBalance && wallet.getBalance() > 0 && wallet.allowSend && wallet.allowSend()) {
|
||||
presentWalletHasBalanceAlert(wallet);
|
||||
} else {
|
||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
||||
dispatch({ type: REMOVE_WALLET, payload: wallet.getID() });
|
||||
}
|
||||
const deleted = await handleWalletDeletion(wallet.getID(), true);
|
||||
if (deleted) {
|
||||
goBack();
|
||||
}
|
||||
},
|
||||
style: 'destructive',
|
||||
},
|
||||
{ text: loc._.cancel, onPress: () => {}, style: 'cancel' },
|
||||
],
|
||||
options: { cancelable: false },
|
||||
});
|
||||
const deletionSucceeded = await handleWalletDeletion(wallet.getID());
|
||||
if (deletionSucceeded) {
|
||||
dispatch({ type: REMOVE_WALLET, payload: wallet.getID() });
|
||||
}
|
||||
},
|
||||
[isBiometricUseCapableAndEnabled, handleWalletDeletion, presentWalletHasBalanceAlert, goBack],
|
||||
[handleWalletDeletion],
|
||||
);
|
||||
|
||||
const handleToggleHideBalance = useCallback(
|
||||
|
|
Loading…
Add table
Reference in a new issue