Files
inji-wallet/components/QrCodeOverlay.tsx
balachandarg-tw d1a9a3c7f5 Injimob 1204 share qr code (#1472)
* [INJIMOB-1204]: Renaming sharing utils file and removing state variable in QRCodeOverlay

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-1204]: Removing state variable for base64 string.

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-1204] : Error logging and renaming to imageUtils

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

* [INJIMOB-1204]: Renaming the function name

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>

---------

Signed-off-by: BalachandarG <balachandar.g@thoughtworks.com>
2024-06-03 15:55:54 +05:30

157 lines
5.0 KiB
TypeScript

import React, {useEffect, useRef, useState} from 'react';
import {Pressable, View} from 'react-native';
import {Icon, Overlay} from 'react-native-elements';
import {Centered, Column, Row, Text, Button} from './ui';
import QRCode from 'react-native-qrcode-svg';
import {Theme} from './ui/styleUtils';
import {useTranslation} from 'react-i18next';
import testIDProps from '../shared/commonUtil';
import {SvgImage} from './ui/svg';
import {NativeModules} from 'react-native';
import {VerifiableCredential} from '../machines/VerifiableCredential/VCMetaMachine/vc';
import RNSecureKeyStore, {ACCESSIBLE} from 'react-native-secure-key-store';
import {DEFAULT_ECL} from '../shared/constants';
import {VCMetadata} from '../shared/VCMetadata';
import {shareImageToAllSupportedApps} from '../shared/sharing/imageUtils';
import {ShareOptions} from 'react-native-share';
export const QrCodeOverlay: React.FC<QrCodeOverlayProps> = props => {
const {RNPixelpassModule} = NativeModules;
const {t} = useTranslation('VcDetails');
const [qrString, setQrString] = useState('');
const [qrError, setQrError] = useState(false);
const base64ImageType = 'data:image/png;base64,';
async function getQRData(): Promise<string> {
let qrData: string;
try {
qrData = await RNSecureKeyStore.get(props.meta.id);
} catch {
qrData = await RNPixelpassModule.generateQRData(
JSON.stringify(props.verifiableCredential),
'',
);
await RNSecureKeyStore.set(props.meta.id, qrData, {
accessible: ACCESSIBLE.ALWAYS_THIS_DEVICE_ONLY,
});
}
return qrData;
}
let qrRef = useRef(null);
function handleShareQRCodePress() {
qrRef.current.toDataURL(dataURL => {
shareImage(`${base64ImageType}${dataURL}`);
});
}
async function shareImage(base64String: string) {
const options: ShareOptions = {
message: t('scanToViewCredential'),
url: base64String,
};
const shareStatus = await shareImageToAllSupportedApps(options);
if (!shareStatus) {
console.error('Error while sharing QR code::');
}
}
function onQRError() {
console.warn('Data is too big');
setQrError(true);
}
useEffect(() => {
(async () => {
const qrData = await getQRData();
setQrString(qrData);
})();
}, []);
const [isQrOverlayVisible, setIsQrOverlayVisible] = useState(false);
const toggleQrOverlay = () => setIsQrOverlayVisible(!isQrOverlayVisible);
return (
qrString != '' &&
!qrError && (
<React.Fragment>
<View testID="qrCodeView" style={Theme.QrCodeStyles.QrView}>
<Pressable
{...testIDProps('qrCodePressable')}
accessible={false}
onPress={toggleQrOverlay}>
<QRCode
{...testIDProps('qrCode')}
size={72}
value={qrString}
backgroundColor={Theme.Colors.QRCodeBackgroundColor}
ecl={DEFAULT_ECL}
onError={onQRError}
/>
<View
testID="magnifierZoom"
style={[Theme.QrCodeStyles.magnifierZoom]}>
{SvgImage.MagnifierZoom()}
</View>
</Pressable>
</View>
<Overlay
isVisible={isQrOverlayVisible}
onBackdropPress={toggleQrOverlay}
overlayStyle={{padding: 1, borderRadius: 21}}>
<Column style={Theme.QrCodeStyles.expandedQrCode}>
<Row pY={20} style={Theme.QrCodeStyles.QrCodeHeader}>
<Text
testID="qrCodeHeader"
align="center"
style={Theme.TextStyles.header}
weight="bold">
{t('qrCodeHeader')}
</Text>
<Icon
{...testIDProps('qrCodeCloseIcon')}
name="close"
onPress={toggleQrOverlay}
color={Theme.Colors.Details}
size={32}
/>
</Row>
<Centered testID="qrCodeDetails" pY={30}>
<QRCode
{...testIDProps('qrCodeExpandedView')}
size={300}
value={qrString}
backgroundColor={Theme.Colors.QRCodeBackgroundColor}
ecl={DEFAULT_ECL}
onError={onQRError}
getRef={data => (qrRef.current = data)}
/>
<Button
testID="share"
styles={Theme.QrCodeStyles.shareQrCodeButton}
title={t('shareQRCode')}
type="gradient"
icon={
<Icon
name="share-variant-outline"
type="material-community"
size={24}
color="white"
/>
}
onPress={handleShareQRCodePress}
/>
</Centered>
</Column>
</Overlay>
</React.Fragment>
)
);
};
interface QrCodeOverlayProps {
verifiableCredential: VerifiableCredential;
meta: VCMetadata;
}