Files
inji-wallet/components/FaceScanner.tsx
PuBHARGAVI dd97a7dd1c [Injimob 917] Close only camera disabled banner when user clicks on close icon in banner (#1447)
* [INJIMOB-917] add enable permission text with underline in camera disabled banner

When user clicks on this, app will redirect the user to the app settings to enable the permissions

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* [INJIMOB-917] add translations for camera disable banner enable permission text

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* [INJIMOB-695] fix the logic of setting the isActive state of the app using AppState listener and fix the styles of Qr scanner

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* [INJIMOB-917]fix the styles of the camera disabled screen

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* [INJIMOB-917] revert appState listener changes in app.ts and set app active or inactive state everytime the app is launched

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* [INJIMOB-917] remove unused imports

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* [INJIMOB-917] remove unneccessary formatting change

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* [INJIMOB-917] fix the styles of camera scanner and add margin styles to the share screen

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* [INJIMOB-917] show activate option in kebab menu only if the VC has image

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* [INJIMOB-917] remove call to verifyIdentityOverlay component in scan Layout and receive vc screen files as we are not using it and move Invalid Identity component to verifyIdentityOverlay to remove redundancy

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

* [INJIMOB-917] change the height of camera scanner to 320 and reduce the margin top and bottom of the whole scanner component to 20

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>

---------

Signed-off-by: PuBHARGAVI <46226958+PuBHARGAVI@users.noreply.github.com>
2024-05-21 17:57:26 +05:30

141 lines
4.2 KiB
TypeScript

import React, {useCallback, useContext, useEffect, useRef} from 'react';
import {Camera} from 'expo-camera';
import {TouchableOpacity, View} from 'react-native';
import {Button, Centered, Column, Row, Text} from './ui';
import {useInterpret, useSelector} from '@xstate/react';
import {useTranslation} from 'react-i18next';
import {
FaceScannerEvents,
selectIsCheckingPermission,
selectIsValid,
selectIsPermissionDenied,
selectIsScanning,
selectWhichCamera,
createFaceScannerMachine,
selectIsInvalid,
selectIsCapturing,
selectIsVerifying,
} from '../machines/faceScanner';
import {GlobalContext} from '../shared/GlobalContext';
import {selectIsActive} from '../machines/app';
import {RotatingIcon} from './RotatingIcon';
import {Theme} from './ui/styleUtils';
import {SvgImage} from './ui/svg';
import testIDProps from '../shared/commonUtil';
export const FaceScanner: React.FC<FaceScannerProps> = props => {
const {t} = useTranslation('FaceScanner');
const {appService} = useContext(GlobalContext);
const isActive = useSelector(appService, selectIsActive);
const machine = useRef(createFaceScannerMachine(props.vcImage));
const service = useInterpret(machine.current);
const whichCamera = useSelector(service, selectWhichCamera);
const isPermissionDenied = useSelector(service, selectIsPermissionDenied);
const isValid = useSelector(service, selectIsValid);
const isInvalid = useSelector(service, selectIsInvalid);
const isCheckingPermission = useSelector(service, selectIsCheckingPermission);
const isScanning = useSelector(service, selectIsScanning);
const isCapturing = useSelector(service, selectIsCapturing);
const isVerifying = useSelector(service, selectIsVerifying);
const setCameraRef = useCallback(
(node: Camera) => {
if (node != null && !isScanning) {
service.send(FaceScannerEvents.READY(node));
}
},
[isScanning],
);
useEffect(() => {
if (isValid) {
props.onValid();
} else if (isInvalid) {
props.onInvalid();
}
}, [isValid, isInvalid]);
useEffect(() => {
if (isActive) {
service.send(FaceScannerEvents.APP_FOCUSED());
}
}, [isActive]);
if (isCheckingPermission) {
return <Column></Column>;
} else if (isPermissionDenied) {
return (
<Column padding="24" fill align="space-between">
<Text align="center" color={Theme.Colors.errorMessage}>
{t('missingPermissionText')}
</Text>
<Button
title={t('allowCameraButton')}
onPress={() => service.send(FaceScannerEvents.OPEN_SETTINGS())}
/>
</Column>
);
}
return (
<Column fill align="space-between">
<View style={Theme.CameraEnabledStyles.scannerContainer}>
<Camera
{...testIDProps('camera')}
style={Theme.CameraEnabledStyles.scanner}
type={whichCamera}
ref={setCameraRef}
/>
</View>
<Text
testID="imageCaptureGuide"
align="center"
weight="semibold"
style={Theme.TextStyles.base}
margin="0 57">
{t('imageCaptureGuide')}
</Text>
<Centered>
{isCapturing || isVerifying ? (
<RotatingIcon name="sync" size={64} />
) : (
<Row align="center">
<Centered style={Theme.Styles.imageCaptureButton}>
<TouchableOpacity
onPress={() => service.send(FaceScannerEvents.CAPTURE())}>
{SvgImage.CameraCaptureIcon()}
</TouchableOpacity>
<Text
testID="captureText"
style={Theme.CameraEnabledStyles.iconText}>
{t('capture')}
</Text>
</Centered>
<Centered>
<TouchableOpacity
onPress={() => service.send(FaceScannerEvents.FLIP_CAMERA())}>
{SvgImage.FlipCameraIcon()}
</TouchableOpacity>
<Text
testID="flipCameraText"
style={Theme.CameraEnabledStyles.iconText}>
{t('flipCamera')}
</Text>
</Centered>
</Row>
)}
</Centered>
</Column>
);
};
interface FaceScannerProps {
vcImage: string;
onValid: () => void;
onInvalid: () => void;
}