BlueWallet/components/QRCodeComponent.tsx

133 lines
3.4 KiB
TypeScript
Raw Normal View History

2024-05-20 10:54:13 +01:00
import Clipboard from '@react-native-clipboard/clipboard';
2024-06-17 15:38:01 -04:00
import React, { useCallback, useRef } from 'react';
2024-05-20 10:54:13 +01:00
import { Platform, StyleSheet, View } from 'react-native';
2021-08-26 21:31:36 -04:00
import QRCode from 'react-native-qrcode-svg';
import Share from 'react-native-share';
2024-05-20 10:54:13 +01:00
2021-08-26 21:31:36 -04:00
import loc from '../loc';
2024-03-24 18:27:58 -04:00
import { ActionIcons } from '../typings/ActionIcons';
2024-05-20 10:54:13 +01:00
import { useTheme } from './themes';
import ToolTipMenu from './TooltipMenu';
2024-05-18 12:48:03 -04:00
import { Action } from './types';
2021-08-26 21:31:36 -04:00
2023-03-23 22:42:56 -04:00
interface QRCodeComponentProps {
value: string;
isLogoRendered?: boolean;
isMenuAvailable?: boolean;
logoSize?: number;
size?: number;
ecl?: 'H' | 'Q' | 'M' | 'L';
onError?: () => void;
}
2024-11-15 22:32:50 +00:00
const BORDER_WIDTH = 6;
2023-03-23 22:42:56 -04:00
const actionIcons: { [key: string]: ActionIcons } = {
Share: {
iconValue: 'square.and.arrow.up',
},
Copy: {
iconValue: 'doc.on.doc',
},
};
2024-05-18 14:34:54 -04:00
const actionKeys = {
Share: 'share',
Copy: 'copy',
};
2024-05-18 12:48:03 -04:00
const menuActions: Action[] =
Platform.OS === 'ios' || Platform.OS === 'macos'
? [
{
2024-05-18 14:34:54 -04:00
id: actionKeys.Copy,
2024-05-18 12:48:03 -04:00
text: loc.transactions.details_copy,
icon: actionIcons.Copy,
},
{ id: actionKeys.Share, text: loc.receive.details_share, icon: actionIcons.Share },
2024-05-18 12:48:03 -04:00
]
: [
{
id: actionKeys.Copy,
text: loc.transactions.details_copy,
icon: actionIcons.Copy,
},
];
2024-05-18 12:48:03 -04:00
2023-03-23 22:42:56 -04:00
const QRCodeComponent: React.FC<QRCodeComponentProps> = ({
value = '',
2021-08-26 21:31:36 -04:00
isLogoRendered = true,
isMenuAvailable = true,
logoSize = 90,
2021-08-28 02:12:33 -04:00
size = 300,
2021-08-26 21:31:36 -04:00
ecl = 'H',
onError = () => {},
}) => {
2023-03-23 22:42:56 -04:00
const qrCode = useRef<any>();
2024-11-15 22:32:50 +00:00
const { colors, dark } = useTheme();
2021-08-26 21:31:36 -04:00
const handleShareQRCode = () => {
2023-03-23 22:42:56 -04:00
qrCode.current.toDataURL((data: string) => {
data = data.replace(/(\r\n|\n|\r)/gm, '');
2021-08-26 21:31:36 -04:00
const shareImageBase64 = {
url: `data:image/png;base64,${data}`,
};
2023-12-25 17:22:49 -04:00
Share.open(shareImageBase64).catch((error: Error) => console.log(error));
2021-08-26 21:31:36 -04:00
});
};
2024-06-17 15:38:01 -04:00
const onPressMenuItem = useCallback((id: string) => {
2024-05-18 14:34:54 -04:00
if (id === actionKeys.Share) {
2021-10-08 12:58:48 -04:00
handleShareQRCode();
2024-05-18 14:34:54 -04:00
} else if (id === actionKeys.Copy) {
2021-10-08 12:58:48 -04:00
qrCode.current.toDataURL(Clipboard.setImage);
}
2024-06-17 15:38:01 -04:00
}, []);
2021-10-08 12:58:48 -04:00
2024-11-15 22:32:50 +00:00
// 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 },
});
2021-08-26 21:31:36 -04:00
const renderQRCode = (
<QRCode
value={value}
{...(isLogoRendered ? { logo: require('../img/qr-code.png') } : {})}
2024-11-15 22:32:50 +00:00
size={newSize}
2021-08-26 21:31:36 -04:00
logoSize={logoSize}
color="#000000"
logoBackgroundColor={colors.brandingColor}
backgroundColor="#FFFFFF"
ecl={ecl}
2023-03-23 22:42:56 -04:00
getRef={(c: any) => (qrCode.current = c)}
2021-08-26 21:31:36 -04:00
onError={onError}
/>
);
return (
<View
2024-11-15 22:32:50 +00:00
style={[styles.container, stylesHook.container]}
testID="BitcoinAddressQRCodeContainer"
accessibilityIgnoresInvertColors
importantForAccessibility="no-hide-descendants"
accessibilityRole="image"
accessibilityLabel={loc.receive.qrcode_for_the_address}
>
2021-08-26 21:31:36 -04:00
{isMenuAvailable ? (
2024-05-18 12:48:03 -04:00
<ToolTipMenu actions={menuActions} onPressMenuItem={onPressMenuItem}>
2021-08-26 21:31:36 -04:00
{renderQRCode}
</ToolTipMenu>
) : (
renderQRCode
)}
</View>
);
};
export default QRCodeComponent;
const styles = StyleSheet.create({
2024-11-18 16:35:45 +00:00
container: { borderColor: '#FFFFFF' },
2021-08-26 21:31:36 -04:00
});