@ha_tecno/live-id-sdk 2.12.3 → 2.13.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/lib/commonjs/components/Typograph/typograph.js +28 -0
- package/lib/commonjs/components/Typograph/typograph.js.map +1 -0
- package/lib/commonjs/components/index.js +14 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/index.js +12 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/screens/RegisterOperations/registerOperationPointsBiometrics.js +185 -0
- package/lib/commonjs/screens/RegisterOperations/registerOperationPointsBiometrics.js.map +1 -0
- package/lib/commonjs/screens/RegisterOperations/registerOperationPointsLifeCertificate.js +165 -0
- package/lib/commonjs/screens/RegisterOperations/registerOperationPointsLifeCertificate.js.map +1 -0
- package/lib/commonjs/screens/RegisterOperations/styles.js +47 -0
- package/lib/commonjs/screens/RegisterOperations/styles.js.map +1 -0
- package/lib/commonjs/screens/index.js +14 -0
- package/lib/commonjs/screens/index.js.map +1 -1
- package/lib/commonjs/services/index.js +18 -0
- package/lib/commonjs/services/index.js.map +1 -1
- package/lib/commonjs/services/services.js +106 -1
- package/lib/commonjs/services/services.js.map +1 -1
- package/lib/commonjs/store/modules/operationPoints/index.js +19 -0
- package/lib/commonjs/store/modules/operationPoints/index.js.map +1 -0
- package/lib/commonjs/store/modules/operationPoints/selectors.js +13 -0
- package/lib/commonjs/store/modules/operationPoints/selectors.js.map +1 -0
- package/lib/commonjs/store/modules/operationPoints/slice.js +233 -0
- package/lib/commonjs/store/modules/operationPoints/slice.js.map +1 -0
- package/lib/commonjs/store/modules/operationPoints/types.js +2 -0
- package/lib/commonjs/store/modules/operationPoints/types.js.map +1 -0
- package/lib/commonjs/utils/index.js +12 -0
- package/lib/commonjs/utils/index.js.map +1 -1
- package/lib/commonjs/utils/utils.js +9 -1
- package/lib/commonjs/utils/utils.js.map +1 -1
- package/lib/module/components/Typograph/typograph.js +21 -0
- package/lib/module/components/Typograph/typograph.js.map +1 -0
- package/lib/module/components/index.js +3 -1
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/index.js +2 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/screens/RegisterOperations/registerOperationPointsBiometrics.js +176 -0
- package/lib/module/screens/RegisterOperations/registerOperationPointsBiometrics.js.map +1 -0
- package/lib/module/screens/RegisterOperations/registerOperationPointsLifeCertificate.js +157 -0
- package/lib/module/screens/RegisterOperations/registerOperationPointsLifeCertificate.js.map +1 -0
- package/lib/module/screens/RegisterOperations/styles.js +41 -0
- package/lib/module/screens/RegisterOperations/styles.js.map +1 -0
- package/lib/module/screens/index.js +3 -1
- package/lib/module/screens/index.js.map +1 -1
- package/lib/module/services/index.js +2 -2
- package/lib/module/services/index.js.map +1 -1
- package/lib/module/services/services.js +102 -0
- package/lib/module/services/services.js.map +1 -1
- package/lib/module/store/modules/operationPoints/index.js +3 -0
- package/lib/module/store/modules/operationPoints/index.js.map +1 -0
- package/lib/module/store/modules/operationPoints/selectors.js +6 -0
- package/lib/module/store/modules/operationPoints/selectors.js.map +1 -0
- package/lib/module/store/modules/operationPoints/slice.js +227 -0
- package/lib/module/store/modules/operationPoints/slice.js.map +1 -0
- package/lib/module/store/modules/operationPoints/types.js +2 -0
- package/lib/module/store/modules/operationPoints/types.js.map +1 -0
- package/lib/module/utils/index.js +2 -2
- package/lib/module/utils/index.js.map +1 -1
- package/lib/module/utils/utils.js +7 -1
- package/lib/module/utils/utils.js.map +1 -1
- package/lib/typescript/src/components/Typograph/typograph.d.ts +10 -0
- package/lib/typescript/src/components/Typograph/typograph.d.ts.map +1 -0
- package/lib/typescript/src/components/index.d.ts +3 -1
- package/lib/typescript/src/components/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/screens/RegisterOperations/registerOperationPointsBiometrics.d.ts +7 -0
- package/lib/typescript/src/screens/RegisterOperations/registerOperationPointsBiometrics.d.ts.map +1 -0
- package/lib/typescript/src/screens/RegisterOperations/registerOperationPointsLifeCertificate.d.ts +7 -0
- package/lib/typescript/src/screens/RegisterOperations/registerOperationPointsLifeCertificate.d.ts.map +1 -0
- package/lib/typescript/src/screens/RegisterOperations/styles.d.ts +40 -0
- package/lib/typescript/src/screens/RegisterOperations/styles.d.ts.map +1 -0
- package/lib/typescript/src/screens/index.d.ts +3 -1
- package/lib/typescript/src/screens/index.d.ts.map +1 -1
- package/lib/typescript/src/services/index.d.ts +2 -2
- package/lib/typescript/src/services/index.d.ts.map +1 -1
- package/lib/typescript/src/services/services.d.ts +4 -1
- package/lib/typescript/src/services/services.d.ts.map +1 -1
- package/lib/typescript/src/services/types.d.ts +29 -0
- package/lib/typescript/src/services/types.d.ts.map +1 -1
- package/lib/typescript/src/store/modules/operationPoints/index.d.ts +3 -0
- package/lib/typescript/src/store/modules/operationPoints/index.d.ts.map +1 -0
- package/lib/typescript/src/store/modules/operationPoints/selectors.d.ts +24 -0
- package/lib/typescript/src/store/modules/operationPoints/selectors.d.ts.map +1 -0
- package/lib/typescript/src/store/modules/operationPoints/slice.d.ts +4 -0
- package/lib/typescript/src/store/modules/operationPoints/slice.d.ts.map +1 -0
- package/lib/typescript/src/store/modules/operationPoints/types.d.ts +51 -0
- package/lib/typescript/src/store/modules/operationPoints/types.d.ts.map +1 -0
- package/lib/typescript/src/utils/index.d.ts +2 -2
- package/lib/typescript/src/utils/index.d.ts.map +1 -1
- package/lib/typescript/src/utils/utils.d.ts +3 -1
- package/lib/typescript/src/utils/utils.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/components/Typograph/typograph.tsx +24 -0
- package/src/components/index.ts +3 -1
- package/src/index.tsx +14 -2
- package/src/screens/RegisterOperations/registerOperationPointsBiometrics.tsx +168 -0
- package/src/screens/RegisterOperations/registerOperationPointsLifeCertificate.tsx +175 -0
- package/src/screens/RegisterOperations/styles.ts +41 -0
- package/src/screens/index.ts +9 -1
- package/src/services/index.ts +18 -2
- package/src/services/services.ts +113 -1
- package/src/services/types.ts +33 -0
- package/src/store/modules/operationPoints/index.ts +3 -0
- package/src/store/modules/operationPoints/selectors.ts +7 -0
- package/src/store/modules/operationPoints/slice.ts +240 -0
- package/src/store/modules/operationPoints/types.ts +61 -0
- package/src/utils/index.ts +2 -2
- package/src/utils/utils.ts +9 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/utils/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,QAAA,MAAM,eAAe,QAAO,MAE3B,CAAC;AAEF,QAAA,MAAM,eAAe,sBACA,MAAM,EAAE,SACpB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,KACxC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAElC,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/utils/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,QAAA,MAAM,eAAe,QAAO,MAE3B,CAAC;AAEF,QAAA,MAAM,eAAe,sBACA,MAAM,EAAE,SACpB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,KACxC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAElC,CAAC;AAEF,QAAA,MAAM,SAAS,UAAW,MAAM,OAAO,MAAM,OAAO,MAAM,WAEzD,CAAC;AAEF,QAAA,MAAM,gBAAgB,gBAAiB,MAAM,OAAO,MAAM,OAAO,MAAM,WAEtE,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ha_tecno/live-id-sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"description": "React Native SDK for Live ID",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -147,6 +147,7 @@
|
|
|
147
147
|
},
|
|
148
148
|
"dependencies": {
|
|
149
149
|
"@react-native-camera-roll/camera-roll": "^7.8.3",
|
|
150
|
+
"@react-native-community/slider": "^4.5.3",
|
|
150
151
|
"@react-native-picker/picker": "^2.7.7",
|
|
151
152
|
"axios": "^1.6.8",
|
|
152
153
|
"react-native-device-info": "^10.13.1",
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Text, TextStyle, useColorScheme } from "react-native";
|
|
3
|
+
import { RFValue } from "react-native-responsive-fontsize";
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
children: string | string[] | undefined;
|
|
7
|
+
bold?: boolean;
|
|
8
|
+
style?: TextStyle;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const HAText = ({ children, bold, style }: Props) => {
|
|
12
|
+
const isDark = useColorScheme() === "dark";
|
|
13
|
+
|
|
14
|
+
const textStyle: TextStyle = {
|
|
15
|
+
fontWeight: bold ? "bold" : "normal",
|
|
16
|
+
color: isDark ? "white" : "black",
|
|
17
|
+
fontSize: RFValue(16),
|
|
18
|
+
...style
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
return <Text style={textStyle}>{children}</Text>;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default HAText;
|
package/src/components/index.ts
CHANGED
|
@@ -4,5 +4,7 @@ import RecordButton from "./recordButton/recordButton";
|
|
|
4
4
|
import CaptureButton from "./CaptureButton";
|
|
5
5
|
import CameraConfigInfo from "./CameraConfigInfo";
|
|
6
6
|
import Gabarito from "./Gabarito";
|
|
7
|
+
import HAText from "./Typograph/typograph";
|
|
8
|
+
import Icon from "./icon/icon";
|
|
7
9
|
|
|
8
|
-
export { DeviceNotFound, ModalMessage, RecordButton, CaptureButton, CameraConfigInfo, Gabarito };
|
|
10
|
+
export { DeviceNotFound, ModalMessage, RecordButton, CaptureButton, CameraConfigInfo, Gabarito, HAText, Icon };
|
package/src/index.tsx
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
LifeCertificate,
|
|
3
|
+
FingerRegister,
|
|
4
|
+
FingerAuth,
|
|
5
|
+
RegisterOperationPointsBiometrics,
|
|
6
|
+
RegisterOperationPointsLifeCertificate
|
|
7
|
+
} from "./screens";
|
|
2
8
|
|
|
3
|
-
export {
|
|
9
|
+
export {
|
|
10
|
+
LifeCertificate,
|
|
11
|
+
FingerRegister,
|
|
12
|
+
FingerAuth,
|
|
13
|
+
RegisterOperationPointsBiometrics,
|
|
14
|
+
RegisterOperationPointsLifeCertificate
|
|
15
|
+
};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import { ActivityIndicator, Alert, BackHandler, Modal, View, useColorScheme } from "react-native";
|
|
3
|
+
import { Camera, Point, useCameraDevice, useCameraFormat, useCameraPermission } from "react-native-vision-camera";
|
|
4
|
+
import { runOnJS } from "react-native-reanimated";
|
|
5
|
+
import { Gesture, GestureDetector, GestureHandlerRootView } from "react-native-gesture-handler";
|
|
6
|
+
import { readFile } from "react-native-fs";
|
|
7
|
+
import Slider from "@react-native-community/slider";
|
|
8
|
+
|
|
9
|
+
import { useDispatch, useSelector } from "../../store/modules/operationPoints";
|
|
10
|
+
import { scale0to1Inverse, useIsForeground } from "../../utils";
|
|
11
|
+
import { CaptureButton, DeviceNotFound, Gabarito, HAText } from "../../components";
|
|
12
|
+
import { styles } from "./styles";
|
|
13
|
+
|
|
14
|
+
type Props = {
|
|
15
|
+
onSuccess: () => void;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const RegisterOperationPointsBiometrics = ({ onSuccess }: Props) => {
|
|
19
|
+
const isDark = useColorScheme() === "dark";
|
|
20
|
+
const backgroundColor = isDark ? "black" : "white";
|
|
21
|
+
const [zoom, setZoom] = useState<number>(2);
|
|
22
|
+
const [torch, setTorch] = useState<"off" | "on">("off");
|
|
23
|
+
const dispatch = useDispatch();
|
|
24
|
+
const { hasPermission, requestPermission } = useCameraPermission();
|
|
25
|
+
const cameraRef = useRef<Camera>(null);
|
|
26
|
+
const isForeground = useIsForeground();
|
|
27
|
+
const isActive = isForeground;
|
|
28
|
+
|
|
29
|
+
const { loading, exposureScaleZeroToOneBiometrics, message, base64Images } = useSelector();
|
|
30
|
+
const imagesCount = base64Images.length;
|
|
31
|
+
|
|
32
|
+
const containerCaptureStyled = [styles.containerCapture, { bottom: 20 }];
|
|
33
|
+
|
|
34
|
+
const device = useCameraDevice("back");
|
|
35
|
+
const cameraFormat = useCameraFormat(device, [
|
|
36
|
+
{
|
|
37
|
+
photoResolution: {
|
|
38
|
+
width: 1280,
|
|
39
|
+
height: 720
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
const cameraPermission = useCallback(async () => {
|
|
45
|
+
if (!hasPermission) {
|
|
46
|
+
await requestPermission();
|
|
47
|
+
}
|
|
48
|
+
}, [hasPermission, requestPermission]);
|
|
49
|
+
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
cameraPermission();
|
|
52
|
+
}, [cameraPermission]);
|
|
53
|
+
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (imagesCount === 3 && device != null) {
|
|
56
|
+
dispatch.sendImagesBase64({
|
|
57
|
+
base64Images,
|
|
58
|
+
exposureScaleZeroToOneBiometrics,
|
|
59
|
+
exposureMin: device.minExposure,
|
|
60
|
+
exposureMax: device.maxExposure,
|
|
61
|
+
zoomMin: device.minZoom,
|
|
62
|
+
zoomMax: device.maxZoom
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}, [imagesCount, device, dispatch]);
|
|
66
|
+
|
|
67
|
+
const takePhoto = async () => {
|
|
68
|
+
const photo = await cameraRef.current?.takePhoto();
|
|
69
|
+
if (photo != null) {
|
|
70
|
+
const imageBase64 = await readFile(photo.path, "base64");
|
|
71
|
+
dispatch.setImageBase64(imageBase64);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const focus = useCallback((point: Point) => {
|
|
76
|
+
const camera = cameraRef.current;
|
|
77
|
+
if (camera != null) {
|
|
78
|
+
camera.focus(point);
|
|
79
|
+
}
|
|
80
|
+
}, []);
|
|
81
|
+
|
|
82
|
+
const gesture = Gesture.Tap().onBegin(({ x, y }) => {
|
|
83
|
+
runOnJS(focus)({ x, y });
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (loading === "succeeded") {
|
|
88
|
+
Alert.alert("Sucesso", message, [{ text: "OK", onPress: () => onSuccess && onSuccess() }]);
|
|
89
|
+
}
|
|
90
|
+
if (loading === "failed") {
|
|
91
|
+
Alert.alert("Continue", message, [
|
|
92
|
+
{
|
|
93
|
+
text: "OK",
|
|
94
|
+
onPress: () => dispatch.changeExposureBiometrics()
|
|
95
|
+
}
|
|
96
|
+
]);
|
|
97
|
+
}
|
|
98
|
+
}, [loading, message, dispatch]);
|
|
99
|
+
|
|
100
|
+
const backAction = () => {
|
|
101
|
+
const exit = BackHandler.exitApp;
|
|
102
|
+
Alert.alert("Atenção!", "Tem certeza que deseja sair?", [
|
|
103
|
+
{
|
|
104
|
+
text: "Cancelar",
|
|
105
|
+
onPress: () => null,
|
|
106
|
+
style: "cancel"
|
|
107
|
+
},
|
|
108
|
+
{ text: "Sim", onPress: exit }
|
|
109
|
+
]);
|
|
110
|
+
return true;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
useEffect(
|
|
114
|
+
useCallback(() => {
|
|
115
|
+
const onBackPress = () => {
|
|
116
|
+
backAction();
|
|
117
|
+
return true;
|
|
118
|
+
};
|
|
119
|
+
BackHandler.addEventListener("hardwareBackPress", onBackPress);
|
|
120
|
+
return () => {
|
|
121
|
+
BackHandler.removeEventListener("hardwareBackPress", onBackPress);
|
|
122
|
+
};
|
|
123
|
+
}, [backAction])
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
const onInitialized = () => setTorch("on");
|
|
127
|
+
|
|
128
|
+
if (device == null || hasPermission === false)
|
|
129
|
+
return <DeviceNotFound hasPermission cameraPermission={cameraPermission} />;
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<GestureHandlerRootView style={{ flex: 1 }}>
|
|
133
|
+
<GestureDetector gesture={gesture}>
|
|
134
|
+
<View style={styles.containerCamera}>
|
|
135
|
+
<Camera
|
|
136
|
+
ref={cameraRef}
|
|
137
|
+
device={device}
|
|
138
|
+
style={styles.camera}
|
|
139
|
+
format={cameraFormat}
|
|
140
|
+
isActive={isActive}
|
|
141
|
+
torch={torch}
|
|
142
|
+
exposure={scale0to1Inverse(exposureScaleZeroToOneBiometrics, device.minExposure, device.maxExposure)}
|
|
143
|
+
zoom={zoom}
|
|
144
|
+
onInitialized={onInitialized}
|
|
145
|
+
photo
|
|
146
|
+
/>
|
|
147
|
+
<Gabarito />
|
|
148
|
+
</View>
|
|
149
|
+
</GestureDetector>
|
|
150
|
+
<View style={containerCaptureStyled}>
|
|
151
|
+
<CaptureButton onPress={takePhoto} imagesCount={imagesCount} />
|
|
152
|
+
</View>
|
|
153
|
+
<View style={[styles.containerSlider, { backgroundColor }]}>
|
|
154
|
+
<HAText bold>{`Ponto de operação`}</HAText>
|
|
155
|
+
<Slider maximumValue={4} minimumValue={2} value={zoom} onValueChange={(value) => setZoom(value)} step={1} />
|
|
156
|
+
</View>
|
|
157
|
+
{loading === "pending" && (
|
|
158
|
+
<Modal animationType="fade" transparent visible={true}>
|
|
159
|
+
<View style={styles.containerModalLoading}>
|
|
160
|
+
<ActivityIndicator size="large" color="#fff" />
|
|
161
|
+
</View>
|
|
162
|
+
</Modal>
|
|
163
|
+
)}
|
|
164
|
+
</GestureHandlerRootView>
|
|
165
|
+
);
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export default RegisterOperationPointsBiometrics;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import { ActivityIndicator, Alert, BackHandler, Modal, View } from "react-native";
|
|
3
|
+
import { Camera, useCameraDevice, useCameraFormat, useCameraPermission } from "react-native-vision-camera";
|
|
4
|
+
|
|
5
|
+
import { useDispatch, useSelector } from "../../store/modules/operationPoints";
|
|
6
|
+
import { scale0to1Inverse, useIsForeground } from "../../utils";
|
|
7
|
+
import { DeviceNotFound, RecordButton } from "../../components";
|
|
8
|
+
import { styles } from "./styles";
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
onSuccess: () => void;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const RegisterOperationPointsLifeCertificate = ({ onSuccess }: Props) => {
|
|
15
|
+
const [torch, setTorch] = useState<"off" | "on">("off");
|
|
16
|
+
const dispatch = useDispatch();
|
|
17
|
+
const { hasPermission, requestPermission } = useCameraPermission();
|
|
18
|
+
const cameraRef = useRef<Camera>(null);
|
|
19
|
+
const isForeground = useIsForeground();
|
|
20
|
+
const isActive = isForeground;
|
|
21
|
+
|
|
22
|
+
const [intervalState, setIntervalState] = useState<NodeJS.Timeout | null>(null);
|
|
23
|
+
const [timer, setTimer] = useState(10);
|
|
24
|
+
const [isRecord, setIsRecord] = useState(false);
|
|
25
|
+
|
|
26
|
+
const { loading, registered, exposureScaleZeroToOneLifeCertificate, message } = useSelector();
|
|
27
|
+
|
|
28
|
+
const device = useCameraDevice("back");
|
|
29
|
+
const cameraFormat = useCameraFormat(device, [
|
|
30
|
+
{
|
|
31
|
+
videoResolution: {
|
|
32
|
+
width: 1280,
|
|
33
|
+
height: 720
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
]);
|
|
37
|
+
const exposure = scale0to1Inverse(
|
|
38
|
+
exposureScaleZeroToOneLifeCertificate,
|
|
39
|
+
device !== undefined ? device.minExposure : 0,
|
|
40
|
+
device !== undefined ? device.maxExposure : 0
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const cameraPermission = useCallback(async () => {
|
|
44
|
+
if (!hasPermission) {
|
|
45
|
+
await requestPermission();
|
|
46
|
+
}
|
|
47
|
+
}, [hasPermission, requestPermission]);
|
|
48
|
+
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
cameraPermission();
|
|
51
|
+
}, [cameraPermission]);
|
|
52
|
+
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (loading === "succeeded") {
|
|
55
|
+
Alert.alert("Sucesso", message, [
|
|
56
|
+
{
|
|
57
|
+
text: "OK",
|
|
58
|
+
onPress: () => {
|
|
59
|
+
registered ? () => onSuccess && onSuccess() : null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
if (loading === "failed") {
|
|
65
|
+
Alert.alert("Continue", message, [
|
|
66
|
+
{
|
|
67
|
+
text: "OK",
|
|
68
|
+
onPress: () => dispatch.changeExposureLifeCertificate()
|
|
69
|
+
}
|
|
70
|
+
]);
|
|
71
|
+
}
|
|
72
|
+
setTimer(10);
|
|
73
|
+
}, [loading, message, dispatch]);
|
|
74
|
+
|
|
75
|
+
const backAction = () => {
|
|
76
|
+
const exit = BackHandler.exitApp;
|
|
77
|
+
Alert.alert("Atenção!", "Tem certeza que deseja sair?", [
|
|
78
|
+
{
|
|
79
|
+
text: "Cancelar",
|
|
80
|
+
onPress: () => null,
|
|
81
|
+
style: "cancel"
|
|
82
|
+
},
|
|
83
|
+
{ text: "Sim", onPress: exit }
|
|
84
|
+
]);
|
|
85
|
+
return true;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
useEffect(
|
|
89
|
+
useCallback(() => {
|
|
90
|
+
const onBackPress = () => {
|
|
91
|
+
backAction();
|
|
92
|
+
return true;
|
|
93
|
+
};
|
|
94
|
+
BackHandler.addEventListener("hardwareBackPress", onBackPress);
|
|
95
|
+
return () => {
|
|
96
|
+
BackHandler.removeEventListener("hardwareBackPress", onBackPress);
|
|
97
|
+
};
|
|
98
|
+
}, [backAction])
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const startVideoRecording = useCallback(() => {
|
|
102
|
+
setIsRecord(true);
|
|
103
|
+
if (device !== undefined) {
|
|
104
|
+
cameraRef.current?.startRecording({
|
|
105
|
+
fileType: "mp4",
|
|
106
|
+
onRecordingFinished: (video) =>
|
|
107
|
+
dispatch.sendVideosLifeCertificate({
|
|
108
|
+
exposureScaleZeroToOneLifeCertificate,
|
|
109
|
+
exposureMax: device.maxExposure,
|
|
110
|
+
exposureMin: device.minExposure,
|
|
111
|
+
videoPath: video.path
|
|
112
|
+
}),
|
|
113
|
+
onRecordingError: (error) => console.error(error)
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}, [dispatch]);
|
|
117
|
+
|
|
118
|
+
const recordingVideo = useCallback(() => {
|
|
119
|
+
startVideoRecording();
|
|
120
|
+
setIntervalState(
|
|
121
|
+
setInterval(() => {
|
|
122
|
+
setTimer((prevTimer) => prevTimer - 1);
|
|
123
|
+
}, 1000)
|
|
124
|
+
);
|
|
125
|
+
}, [startVideoRecording]);
|
|
126
|
+
|
|
127
|
+
const stopRecodingVideo = useCallback(async () => {
|
|
128
|
+
setIsRecord(false);
|
|
129
|
+
await cameraRef.current?.stopRecording();
|
|
130
|
+
}, [dispatch]);
|
|
131
|
+
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
if (timer < 0) {
|
|
134
|
+
if (!intervalState) return;
|
|
135
|
+
clearInterval(intervalState);
|
|
136
|
+
stopRecodingVideo();
|
|
137
|
+
}
|
|
138
|
+
}, [timer, intervalState, stopRecodingVideo]);
|
|
139
|
+
|
|
140
|
+
const onInitialized = () => setTorch("on");
|
|
141
|
+
|
|
142
|
+
if (device == null || hasPermission === false)
|
|
143
|
+
return <DeviceNotFound hasPermission={hasPermission} cameraPermission={cameraPermission} />;
|
|
144
|
+
|
|
145
|
+
return (
|
|
146
|
+
<>
|
|
147
|
+
<View style={styles.containerCamera}>
|
|
148
|
+
<Camera
|
|
149
|
+
ref={cameraRef}
|
|
150
|
+
device={device}
|
|
151
|
+
style={styles.camera}
|
|
152
|
+
format={cameraFormat}
|
|
153
|
+
isActive={isActive}
|
|
154
|
+
torch={torch}
|
|
155
|
+
exposure={exposure}
|
|
156
|
+
zoom={0}
|
|
157
|
+
onInitialized={onInitialized}
|
|
158
|
+
video
|
|
159
|
+
/>
|
|
160
|
+
</View>
|
|
161
|
+
<View style={[styles.containerCapture, { bottom: 0 }]}>
|
|
162
|
+
<RecordButton onPress={recordingVideo} disabled={loading === "pending"} timer={timer} isRecording={isRecord} />
|
|
163
|
+
</View>
|
|
164
|
+
{loading === "pending" && (
|
|
165
|
+
<Modal animationType="fade" transparent visible>
|
|
166
|
+
<View style={styles.containerModalLoading}>
|
|
167
|
+
<ActivityIndicator size="large" color="#fff" />
|
|
168
|
+
</View>
|
|
169
|
+
</Modal>
|
|
170
|
+
)}
|
|
171
|
+
</>
|
|
172
|
+
);
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
export default RegisterOperationPointsLifeCertificate;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { StyleSheet, Platform } from "react-native";
|
|
2
|
+
|
|
3
|
+
export const styles = StyleSheet.create({
|
|
4
|
+
containerCamera: {
|
|
5
|
+
flex: 1,
|
|
6
|
+
justifyContent: "center"
|
|
7
|
+
},
|
|
8
|
+
camera: {
|
|
9
|
+
flex: 1
|
|
10
|
+
},
|
|
11
|
+
box: {
|
|
12
|
+
flexDirection: "row",
|
|
13
|
+
height: 50,
|
|
14
|
+
justifyContent: "center",
|
|
15
|
+
alignItems: "center",
|
|
16
|
+
borderRadius: 50,
|
|
17
|
+
backgroundColor: "#1F75FF",
|
|
18
|
+
marginVertical: Platform.OS === "android" ? 100 : 120
|
|
19
|
+
},
|
|
20
|
+
text: {
|
|
21
|
+
position: "absolute",
|
|
22
|
+
color: "#fff"
|
|
23
|
+
},
|
|
24
|
+
containerCapture: {
|
|
25
|
+
position: "absolute",
|
|
26
|
+
width: "100%",
|
|
27
|
+
marginBottom: "30%",
|
|
28
|
+
alignItems: "center"
|
|
29
|
+
},
|
|
30
|
+
containerModalLoading: {
|
|
31
|
+
flex: 1,
|
|
32
|
+
justifyContent: "center",
|
|
33
|
+
alignItems: "center",
|
|
34
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)"
|
|
35
|
+
},
|
|
36
|
+
containerSlider: {
|
|
37
|
+
height: Platform.OS === "android" ? 100 : 120,
|
|
38
|
+
padding: 20,
|
|
39
|
+
gap: 10
|
|
40
|
+
}
|
|
41
|
+
});
|
package/src/screens/index.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import FingerRegister from "./FingerRegister/FingerRegister";
|
|
2
2
|
import LifeCertificate from "./LifeCertificate/LifeCertificate";
|
|
3
3
|
import FingerAuth from "./FingerAuth/FingerAuth";
|
|
4
|
+
import RegisterOperationPointsBiometrics from "./RegisterOperations/registerOperationPointsBiometrics";
|
|
5
|
+
import RegisterOperationPointsLifeCertificate from "./RegisterOperations/registerOperationPointsLifeCertificate";
|
|
4
6
|
|
|
5
|
-
export {
|
|
7
|
+
export {
|
|
8
|
+
FingerRegister,
|
|
9
|
+
LifeCertificate,
|
|
10
|
+
FingerAuth,
|
|
11
|
+
RegisterOperationPointsBiometrics,
|
|
12
|
+
RegisterOperationPointsLifeCertificate
|
|
13
|
+
};
|
package/src/services/index.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
lifeCertificate,
|
|
3
|
+
getConfigsApi,
|
|
4
|
+
registerFingerImages,
|
|
5
|
+
authFinger,
|
|
6
|
+
getConfigOperationPoints,
|
|
7
|
+
sendImagesForRegisterOperationPoints,
|
|
8
|
+
sendVideoForRegisterOperationPoints
|
|
9
|
+
} from "./services";
|
|
2
10
|
|
|
3
11
|
const BASE_URL = "https://api.liveid.app.br";
|
|
4
12
|
const TOKEN =
|
|
@@ -39,4 +47,12 @@ export const verificaCPF = async (cpf: any) => {
|
|
|
39
47
|
return data;
|
|
40
48
|
};
|
|
41
49
|
|
|
42
|
-
export {
|
|
50
|
+
export {
|
|
51
|
+
lifeCertificate,
|
|
52
|
+
getConfigsApi,
|
|
53
|
+
registerFingerImages,
|
|
54
|
+
authFinger,
|
|
55
|
+
getConfigOperationPoints,
|
|
56
|
+
sendImagesForRegisterOperationPoints,
|
|
57
|
+
sendVideoForRegisterOperationPoints
|
|
58
|
+
};
|
package/src/services/services.ts
CHANGED
|
@@ -8,7 +8,11 @@ import type {
|
|
|
8
8
|
RegisterFingerResponse,
|
|
9
9
|
RegisterFingerImagesType,
|
|
10
10
|
AuthFingerType,
|
|
11
|
-
AuthFingerResponse
|
|
11
|
+
AuthFingerResponse,
|
|
12
|
+
SendImagesForRegisterOperationPointsType,
|
|
13
|
+
SendImagesForRegisterOperationPointsResponse,
|
|
14
|
+
SendVideoForRegisterOperationPointsType,
|
|
15
|
+
SendVideoForRegisterOperationPointsResponse
|
|
12
16
|
} from "./types";
|
|
13
17
|
import DeviceInfo from "react-native-device-info";
|
|
14
18
|
|
|
@@ -136,3 +140,111 @@ export const lifeCertificate = async ({
|
|
|
136
140
|
};
|
|
137
141
|
}
|
|
138
142
|
};
|
|
143
|
+
|
|
144
|
+
export const getConfigOperationPoints = async (): Promise<GetConfigApiResponse> => {
|
|
145
|
+
const { data } = await axiosInstance.get("/configs", {
|
|
146
|
+
headers: {
|
|
147
|
+
"Content-Type": "application/json",
|
|
148
|
+
Authorization: `Bearer ${TOKEN}`
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
return data.deviceParamsConfig;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export const sendImagesForRegisterOperationPoints = async ({
|
|
155
|
+
deviceModel,
|
|
156
|
+
exposure,
|
|
157
|
+
exposureMax,
|
|
158
|
+
exposureMin,
|
|
159
|
+
exposureScaleZeroToOneBiometrics,
|
|
160
|
+
images,
|
|
161
|
+
zoom,
|
|
162
|
+
zoomMax,
|
|
163
|
+
zoomMin,
|
|
164
|
+
zoomScaleZeroToOne
|
|
165
|
+
}: SendImagesForRegisterOperationPointsType): Promise<SendImagesForRegisterOperationPointsResponse> => {
|
|
166
|
+
try {
|
|
167
|
+
const { data } = await axiosInstance.post(
|
|
168
|
+
"/images-quality",
|
|
169
|
+
{
|
|
170
|
+
device_model: deviceModel,
|
|
171
|
+
images,
|
|
172
|
+
exposure,
|
|
173
|
+
exposureMin,
|
|
174
|
+
exposureMax,
|
|
175
|
+
exposureScaleZeroToOne: exposureScaleZeroToOneBiometrics,
|
|
176
|
+
zoom,
|
|
177
|
+
zoomMin,
|
|
178
|
+
zoomMax,
|
|
179
|
+
zoomScaleZeroToOne,
|
|
180
|
+
operationalSystem: Platform.OS
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
headers: {
|
|
184
|
+
"Content-Type": "application/json",
|
|
185
|
+
Authorization: `Bearer ${TOKEN}`
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
return {
|
|
190
|
+
message: "Cadastro de ponto de operação realizado com sucesso!",
|
|
191
|
+
status: data.status
|
|
192
|
+
};
|
|
193
|
+
} catch (error: any) {
|
|
194
|
+
return {
|
|
195
|
+
message: "Continue, faça com o próximo ponto de operação.",
|
|
196
|
+
status: error.response.data.status
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export const sendVideoForRegisterOperationPoints = async ({
|
|
202
|
+
deviceModel,
|
|
203
|
+
exposure,
|
|
204
|
+
exposureMax,
|
|
205
|
+
exposureMin,
|
|
206
|
+
exposureScaleZeroToOneLifeCertificate,
|
|
207
|
+
videoPath
|
|
208
|
+
}: SendVideoForRegisterOperationPointsType): Promise<SendVideoForRegisterOperationPointsResponse> => {
|
|
209
|
+
try {
|
|
210
|
+
const uuidv4 = uuid.v4();
|
|
211
|
+
const formData = new FormData();
|
|
212
|
+
|
|
213
|
+
formData.append("video", {
|
|
214
|
+
uri: Platform.select({
|
|
215
|
+
ios: videoPath,
|
|
216
|
+
android: `file://${videoPath}`
|
|
217
|
+
}),
|
|
218
|
+
type: "video/mp4",
|
|
219
|
+
name: `${uuidv4}.mp4`
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
formData.append("video_key", uuidv4);
|
|
223
|
+
formData.append("device_model", deviceModel);
|
|
224
|
+
formData.append("operationalSystem", Platform.OS);
|
|
225
|
+
formData.append("exposure", exposure);
|
|
226
|
+
formData.append("exposureMin", exposureMin);
|
|
227
|
+
formData.append("exposureMax", exposureMax);
|
|
228
|
+
formData.append("exposureScaleZeroToOne", exposureScaleZeroToOneLifeCertificate);
|
|
229
|
+
|
|
230
|
+
const { data } = await axiosInstance.post("/video-quality", formData, {
|
|
231
|
+
headers: {
|
|
232
|
+
"Content-Type": "multipart/form-data",
|
|
233
|
+
Authorization: `Bearer ${TOKEN}`
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
const hasConfig = data.config !== undefined;
|
|
237
|
+
return {
|
|
238
|
+
message: hasConfig
|
|
239
|
+
? "Cadastro de ponto de operação realizado com sucesso!"
|
|
240
|
+
: "A calibração foi um sucesso, faça novamente mais uma vez!",
|
|
241
|
+
status: data.status,
|
|
242
|
+
hasConfig
|
|
243
|
+
};
|
|
244
|
+
} catch (e: any) {
|
|
245
|
+
return {
|
|
246
|
+
message: "Continue, faça com o próximo ponto de operação.",
|
|
247
|
+
status: e.response.data.status
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
};
|
package/src/services/types.ts
CHANGED
|
@@ -58,3 +58,36 @@ export type LifeCertificateResponse = {
|
|
|
58
58
|
bpm?: number;
|
|
59
59
|
message?: string;
|
|
60
60
|
};
|
|
61
|
+
|
|
62
|
+
export type SendImagesForRegisterOperationPointsType = {
|
|
63
|
+
deviceModel: string;
|
|
64
|
+
images: string[];
|
|
65
|
+
exposure: number;
|
|
66
|
+
exposureMin: number;
|
|
67
|
+
exposureMax: number;
|
|
68
|
+
exposureScaleZeroToOneBiometrics: number;
|
|
69
|
+
zoom: number;
|
|
70
|
+
zoomMax: number;
|
|
71
|
+
zoomMin: number;
|
|
72
|
+
zoomScaleZeroToOne: number;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export type SendImagesForRegisterOperationPointsResponse = {
|
|
76
|
+
status: number;
|
|
77
|
+
message: string;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export type SendVideoForRegisterOperationPointsType = {
|
|
81
|
+
deviceModel: string;
|
|
82
|
+
videoPath: string;
|
|
83
|
+
exposure: number;
|
|
84
|
+
exposureScaleZeroToOneLifeCertificate: number;
|
|
85
|
+
exposureMin: number;
|
|
86
|
+
exposureMax: number;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export type SendVideoForRegisterOperationPointsResponse = {
|
|
90
|
+
status: number;
|
|
91
|
+
message: string;
|
|
92
|
+
hasConfig?: boolean;
|
|
93
|
+
};
|