import React, { useCallback, useMemo } from 'react'; import { Image, Keyboard, Platform, StyleSheet, Text, View } from 'react-native'; import Clipboard from '@react-native-clipboard/clipboard'; import ToolTipMenu from './TooltipMenu'; import loc from '../loc'; import { showFilePickerAndReadFile, showImagePickerAndReadImage } from '../blue_modules/fs'; import presentAlert from './Alert'; import { useTheme } from './themes'; import { detectQRCodeInImage } from 'react-native-camera-kit-no-google'; import { CommonToolTipActions } from '../typings/CommonToolTipActions'; import { useSettings } from '../hooks/context/useSettings'; import { scanQrHelper } from '../helpers/scan-qr.ts'; interface AddressInputScanButtonProps { isLoading?: boolean; onChangeText: (text: string) => void; type?: 'default' | 'link'; testID?: string; beforePress?: () => Promise | void; } export const AddressInputScanButton = ({ isLoading, onChangeText, type = 'default', testID = 'BlueAddressInputScanQrButton', beforePress, }: AddressInputScanButtonProps) => { const { colors } = useTheme(); const { isClipboardGetContentEnabled } = useSettings(); const stylesHook = StyleSheet.create({ scan: { backgroundColor: colors.scanLabel, }, scanText: { color: colors.inverseForegroundColor, }, }); const toolTipOnPress = useCallback(async () => { if (beforePress) { await beforePress(); } Keyboard.dismiss(); scanQrHelper().then(onChangeText); }, [beforePress, onChangeText]); const actions = useMemo(() => { const availableActions = [ CommonToolTipActions.ChoosePhoto, CommonToolTipActions.ImportFile, { ...CommonToolTipActions.PasteFromClipboard, hidden: !isClipboardGetContentEnabled, }, ]; return availableActions; }, [isClipboardGetContentEnabled]); const onMenuItemPressed = useCallback( async (action: string) => { switch (action) { case CommonToolTipActions.PasteFromClipboard.id: try { let getImage: string | null = null; let hasImage = false; if (Platform.OS === 'android') { hasImage = true; } else { hasImage = await Clipboard.hasImage(); } if (hasImage) { getImage = await Clipboard.getImage(); } if (getImage) { try { const base64Data = getImage.replace(/^data:image\/(png|jpeg|jpg);base64,/, ''); const result = await detectQRCodeInImage(base64Data); if (result) { onChangeText(result); } else { presentAlert({ message: loc.send.qr_error_no_qrcode }); } } catch (error) { presentAlert({ message: (error as Error).message }); } } else { const clipboardText = await Clipboard.getString(); onChangeText(clipboardText); } } catch (error) { presentAlert({ message: (error as Error).message }); } break; case CommonToolTipActions.ChoosePhoto.id: showImagePickerAndReadImage() .then(value => { if (value) { onChangeText(value); } }) .catch(error => { presentAlert({ message: error.message }); }); break; case CommonToolTipActions.ImportFile.id: showFilePickerAndReadFile() .then(value => { if (value.data) { onChangeText(value.data); } }) .catch(error => { presentAlert({ message: error.message }); }); break; } Keyboard.dismiss(); }, [onChangeText], ); const menuButtonStyle = useMemo(() => (type === 'default' ? [styles.scan, stylesHook.scan] : undefined), [stylesHook.scan, type]); return ( {type === 'default' ? ( {loc.send.details_scan} ) : ( {loc.wallets.import_scan_qr} )} ); }; AddressInputScanButton.displayName = 'AddressInputScanButton'; const styles = StyleSheet.create({ scan: { height: 36, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: 6, minWidth: 82, flexShrink: 0, borderRadius: 4, paddingVertical: 4, paddingHorizontal: 8, marginHorizontal: 4, alignSelf: 'center', }, scanText: { marginLeft: 4, flexShrink: 0, textAlignVertical: 'center', }, scanContent: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', flexShrink: 0, }, linkText: { textAlign: 'center', fontSize: 16, flexShrink: 1, textAlignVertical: 'center', }, contentRow: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', width: '100%', }, });