mirror of
https://github.com/mosip/inji-wallet.git
synced 2026-01-08 05:03:56 -05:00
* [INJIMOB-956]: Android native module integration Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> * [INJIMOB-956]: iOS native module integration and react native layer Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> * [INJIMOB-956]: React native UI design changes Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> * [INJIMOB-3499]: Updating android native module integration to adapt latest chagnes in libray api Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> * [INJIMOB-3499]: Updated Native module integration Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> * [INJIMOB-956]: Update tht package dependency version Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> * [INJIMOB-956]: Loading before SVg rendering issue fixed Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> * [INJIMOB-956]: show Qr code button based on fallback image id Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> * [INJIMOB-956]: Update Swift package dependency Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> * [INJIMOB-3499]: Update Swift Package dependency to develop of Renderer library Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> * [INJIMOB-956]: Update in received screen Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> * [INJIMOB-956]: Update format in renderVC call Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> * [INJIMOB-956]: Change ordering of the params Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> * [INJIMOB-956]: Changes in caching Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> * [INJIMOB-956]: Updating the package dependency files Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com> --------- Signed-off-by: balachandarg-tw <balachandar.g@thoughtworks.com>
176 lines
5.5 KiB
TypeScript
176 lines
5.5 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 {DEFAULT_ECL, MAX_QR_DATA_LENGTH} 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,';
|
|
const {RNSecureKeystoreModule} = NativeModules;
|
|
|
|
async function getQRData(): Promise<string> {
|
|
let qrData: string;
|
|
try {
|
|
const keyData = await RNSecureKeystoreModule.getData(props.meta.id);
|
|
if (keyData[1] && keyData.length > 0) {
|
|
qrData = keyData[1];
|
|
} else {
|
|
throw new Error('No key data found');
|
|
}
|
|
} catch {
|
|
const {credential} = props.verifiableCredential;
|
|
qrData = await RNPixelpassModule.generateQRData(
|
|
JSON.stringify(credential),
|
|
'',
|
|
);
|
|
await RNSecureKeystoreModule.storeData(props.meta.id, qrData);
|
|
}
|
|
return qrData;
|
|
}
|
|
|
|
let qrRef = useRef(null);
|
|
|
|
function handleShareQRCodePress() {
|
|
qrRef.current.toDataURL(dataURL => {
|
|
shareImage(`${base64ImageType}${dataURL}`);
|
|
});
|
|
}
|
|
|
|
async function shareImage(base64String: string) {
|
|
const options: ShareOptions = {
|
|
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();
|
|
if (qrData?.length < MAX_QR_DATA_LENGTH) {
|
|
setQrString(qrData);
|
|
} else {
|
|
setQrError(true);
|
|
}
|
|
})();
|
|
}, []);
|
|
const [isQrOverlayVisible, setIsQrOverlayVisible] = useState(false);
|
|
|
|
const overlayVisible = props.forceVisible ?? isQrOverlayVisible;
|
|
|
|
const toggleQrOverlay = () => {
|
|
if (props.onClose) props.onClose();
|
|
else setIsQrOverlayVisible(!overlayVisible);
|
|
};
|
|
|
|
return (
|
|
qrString != '' &&
|
|
!qrError && (
|
|
<React.Fragment>
|
|
<View testID="qrCodeView" style={Theme.QrCodeStyles.QrView}>
|
|
{props.showInlineQr !== false && (
|
|
<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={overlayVisible}
|
|
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}
|
|
quietZone={10}
|
|
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;
|
|
showInlineQr?: boolean;
|
|
forceVisible?: boolean;
|
|
onClose?: () => void;
|
|
}
|