@aws-amplify/ui-react-liveness 3.3.8 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -15
- package/dist/esm/components/FaceLivenessDetector/FaceLivenessDetectorCore.mjs +4 -2
- package/dist/esm/components/FaceLivenessDetector/LivenessCheck/CameraSelector.mjs +13 -0
- package/dist/esm/components/FaceLivenessDetector/LivenessCheck/LivenessCameraModule.mjs +50 -28
- package/dist/esm/components/FaceLivenessDetector/LivenessCheck/LivenessCheck.mjs +5 -4
- package/dist/esm/components/FaceLivenessDetector/service/machine/machine.mjs +247 -314
- package/dist/esm/components/FaceLivenessDetector/service/utils/ColorSequenceDisplay/ColorSequenceDisplay.mjs +140 -0
- package/dist/esm/components/FaceLivenessDetector/service/utils/StreamRecorder/StreamRecorder.mjs +171 -0
- package/dist/esm/components/FaceLivenessDetector/service/utils/TelemetryReporter/TelemetryReporter.mjs +27 -0
- package/dist/esm/components/FaceLivenessDetector/service/utils/constants.mjs +30 -7
- package/dist/esm/components/FaceLivenessDetector/service/utils/createRequestStreamGenerator/createRequestStreamGenerator.mjs +32 -0
- package/dist/esm/components/FaceLivenessDetector/service/utils/createRequestStreamGenerator/utils.mjs +148 -0
- package/dist/esm/components/FaceLivenessDetector/service/utils/createStreamingClient/Signer.mjs +2 -3
- package/dist/esm/components/FaceLivenessDetector/service/utils/createStreamingClient/createStreamingClient.mjs +36 -6
- package/dist/esm/components/FaceLivenessDetector/service/utils/createStreamingClient/resolveCredentials.mjs +7 -6
- package/dist/esm/components/FaceLivenessDetector/service/utils/getFaceMatchStateInLivenessOval.mjs +9 -5
- package/dist/esm/components/FaceLivenessDetector/service/utils/liveness.mjs +19 -34
- package/dist/esm/components/FaceLivenessDetector/service/utils/{eventUtils.mjs → responseStreamEvent.mjs} +2 -2
- package/dist/esm/components/FaceLivenessDetector/service/utils/sessionInformation.mjs +45 -0
- package/dist/esm/components/FaceLivenessDetector/shared/DefaultStartScreenComponents.mjs +3 -2
- package/dist/esm/components/FaceLivenessDetector/shared/FaceLivenessErrorModal.mjs +4 -2
- package/dist/esm/components/FaceLivenessDetector/shared/Hint.mjs +4 -7
- package/dist/esm/components/FaceLivenessDetector/types/classNames.mjs +3 -0
- package/dist/esm/components/FaceLivenessDetector/utils/device.mjs +12 -12
- package/dist/esm/index.mjs +12 -0
- package/dist/esm/version.mjs +1 -1
- package/dist/index.js +956 -775
- package/dist/styles.css +17 -2
- package/dist/types/components/FaceLivenessDetector/FaceLivenessDetector.d.ts +3 -3
- package/dist/types/components/FaceLivenessDetector/FaceLivenessDetectorCore.d.ts +3 -3
- package/dist/types/components/FaceLivenessDetector/LivenessCheck/CameraSelector.d.ts +8 -0
- package/dist/types/components/FaceLivenessDetector/LivenessCheck/LivenessCameraModule.d.ts +3 -2
- package/dist/types/components/FaceLivenessDetector/LivenessCheck/LivenessCheck.d.ts +2 -2
- package/dist/types/components/FaceLivenessDetector/displayText.d.ts +1 -1
- package/dist/types/components/FaceLivenessDetector/hooks/useLivenessSelector.d.ts +1 -1
- package/dist/types/components/FaceLivenessDetector/index.d.ts +6 -3
- package/dist/types/components/FaceLivenessDetector/providers/FaceLivenessDetectorProvider.d.ts +1 -1
- package/dist/types/components/FaceLivenessDetector/service/machine/machine.d.ts +1 -1
- package/dist/types/components/FaceLivenessDetector/service/types/credentials.d.ts +1 -1
- package/dist/types/components/FaceLivenessDetector/service/types/liveness.d.ts +2 -2
- package/dist/types/components/FaceLivenessDetector/service/types/machine.d.ts +40 -27
- package/dist/types/components/FaceLivenessDetector/service/utils/ColorSequenceDisplay/ColorSequenceDisplay.d.ts +55 -0
- package/dist/types/components/FaceLivenessDetector/service/utils/ColorSequenceDisplay/index.d.ts +2 -0
- package/dist/types/components/FaceLivenessDetector/service/utils/StreamRecorder/StreamRecorder.d.ts +15 -0
- package/dist/types/components/FaceLivenessDetector/service/utils/StreamRecorder/index.d.ts +1 -0
- package/dist/types/components/FaceLivenessDetector/service/utils/TelemetryReporter/TelemetryReporter.d.ts +8 -0
- package/dist/types/components/FaceLivenessDetector/service/utils/TelemetryReporter/index.d.ts +2 -0
- package/dist/types/components/FaceLivenessDetector/service/utils/blazefaceFaceDetection.d.ts +2 -1
- package/dist/types/components/FaceLivenessDetector/service/utils/constants.d.ts +27 -3
- package/dist/types/components/FaceLivenessDetector/service/utils/createRequestStreamGenerator/createRequestStreamGenerator.d.ts +15 -0
- package/dist/types/components/FaceLivenessDetector/service/utils/createRequestStreamGenerator/index.d.ts +2 -0
- package/dist/types/components/FaceLivenessDetector/service/utils/createRequestStreamGenerator/utils.d.ts +30 -0
- package/dist/types/components/FaceLivenessDetector/service/utils/createStreamingClient/CustomWebSocketFetchHandler.d.ts +3 -2
- package/dist/types/components/FaceLivenessDetector/service/utils/createStreamingClient/Signer.d.ts +1 -2
- package/dist/types/components/FaceLivenessDetector/service/utils/createStreamingClient/createStreamingClient.d.ts +28 -6
- package/dist/types/components/FaceLivenessDetector/service/utils/createStreamingClient/index.d.ts +1 -0
- package/dist/types/components/FaceLivenessDetector/service/utils/createStreamingClient/resolveCredentials.d.ts +1 -1
- package/dist/types/components/FaceLivenessDetector/service/utils/createStreamingClient/types.d.ts +1 -1
- package/dist/types/components/FaceLivenessDetector/service/utils/getFaceMatchStateInLivenessOval.d.ts +4 -4
- package/dist/types/components/FaceLivenessDetector/service/utils/index.d.ts +7 -4
- package/dist/types/components/FaceLivenessDetector/service/utils/liveness.d.ts +16 -26
- package/dist/types/components/FaceLivenessDetector/service/utils/{eventUtils.d.ts → responseStreamEvent.d.ts} +2 -2
- package/dist/types/components/FaceLivenessDetector/service/utils/sessionInformation.d.ts +7 -0
- package/dist/types/components/FaceLivenessDetector/service/utils/types.d.ts +21 -0
- package/dist/types/components/FaceLivenessDetector/shared/DefaultStartScreenComponents.d.ts +1 -1
- package/dist/types/components/FaceLivenessDetector/shared/FaceLivenessErrorModal.d.ts +2 -2
- package/dist/types/components/FaceLivenessDetector/shared/Hint.d.ts +1 -1
- package/dist/types/components/FaceLivenessDetector/shared/Overlay.d.ts +1 -1
- package/dist/types/components/FaceLivenessDetector/shared/Toast.d.ts +1 -1
- package/dist/types/components/FaceLivenessDetector/types/classNames.d.ts +3 -0
- package/dist/types/components/FaceLivenessDetector/utils/device.d.ts +1 -0
- package/dist/types/components/FaceLivenessDetector/utils/getDisplayText.d.ts +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +10 -10
- package/dist/esm/components/FaceLivenessDetector/service/utils/freshnessColorDisplay.mjs +0 -131
- package/dist/esm/components/FaceLivenessDetector/service/utils/streamProvider.mjs +0 -126
- package/dist/esm/components/FaceLivenessDetector/service/utils/videoRecorder.mjs +0 -108
- package/dist/types/components/FaceLivenessDetector/service/types/service.d.ts +0 -5
- package/dist/types/components/FaceLivenessDetector/service/utils/freshnessColorDisplay.d.ts +0 -21
- package/dist/types/components/FaceLivenessDetector/service/utils/streamProvider.d.ts +0 -42
- package/dist/types/components/FaceLivenessDetector/service/utils/videoRecorder.d.ts +0 -27
package/README.md
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
# Amplify UI
|
|
1
|
+
# Amplify UI React Liveness
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The React Liveness package provides components for face liveness detection in Amplify connected applications.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
2. Primitive components that create consistency across Amplify UI and allow you to build complete applications that fit your brand, like Buttons and Badges.
|
|
7
|
-
3. Data-bound components that make it easy to display dynamic data, like DataStoreCollections.
|
|
8
|
-
4. Theming capabilities that allow you to customize the appearance of Amplify UI to match your brand.
|
|
5
|
+
## Contents
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
### Core Components
|
|
11
8
|
|
|
12
|
-
-
|
|
9
|
+
- `FaceLivenessDetector` - Component for face liveness detection
|
|
10
|
+
- `FaceLivenessDetectorCore` - Core component for face liveness detection
|
|
13
11
|
|
|
14
|
-
|
|
12
|
+
### Type Definitions
|
|
15
13
|
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
14
|
+
- `FaceLivenessDetectorProps` - Props for FaceLivenessDetector component
|
|
15
|
+
- `FaceLivenessDetectorCoreProps` - Props for FaceLivenessDetectorCore component
|
|
16
|
+
- `AwsCredentialProvider` - Type for AWS credential provider
|
|
17
|
+
- `AwsCredentials` - Type for AWS credentials
|
|
18
|
+
- `AwsTemporaryCredentials` - Type for AWS temporary credentials
|
|
19
|
+
- `ErrorState` - Type for error state
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## React Documentation
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
- https://ui.docs.amplify.aws/react
|
|
@@ -7,9 +7,11 @@ import '@tensorflow-models/face-detection';
|
|
|
7
7
|
import '@tensorflow/tfjs-backend-wasm';
|
|
8
8
|
import '@tensorflow/tfjs-backend-cpu';
|
|
9
9
|
import '@aws-amplify/core/internals/utils';
|
|
10
|
-
import '
|
|
10
|
+
import './service/utils/constants.mjs';
|
|
11
|
+
import './service/utils/ColorSequenceDisplay/ColorSequenceDisplay.mjs';
|
|
12
|
+
import '@aws-amplify/ui';
|
|
11
13
|
import './service/utils/createStreamingClient/createStreamingClient.mjs';
|
|
12
|
-
import './service/utils/
|
|
14
|
+
import './service/utils/StreamRecorder/StreamRecorder.mjs';
|
|
13
15
|
import { View, Flex } from '@aws-amplify/ui-react';
|
|
14
16
|
import { FaceLivenessDetectorProvider } from './providers/FaceLivenessDetectorProvider.mjs';
|
|
15
17
|
import { LivenessCheck } from './LivenessCheck/LivenessCheck.mjs';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Flex, View, Label, SelectField } from '@aws-amplify/ui-react';
|
|
2
|
+
import React__default from 'react';
|
|
3
|
+
import { LivenessClassNames } from '../types/classNames.mjs';
|
|
4
|
+
|
|
5
|
+
const CameraSelector = (props) => {
|
|
6
|
+
const { onSelect: onCameraChange, devices: selectableDevices, deviceId: selectedDeviceId, } = props;
|
|
7
|
+
return (React__default.createElement(Flex, { className: LivenessClassNames.StartScreenCameraSelect },
|
|
8
|
+
React__default.createElement(View, { className: LivenessClassNames.StartScreenCameraSelectContainer },
|
|
9
|
+
React__default.createElement(Label, { htmlFor: "amplify-liveness-camera-select", className: `${LivenessClassNames.StartScreenCameraSelect}__label` }, "Camera:"),
|
|
10
|
+
React__default.createElement(SelectField, { id: "amplify-liveness-camera-select", testId: "amplify-liveness-camera-select", label: "Camera", labelHidden: true, value: selectedDeviceId, onChange: onCameraChange }, selectableDevices.map((device) => (React__default.createElement("option", { value: device.deviceId, key: device.deviceId }, device.label)))))));
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { CameraSelector };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React__default, { useRef, useState } from 'react';
|
|
2
2
|
import { classNames } from '@aws-amplify/ui';
|
|
3
|
-
import {
|
|
3
|
+
import { View, Flex, Loader, Text, Button } from '@aws-amplify/ui-react';
|
|
4
4
|
import { useColorMode } from '@aws-amplify/ui-react/internal';
|
|
5
5
|
import '../service/machine/machine.mjs';
|
|
6
6
|
import { FaceMatchState } from '../service/types/liveness.mjs';
|
|
@@ -10,9 +10,10 @@ import '@tensorflow/tfjs-backend-wasm';
|
|
|
10
10
|
import '@tensorflow/tfjs-backend-cpu';
|
|
11
11
|
import '@aws-amplify/core/internals/utils';
|
|
12
12
|
import { drawStaticOval, clearOvalCanvas } from '../service/utils/liveness.mjs';
|
|
13
|
-
import '
|
|
13
|
+
import { FACE_MOVEMENT_CHALLENGE } from '../service/utils/constants.mjs';
|
|
14
|
+
import '../service/utils/ColorSequenceDisplay/ColorSequenceDisplay.mjs';
|
|
14
15
|
import '../service/utils/createStreamingClient/createStreamingClient.mjs';
|
|
15
|
-
import '../service/utils/
|
|
16
|
+
import '../service/utils/StreamRecorder/StreamRecorder.mjs';
|
|
16
17
|
import { useLivenessActor } from '../hooks/useLivenessActor.mjs';
|
|
17
18
|
import { useLivenessSelector, createLivenessSelector } from '../hooks/useLivenessSelector.mjs';
|
|
18
19
|
import { useMediaStreamInVideo } from '../hooks/useMediaStreamInVideo.mjs';
|
|
@@ -20,16 +21,18 @@ import { LivenessClassNames } from '../types/classNames.mjs';
|
|
|
20
21
|
import { selectErrorState, Hint } from '../shared/Hint.mjs';
|
|
21
22
|
import { MatchIndicator } from '../shared/MatchIndicator.mjs';
|
|
22
23
|
import { Overlay } from '../shared/Overlay.mjs';
|
|
24
|
+
import { isDeviceUserFacing } from '../utils/device.mjs';
|
|
23
25
|
import { FaceLivenessErrorModal, renderErrorModal } from '../shared/FaceLivenessErrorModal.mjs';
|
|
24
26
|
import { DefaultPhotosensitiveWarning, DefaultRecordingIcon, DefaultCancelButton } from '../shared/DefaultStartScreenComponents.mjs';
|
|
27
|
+
import { CameraSelector } from './CameraSelector.mjs';
|
|
25
28
|
|
|
29
|
+
const selectChallengeType = createLivenessSelector((state) => state.context.parsedSessionInformation?.Challenge?.Name);
|
|
26
30
|
const selectVideoConstraints = createLivenessSelector((state) => state.context.videoAssociatedParams?.videoConstraints);
|
|
27
31
|
const selectVideoStream = createLivenessSelector((state) => state.context.videoAssociatedParams?.videoMediaStream);
|
|
28
32
|
const selectFaceMatchPercentage = createLivenessSelector((state) => state.context.faceMatchAssociatedParams?.faceMatchPercentage);
|
|
29
33
|
const selectFaceMatchState = createLivenessSelector((state) => state.context.faceMatchAssociatedParams?.faceMatchState);
|
|
30
34
|
const selectSelectedDeviceId = createLivenessSelector((state) => state.context.videoAssociatedParams?.selectedDeviceId);
|
|
31
35
|
const selectSelectableDevices = createLivenessSelector((state) => state.context.videoAssociatedParams?.selectableDevices);
|
|
32
|
-
const centeredLoader = (React__default.createElement(Loader, { size: "large", className: LivenessClassNames.Loader, "data-testid": "centered-loader" }));
|
|
33
36
|
const showMatchIndicatorStates = [
|
|
34
37
|
FaceMatchState.TOO_FAR,
|
|
35
38
|
FaceMatchState.CANT_IDENTIFY,
|
|
@@ -47,6 +50,7 @@ const LivenessCameraModule = (props) => {
|
|
|
47
50
|
const { cancelLivenessCheckText, recordingIndicatorText } = streamDisplayText;
|
|
48
51
|
const { ErrorView = FaceLivenessErrorModal, PhotosensitiveWarning = DefaultPhotosensitiveWarning, } = customComponents ?? {};
|
|
49
52
|
const [state, send] = useLivenessActor();
|
|
53
|
+
const isFaceMovementChallenge = useLivenessSelector(selectChallengeType) === FACE_MOVEMENT_CHALLENGE.type;
|
|
50
54
|
const videoStream = useLivenessSelector(selectVideoStream);
|
|
51
55
|
const videoConstraints = useLivenessSelector(selectVideoConstraints);
|
|
52
56
|
const selectedDeviceId = useLivenessSelector(selectSelectedDeviceId);
|
|
@@ -59,8 +63,14 @@ const LivenessCameraModule = (props) => {
|
|
|
59
63
|
const canvasRef = useRef(null);
|
|
60
64
|
const freshnessColorRef = useRef(null);
|
|
61
65
|
const [isCameraReady, setIsCameraReady] = useState(false);
|
|
62
|
-
const
|
|
63
|
-
const
|
|
66
|
+
const [isMetadataLoaded, setIsMetadataLoaded] = useState(false);
|
|
67
|
+
const [isCameraUserFacing, setIsCameraUserFacing] = useState(true);
|
|
68
|
+
const isInitCamera = state.matches('initCamera');
|
|
69
|
+
const isInitWebsocket = state.matches('initWebsocket');
|
|
70
|
+
const isCheckingCamera = state.matches({ initCamera: 'cameraCheck' });
|
|
71
|
+
const isWaitingForCamera = state.matches({
|
|
72
|
+
initCamera: 'waitForDOMAndCameraDetails',
|
|
73
|
+
});
|
|
64
74
|
const isStartView = state.matches('start') || state.matches('userCancel');
|
|
65
75
|
const isDetectFaceBeforeStart = state.matches('detectFaceBeforeStart');
|
|
66
76
|
const isRecording = state.matches('recording');
|
|
@@ -74,18 +84,29 @@ const LivenessCameraModule = (props) => {
|
|
|
74
84
|
const [mediaWidth, setMediaWidth] = useState(videoWidth);
|
|
75
85
|
const [mediaHeight, setMediaHeight] = useState(videoHeight);
|
|
76
86
|
const [aspectRatio, setAspectRatio] = useState(() => videoWidth && videoHeight ? videoWidth / videoHeight : 0);
|
|
87
|
+
// Only mobile device camera selection for no light challenge
|
|
88
|
+
const hasMultipleDevices = !!selectableDevices?.length && selectableDevices.length > 1;
|
|
89
|
+
const allowDeviceSelection = isStartView &&
|
|
90
|
+
hasMultipleDevices &&
|
|
91
|
+
(!isMobileScreen || isFaceMovementChallenge);
|
|
77
92
|
React__default.useEffect(() => {
|
|
78
|
-
|
|
79
|
-
|
|
93
|
+
async function checkCameraFacing() {
|
|
94
|
+
const isUserFacing = await isDeviceUserFacing(selectedDeviceId);
|
|
95
|
+
setIsCameraUserFacing(isUserFacing);
|
|
80
96
|
}
|
|
81
|
-
|
|
97
|
+
checkCameraFacing();
|
|
98
|
+
}, [selectedDeviceId]);
|
|
82
99
|
React__default.useEffect(() => {
|
|
100
|
+
const shouldDrawOval = canvasRef?.current &&
|
|
101
|
+
videoRef?.current &&
|
|
102
|
+
videoStream &&
|
|
103
|
+
isStartView &&
|
|
104
|
+
isMetadataLoaded;
|
|
105
|
+
if (shouldDrawOval) {
|
|
106
|
+
drawStaticOval(canvasRef.current, videoRef.current, videoStream);
|
|
107
|
+
}
|
|
83
108
|
const updateColorModeHandler = (e) => {
|
|
84
|
-
if (e.matches &&
|
|
85
|
-
canvasRef?.current &&
|
|
86
|
-
videoRef?.current &&
|
|
87
|
-
videoStream &&
|
|
88
|
-
isStartView) {
|
|
109
|
+
if (e.matches && shouldDrawOval) {
|
|
89
110
|
drawStaticOval(canvasRef.current, videoRef.current, videoStream);
|
|
90
111
|
}
|
|
91
112
|
};
|
|
@@ -97,7 +118,7 @@ const LivenessCameraModule = (props) => {
|
|
|
97
118
|
darkModePreference.removeEventListener('change', updateColorModeHandler);
|
|
98
119
|
lightModePreference.addEventListener('change', updateColorModeHandler);
|
|
99
120
|
};
|
|
100
|
-
}, [
|
|
121
|
+
}, [videoRef, videoStream, colorMode, isStartView, isMetadataLoaded]);
|
|
101
122
|
React__default.useLayoutEffect(() => {
|
|
102
123
|
if (isCameraReady) {
|
|
103
124
|
send({
|
|
@@ -128,6 +149,9 @@ const LivenessCameraModule = (props) => {
|
|
|
128
149
|
const handleMediaPlay = () => {
|
|
129
150
|
setIsCameraReady(true);
|
|
130
151
|
};
|
|
152
|
+
const handleLoadedMetadata = () => {
|
|
153
|
+
setIsMetadataLoaded(true);
|
|
154
|
+
};
|
|
131
155
|
const beginLivenessCheck = React__default.useCallback(() => {
|
|
132
156
|
send({
|
|
133
157
|
type: 'BEGIN',
|
|
@@ -136,6 +160,7 @@ const LivenessCameraModule = (props) => {
|
|
|
136
160
|
const onCameraChange = React__default.useCallback((e) => {
|
|
137
161
|
const newDeviceId = e.target.value;
|
|
138
162
|
const changeCamera = async () => {
|
|
163
|
+
setIsMetadataLoaded(false);
|
|
139
164
|
const newStream = await navigator.mediaDevices.getUserMedia({
|
|
140
165
|
video: {
|
|
141
166
|
...videoConstraints,
|
|
@@ -152,16 +177,19 @@ const LivenessCameraModule = (props) => {
|
|
|
152
177
|
}, [videoConstraints, send]);
|
|
153
178
|
if (isCheckingCamera) {
|
|
154
179
|
return (React__default.createElement(Flex, { justifyContent: 'center', className: LivenessClassNames.StartScreenCameraWaiting },
|
|
155
|
-
React__default.createElement(Loader, { size: "large", className: LivenessClassNames.
|
|
180
|
+
React__default.createElement(Loader, { size: "large", className: LivenessClassNames.CenteredLoader, "data-testid": "centered-loader", position: "unset" }),
|
|
156
181
|
React__default.createElement(Text, { fontSize: "large", fontWeight: "bold", "data-testid": "waiting-camera-permission", className: `${LivenessClassNames.StartScreenCameraWaiting}__text` }, cameraDisplayText.waitingCameraPermissionText)));
|
|
157
182
|
}
|
|
183
|
+
const shouldShowCenteredLoader = isInitCamera || isInitWebsocket;
|
|
158
184
|
// We don't show full screen camera on the pre check screen (isStartView/isWaitingForCamera)
|
|
159
|
-
const shouldShowFullScreenCamera = isMobileScreen && !isStartView && !
|
|
185
|
+
const shouldShowFullScreenCamera = isMobileScreen && !isStartView && !shouldShowCenteredLoader;
|
|
160
186
|
return (React__default.createElement(React__default.Fragment, null,
|
|
161
|
-
photoSensitivityWarning,
|
|
187
|
+
!isFaceMovementChallenge && photoSensitivityWarning,
|
|
188
|
+
shouldShowCenteredLoader && (React__default.createElement(Flex, { className: LivenessClassNames.ConnectingLoader },
|
|
189
|
+
React__default.createElement(Loader, { size: "large", className: LivenessClassNames.Loader, "data-testid": "centered-loader" }),
|
|
190
|
+
React__default.createElement(Text, { className: LivenessClassNames.LandscapeErrorModalHeader }, hintDisplayText.hintConnectingText))),
|
|
162
191
|
React__default.createElement(Flex, { className: classNames(LivenessClassNames.CameraModule, shouldShowFullScreenCamera &&
|
|
163
192
|
`${LivenessClassNames.CameraModule}--mobile`), "data-testid": testId, gap: "zero" },
|
|
164
|
-
!isCameraReady && centeredLoader,
|
|
165
193
|
React__default.createElement(Overlay, { horizontal: "center", vertical: isRecording && !isFlashingFreshness ? 'start' : 'space-between', className: LivenessClassNames.InstructionOverlay },
|
|
166
194
|
isRecording && (React__default.createElement(DefaultRecordingIcon, { recordingIndicatorText: recordingIndicatorText })),
|
|
167
195
|
!isStartView && !isWaitingForCamera && !isCheckSucceeded && (React__default.createElement(DefaultCancelButton, { cancelLivenessCheckText: cancelLivenessCheckText })),
|
|
@@ -180,19 +208,13 @@ const LivenessCameraModule = (props) => {
|
|
|
180
208
|
React__default.createElement(View, { className: LivenessClassNames.VideoAnchor, style: {
|
|
181
209
|
aspectRatio: `${aspectRatio}`,
|
|
182
210
|
} },
|
|
183
|
-
React__default.createElement("video", { ref: videoRef, muted: true, autoPlay: true, playsInline: true, width: mediaWidth, height: mediaHeight, onCanPlay: handleMediaPlay, "data-testid": "video", className: classNames(LivenessClassNames.Video, isRecordingStopped && LivenessClassNames.FadeOut), "aria-label": cameraDisplayText.a11yVideoLabelText }),
|
|
211
|
+
React__default.createElement("video", { ref: videoRef, muted: true, autoPlay: true, playsInline: true, width: mediaWidth, height: mediaHeight, onCanPlay: handleMediaPlay, onLoadedMetadata: handleLoadedMetadata, "data-testid": "video", className: classNames(LivenessClassNames.Video, isCameraUserFacing && LivenessClassNames.UserFacingVideo, isRecordingStopped && LivenessClassNames.FadeOut), "aria-label": cameraDisplayText.a11yVideoLabelText }),
|
|
184
212
|
React__default.createElement(Flex, { className: classNames(LivenessClassNames.OvalCanvas, shouldShowFullScreenCamera &&
|
|
185
213
|
`${LivenessClassNames.OvalCanvas}--mobile`, isRecordingStopped && LivenessClassNames.FadeOut) },
|
|
186
214
|
React__default.createElement(View, { as: "canvas", ref: canvasRef })),
|
|
187
|
-
|
|
188
|
-
!isMobileScreen &&
|
|
189
|
-
selectableDevices &&
|
|
190
|
-
selectableDevices.length > 1 && (React__default.createElement(Flex, { className: LivenessClassNames.StartScreenCameraSelect },
|
|
191
|
-
React__default.createElement(View, { className: LivenessClassNames.StartScreenCameraSelectContainer },
|
|
192
|
-
React__default.createElement(Label, { htmlFor: "amplify-liveness-camera-select", className: `${LivenessClassNames.StartScreenCameraSelect}__label` }, "Camera:"),
|
|
193
|
-
React__default.createElement(SelectField, { id: "amplify-liveness-camera-select", label: "Camera", labelHidden: true, value: selectedDeviceId, onChange: onCameraChange }, selectableDevices?.map((device) => (React__default.createElement("option", { value: device.deviceId, key: device.deviceId }, device.label))))))))),
|
|
215
|
+
allowDeviceSelection ? (React__default.createElement(CameraSelector, { onSelect: onCameraChange, devices: selectableDevices, deviceId: selectedDeviceId })) : null)),
|
|
194
216
|
isStartView && (React__default.createElement(Flex, { justifyContent: "center" },
|
|
195
217
|
React__default.createElement(Button, { variation: "primary", type: "button", onClick: beginLivenessCheck }, instructionDisplayText.startScreenBeginCheckText)))));
|
|
196
218
|
};
|
|
197
219
|
|
|
198
|
-
export { LivenessCameraModule, selectFaceMatchPercentage, selectFaceMatchState, selectSelectableDevices, selectSelectedDeviceId, selectVideoConstraints, selectVideoStream };
|
|
220
|
+
export { LivenessCameraModule, selectChallengeType, selectFaceMatchPercentage, selectFaceMatchState, selectSelectableDevices, selectSelectedDeviceId, selectVideoConstraints, selectVideoStream };
|
|
@@ -8,14 +8,15 @@ import '@tensorflow-models/face-detection';
|
|
|
8
8
|
import '@tensorflow/tfjs-backend-wasm';
|
|
9
9
|
import '@tensorflow/tfjs-backend-cpu';
|
|
10
10
|
import '@aws-amplify/core/internals/utils';
|
|
11
|
-
import
|
|
12
|
-
import '
|
|
11
|
+
import '../service/utils/constants.mjs';
|
|
12
|
+
import '../service/utils/ColorSequenceDisplay/ColorSequenceDisplay.mjs';
|
|
13
|
+
import '@aws-amplify/ui';
|
|
13
14
|
import '../service/utils/createStreamingClient/createStreamingClient.mjs';
|
|
14
|
-
import '../service/utils/
|
|
15
|
+
import '../service/utils/StreamRecorder/StreamRecorder.mjs';
|
|
15
16
|
import { LivenessCameraModule } from './LivenessCameraModule.mjs';
|
|
16
17
|
import { useLivenessActor } from '../hooks/useLivenessActor.mjs';
|
|
17
18
|
import { useLivenessSelector, createLivenessSelector } from '../hooks/useLivenessSelector.mjs';
|
|
18
|
-
import '
|
|
19
|
+
import { getLandscapeMediaQuery, isMobileScreen } from '../utils/device.mjs';
|
|
19
20
|
import { CancelButton } from '../shared/CancelButton.mjs';
|
|
20
21
|
import { defaultErrorDisplayText } from '../displayText.mjs';
|
|
21
22
|
import { LandscapeErrorModal } from '../shared/LandscapeErrorModal.mjs';
|