BlueWallet/components/AddressInput.tsx

135 lines
3.5 KiB
TypeScript
Raw Normal View History

2024-10-27 19:06:14 +01:00
import React, { useCallback } from 'react';
2024-09-24 03:36:45 +02:00
import { Keyboard, StyleSheet, TextInput, View } from 'react-native';
2024-05-20 11:54:13 +02:00
import loc from '../loc';
2024-09-24 03:36:45 +02:00
import { AddressInputScanButton } from './AddressInputScanButton';
import { useTheme } from './themes';
import DeeplinkSchemaMatch from '../class/deeplink-schema-match';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../blue_modules/hapticFeedback';
2024-01-06 09:04:23 +01:00
interface AddressInputProps {
isLoading?: boolean;
address?: string;
placeholder?: string;
onChangeText: (text: string) => void;
2024-01-07 14:55:55 +01:00
onBarScanned: (ret: { data?: any }) => void;
2024-01-06 09:04:23 +01:00
scanButtonTapped?: () => void;
launchedBy?: string;
editable?: boolean;
inputAccessoryViewID?: string;
onBlur?: () => void;
2024-09-24 03:36:45 +02:00
onFocus?: () => void;
2024-09-27 01:21:47 +02:00
testID?: string;
2024-01-06 09:04:23 +01:00
keyboardType?:
| 'default'
| 'numeric'
| 'email-address'
| 'ascii-capable'
| 'numbers-and-punctuation'
| 'url'
| 'number-pad'
| 'phone-pad'
| 'name-phone-pad'
| 'decimal-pad'
| 'twitter'
| 'web-search'
| 'visible-password';
}
const AddressInput = ({
isLoading = false,
address = '',
2024-09-27 01:21:47 +02:00
testID = 'AddressInput',
placeholder = loc.send.details_address,
onChangeText,
onBarScanned,
2021-09-09 13:00:11 +02:00
scanButtonTapped = () => {},
launchedBy,
2021-09-09 13:00:11 +02:00
editable = true,
inputAccessoryViewID,
onBlur = () => {},
2024-09-24 03:36:45 +02:00
onFocus = () => {},
2021-10-15 16:52:25 +02:00
keyboardType = 'default',
2024-01-06 09:04:23 +01:00
}: AddressInputProps) => {
const { colors } = useTheme();
const stylesHook = StyleSheet.create({
root: {
borderColor: colors.formBorder,
borderBottomColor: colors.formBorder,
backgroundColor: colors.inputBackgroundColor,
},
2024-09-24 03:36:45 +02:00
input: {
color: colors.foregroundColor,
},
});
2024-10-27 19:06:14 +01:00
const validateAddressWithFeedback = useCallback((value: string) => {
const isBitcoinAddress = DeeplinkSchemaMatch.isBitcoinAddress(value);
const isLightningInvoice = DeeplinkSchemaMatch.isLightningInvoice(value);
const isValid = isBitcoinAddress || isLightningInvoice;
2024-10-23 00:26:36 +02:00
2024-10-27 19:06:14 +01:00
triggerHapticFeedback(isValid ? HapticFeedbackTypes.NotificationSuccess : HapticFeedbackTypes.NotificationError);
return {
isValid,
2024-10-28 03:05:14 +01:00
type: isBitcoinAddress ? 'bitcoin' : isLightningInvoice ? 'lightning' : 'invalid',
};
2024-10-27 19:06:14 +01:00
}, []);
2024-10-27 19:06:14 +01:00
const onBlurEditing = () => {
validateAddressWithFeedback(address);
onBlur();
Keyboard.dismiss();
};
return (
<View style={[styles.root, stylesHook.root]}>
<TextInput
2024-09-27 01:21:47 +02:00
testID={testID}
onChangeText={onChangeText}
placeholder={placeholder}
placeholderTextColor="#81868e"
value={address}
2024-09-24 03:36:45 +02:00
style={[styles.input, stylesHook.input]}
2021-09-09 13:00:11 +02:00
editable={!isLoading && editable}
multiline={!editable}
inputAccessoryViewID={inputAccessoryViewID}
clearButtonMode="while-editing"
onBlur={onBlurEditing}
2024-09-24 03:36:45 +02:00
onFocus={onFocus}
autoCapitalize="none"
autoCorrect={false}
2021-10-15 16:52:25 +02:00
keyboardType={keyboardType}
/>
2021-09-09 13:00:11 +02:00
{editable ? (
2024-09-24 03:36:45 +02:00
<AddressInputScanButton
isLoading={isLoading}
launchedBy={launchedBy}
scanButtonTapped={scanButtonTapped}
onBarScanned={onBarScanned}
onChangeText={onChangeText}
/>
2021-09-09 13:00:11 +02:00
) : null}
</View>
);
};
const styles = StyleSheet.create({
root: {
flexDirection: 'row',
borderWidth: 1.0,
borderBottomWidth: 0.5,
minHeight: 44,
height: 44,
alignItems: 'center',
marginVertical: 8,
2024-10-28 03:05:14 +01:00
marginHorizontal: 18,
borderRadius: 4,
},
input: {
flex: 1,
2024-10-28 03:05:14 +01:00
paddingHorizontal: 8,
minHeight: 33,
},
});
export default AddressInput;