import Clipboard from '@react-native-clipboard/clipboard'; import React, { useCallback, useRef } from 'react'; import { Platform, StyleSheet, View } from 'react-native'; import QRCode from 'react-native-qrcode-svg'; import Share from 'react-native-share'; import loc from '../loc'; import { ActionIcons } from '../typings/ActionIcons'; import { useTheme } from './themes'; import ToolTipMenu from './TooltipMenu'; import { Action } from './types'; interface QRCodeComponentProps { value: string; isLogoRendered?: boolean; isMenuAvailable?: boolean; logoSize?: number; size?: number; ecl?: 'H' | 'Q' | 'M' | 'L'; onError?: () => void; } const BORDER_WIDTH = 6; const actionIcons: { [key: string]: ActionIcons } = { Share: { iconValue: 'square.and.arrow.up', }, Copy: { iconValue: 'doc.on.doc', }, }; const actionKeys = { Share: 'share', Copy: 'copy', }; const menuActions: Action[] = Platform.OS === 'ios' || Platform.OS === 'macos' ? [ { id: actionKeys.Copy, text: loc.transactions.details_copy, icon: actionIcons.Copy, }, { id: actionKeys.Share, text: loc.receive.details_share, icon: actionIcons.Share }, ] : [ { id: actionKeys.Copy, text: loc.transactions.details_copy, icon: actionIcons.Copy, }, ]; const QRCodeComponent: React.FC<QRCodeComponentProps> = ({ value = '', isLogoRendered = true, isMenuAvailable = true, logoSize = 90, size = 300, ecl = 'H', onError = () => {}, }) => { const qrCode = useRef<any>(); const { colors, dark } = useTheme(); const handleShareQRCode = () => { qrCode.current.toDataURL((data: string) => { data = data.replace(/(\r\n|\n|\r)/gm, ''); const shareImageBase64 = { url: `data:image/png;base64,${data}`, }; Share.open(shareImageBase64).catch((error: Error) => console.log(error)); }); }; const onPressMenuItem = useCallback((id: string) => { if (id === actionKeys.Share) { handleShareQRCode(); } else if (id === actionKeys.Copy) { qrCode.current.toDataURL(Clipboard.setImage); } }, []); // Adjust the size of the QR code to account for the border width const newSize = dark ? size - BORDER_WIDTH * 2 : size; const stylesHook = StyleSheet.create({ container: { borderWidth: dark ? BORDER_WIDTH : 0 }, }); const renderQRCode = ( <QRCode value={value} {...(isLogoRendered ? { logo: require('../img/qr-code.png') } : {})} size={newSize} logoSize={logoSize} color="#000000" logoBackgroundColor={colors.brandingColor} backgroundColor="#FFFFFF" ecl={ecl} getRef={(c: any) => (qrCode.current = c)} onError={onError} /> ); return ( <View style={[styles.container, stylesHook.container]} testID="BitcoinAddressQRCodeContainer" accessibilityIgnoresInvertColors importantForAccessibility="no-hide-descendants" accessibilityRole="image" accessibilityLabel={loc.receive.qrcode_for_the_address} > {isMenuAvailable ? ( <ToolTipMenu actions={menuActions} onPressMenuItem={onPressMenuItem}> {renderQRCode} </ToolTipMenu> ) : ( renderQRCode )} </View> ); }; export default QRCodeComponent; const styles = StyleSheet.create({ container: { borderColor: '#FFFFFF' }, });