react-native-timacare 3.3.27 → 3.3.29
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/screens/camera/CCCDCameraScreen.js +1 -1
- package/lib/commonjs/screens/camera/CCCDCameraScreen.js.flow +29 -26
- package/lib/commonjs/screens/camera/CCCDCameraScreen.js.map +1 -1
- package/lib/commonjs/screens/camera/index.js +1 -1
- package/lib/commonjs/screens/camera/index.js.flow +34 -48
- package/lib/commonjs/screens/camera/index.js.map +1 -1
- package/lib/commonjs/screens/home/DigitalTopupItem.js +1 -1
- package/lib/commonjs/screens/home/DigitalTopupItem.js.flow +31 -33
- package/lib/commonjs/screens/home/DigitalTopupItem.js.map +1 -1
- package/lib/commonjs/screens/home/ItemMotoBikeLoan.js +1 -1
- package/lib/commonjs/screens/home/ItemMotoBikeLoan.js.flow +44 -4
- package/lib/commonjs/screens/home/ItemMotoBikeLoan.js.map +1 -1
- package/lib/commonjs/screens/liveness/index.js +1 -1
- package/lib/commonjs/screens/liveness/index.js.flow +43 -54
- package/lib/commonjs/screens/liveness/index.js.map +1 -1
- package/lib/commonjs/screens/liveness-v2/index.js +1 -1
- package/lib/commonjs/screens/liveness-v2/index.js.flow +60 -56
- package/lib/commonjs/screens/liveness-v2/index.js.map +1 -1
- package/lib/commonjs/screens/mrz-scanner/index.js +1 -1
- package/lib/commonjs/screens/mrz-scanner/index.js.flow +25 -10
- package/lib/commonjs/screens/mrz-scanner/index.js.map +1 -1
- package/lib/commonjs/screens/toan-trinh-so/OCR.js +1 -1
- package/lib/commonjs/screens/toan-trinh-so/OCR.js.flow +48 -49
- package/lib/commonjs/screens/toan-trinh-so/OCR.js.map +1 -1
- package/lib/commonjs/screens/toan-trinh-so/RegisterCamera.js +1 -1
- package/lib/commonjs/screens/toan-trinh-so/RegisterCamera.js.flow +32 -33
- package/lib/commonjs/screens/toan-trinh-so/RegisterCamera.js.map +1 -1
- package/lib/commonjs/screens/toan-trinh-so/TTSSelfie.js +1 -1
- package/lib/commonjs/screens/toan-trinh-so/TTSSelfie.js.flow +26 -37
- package/lib/commonjs/screens/toan-trinh-so/TTSSelfie.js.map +1 -1
- package/lib/commonjs/screens/toan-trinh-so/VehicleCamera.js +1 -1
- package/lib/commonjs/screens/toan-trinh-so/VehicleCamera.js.flow +77 -78
- package/lib/commonjs/screens/toan-trinh-so/VehicleCamera.js.map +1 -1
- package/lib/commonjs/screens/uploadVideo/index.js +1 -1
- package/lib/commonjs/screens/uploadVideo/index.js.flow +32 -33
- package/lib/commonjs/screens/uploadVideo/index.js.map +1 -1
- package/lib/module/screens/camera/CCCDCameraScreen.js +1 -1
- package/lib/module/screens/camera/CCCDCameraScreen.js.map +1 -1
- package/lib/module/screens/camera/index.js +1 -1
- package/lib/module/screens/camera/index.js.map +1 -1
- package/lib/module/screens/home/DigitalTopupItem.js +1 -1
- package/lib/module/screens/home/DigitalTopupItem.js.map +1 -1
- package/lib/module/screens/home/ItemMotoBikeLoan.js +1 -1
- package/lib/module/screens/home/ItemMotoBikeLoan.js.map +1 -1
- package/lib/module/screens/liveness/index.js +1 -1
- package/lib/module/screens/liveness/index.js.map +1 -1
- package/lib/module/screens/liveness-v2/index.js +1 -1
- package/lib/module/screens/liveness-v2/index.js.map +1 -1
- package/lib/module/screens/mrz-scanner/index.js +1 -1
- package/lib/module/screens/mrz-scanner/index.js.map +1 -1
- package/lib/module/screens/toan-trinh-so/OCR.js +1 -1
- package/lib/module/screens/toan-trinh-so/OCR.js.map +1 -1
- package/lib/module/screens/toan-trinh-so/RegisterCamera.js +1 -1
- package/lib/module/screens/toan-trinh-so/RegisterCamera.js.map +1 -1
- package/lib/module/screens/toan-trinh-so/TTSSelfie.js +1 -1
- package/lib/module/screens/toan-trinh-so/TTSSelfie.js.map +1 -1
- package/lib/module/screens/toan-trinh-so/VehicleCamera.js +1 -1
- package/lib/module/screens/toan-trinh-so/VehicleCamera.js.map +1 -1
- package/lib/module/screens/uploadVideo/index.js +1 -1
- package/lib/module/screens/uploadVideo/index.js.map +1 -1
- package/lib/typescript/screens/camera/CCCDCameraScreen.d.ts.map +1 -1
- package/lib/typescript/screens/camera/index.d.ts.map +1 -1
- package/lib/typescript/screens/home/DigitalTopupItem.d.ts.map +1 -1
- package/lib/typescript/screens/home/ItemMotoBikeLoan.d.ts.map +1 -1
- package/lib/typescript/screens/liveness/index.d.ts.map +1 -1
- package/lib/typescript/screens/liveness-v2/index.d.ts.map +1 -1
- package/lib/typescript/screens/mrz-scanner/index.d.ts.map +1 -1
- package/lib/typescript/screens/toan-trinh-so/OCR.d.ts.map +1 -1
- package/lib/typescript/screens/toan-trinh-so/RegisterCamera.d.ts.map +1 -1
- package/lib/typescript/screens/toan-trinh-so/TTSSelfie.d.ts.map +1 -1
- package/lib/typescript/screens/toan-trinh-so/VehicleCamera.d.ts.map +1 -1
- package/lib/typescript/screens/uploadVideo/index.d.ts.map +1 -1
- package/package.json +1 -2
- package/src/screens/camera/CCCDCameraScreen.tsx +29 -26
- package/src/screens/camera/index.tsx +34 -48
- package/src/screens/home/DigitalTopupItem.tsx +31 -33
- package/src/screens/home/ItemMotoBikeLoan.tsx +44 -4
- package/src/screens/liveness/index.tsx +43 -54
- package/src/screens/liveness-v2/index.tsx +60 -56
- package/src/screens/mrz-scanner/index.tsx +25 -10
- package/src/screens/toan-trinh-so/OCR.tsx +48 -49
- package/src/screens/toan-trinh-so/RegisterCamera.tsx +32 -33
- package/src/screens/toan-trinh-so/TTSSelfie.tsx +26 -37
- package/src/screens/toan-trinh-so/VehicleCamera.tsx +77 -78
- package/src/screens/uploadVideo/index.tsx +32 -33
|
@@ -30,7 +30,11 @@ import {
|
|
|
30
30
|
RESULTS,
|
|
31
31
|
openSettings,
|
|
32
32
|
} from 'react-native-permissions';
|
|
33
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
Camera as VisionCamera,
|
|
35
|
+
useCameraDevice,
|
|
36
|
+
useCameraFormat,
|
|
37
|
+
} from 'react-native-vision-camera';
|
|
34
38
|
import {
|
|
35
39
|
CIMBBank,
|
|
36
40
|
IconBackFill,
|
|
@@ -48,6 +52,7 @@ import Store from './Store';
|
|
|
48
52
|
import { MText } from '../../components/MText';
|
|
49
53
|
import Modal from 'react-native-modal';
|
|
50
54
|
import LinearGradient from 'react-native-linear-gradient';
|
|
55
|
+
import RNFS from 'react-native-fs';
|
|
51
56
|
|
|
52
57
|
const cameraStore = new Store();
|
|
53
58
|
export const Camera = observer(function Camera(props: any) {
|
|
@@ -62,27 +67,28 @@ export const Camera = observer(function Camera(props: any) {
|
|
|
62
67
|
const [showModal, setShowModal] = useState(false);
|
|
63
68
|
|
|
64
69
|
const myCamera = useRef(null);
|
|
70
|
+
const device = useCameraDevice(front ? 'front' : 'back');
|
|
71
|
+
const format = useCameraFormat(device, [
|
|
72
|
+
{ photoResolution: { width: 1280, height: 720 } },
|
|
73
|
+
]);
|
|
65
74
|
|
|
66
75
|
const takePhoto = async () => {
|
|
76
|
+
if (myCamera.current == null || taking) return;
|
|
67
77
|
setTaking(true);
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
fixOrientation: false,
|
|
73
|
-
forceUpOrientation: false,
|
|
74
|
-
orientation: RNCamera.Constants.Orientation.portrait,
|
|
75
|
-
};
|
|
76
|
-
const data = await myCamera.current.takePictureAsync(options);
|
|
78
|
+
const data = await myCamera.current.takePhoto({
|
|
79
|
+
qualityPrioritization: 'quality',
|
|
80
|
+
});
|
|
81
|
+
const uri = 'file://' + data.path;
|
|
77
82
|
|
|
78
83
|
setTaking(false);
|
|
79
84
|
// eslint-disable-next-line
|
|
80
85
|
navigation.goBack();
|
|
81
86
|
if (props.route.params.callback) {
|
|
82
|
-
props.route.params.callback(
|
|
87
|
+
props.route.params.callback(uri);
|
|
83
88
|
}
|
|
84
89
|
if (props.route.params.base64) {
|
|
85
|
-
|
|
90
|
+
const base64 = await RNFS.readFile(data.path, 'base64');
|
|
91
|
+
props.route.params.base64(base64);
|
|
86
92
|
}
|
|
87
93
|
};
|
|
88
94
|
|
|
@@ -223,42 +229,22 @@ export const Camera = observer(function Camera(props: any) {
|
|
|
223
229
|
},
|
|
224
230
|
]}
|
|
225
231
|
>
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
? RNCamera.Constants.FlashMode.on
|
|
243
|
-
: RNCamera.Constants.FlashMode.off
|
|
244
|
-
}
|
|
245
|
-
androidCameraPermissionOptions={{
|
|
246
|
-
title: 'Permission to use camera',
|
|
247
|
-
message: 'We need your permission to use your camera',
|
|
248
|
-
buttonPositive: 'Ok',
|
|
249
|
-
buttonNegative: 'Cancel',
|
|
250
|
-
}}
|
|
251
|
-
androidRecordAudioPermissionOptions={{
|
|
252
|
-
title: 'Permission to use audio recording',
|
|
253
|
-
message: 'We need your permission to use your audio',
|
|
254
|
-
buttonPositive: 'Ok',
|
|
255
|
-
buttonNegative: 'Cancel',
|
|
256
|
-
}}
|
|
257
|
-
>
|
|
258
|
-
{({ camera, status, recordAudioPermissionStatus }) => {
|
|
259
|
-
if (status !== 'READY') return <ActivityIndicator />;
|
|
260
|
-
}}
|
|
261
|
-
</RNCamera>
|
|
232
|
+
{device ? (
|
|
233
|
+
<VisionCamera
|
|
234
|
+
ref={myCamera}
|
|
235
|
+
style={{
|
|
236
|
+
width: Dimensions.get('window').width,
|
|
237
|
+
height: (Dimensions.get('window').width * 4) / 3.1,
|
|
238
|
+
}}
|
|
239
|
+
device={device}
|
|
240
|
+
isActive={true}
|
|
241
|
+
photo={true}
|
|
242
|
+
format={format}
|
|
243
|
+
torch={flash && device.hasTorch ? 'on' : 'off'}
|
|
244
|
+
/>
|
|
245
|
+
) : (
|
|
246
|
+
<ActivityIndicator />
|
|
247
|
+
)}
|
|
262
248
|
</View>
|
|
263
249
|
)}
|
|
264
250
|
|
|
@@ -9,7 +9,12 @@ import {
|
|
|
9
9
|
ViewStyle,
|
|
10
10
|
} from 'react-native';
|
|
11
11
|
import LinearGradient from 'react-native-linear-gradient';
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
IconMoney2,
|
|
14
|
+
IconQuestion,
|
|
15
|
+
IconTick,
|
|
16
|
+
IconTima16,
|
|
17
|
+
} from '../../assets/svgs';
|
|
13
18
|
import { formatMoney } from '../../utils';
|
|
14
19
|
import { MText } from '../../components/MText';
|
|
15
20
|
import Modal from 'react-native-modal';
|
|
@@ -78,7 +83,7 @@ export default function DigitalTopupItem({
|
|
|
78
83
|
setShowModalInfo(false);
|
|
79
84
|
if (callback) {
|
|
80
85
|
setTimeout(() => {
|
|
81
|
-
callback()
|
|
86
|
+
callback();
|
|
82
87
|
}, 300);
|
|
83
88
|
}
|
|
84
89
|
} else {
|
|
@@ -194,11 +199,7 @@ export default function DigitalTopupItem({
|
|
|
194
199
|
</TouchableOpacity>
|
|
195
200
|
<TouchableOpacity
|
|
196
201
|
style={$action}
|
|
197
|
-
disabled={
|
|
198
|
-
item?.step === 4 || item?.step === 5
|
|
199
|
-
? false
|
|
200
|
-
: true
|
|
201
|
-
}
|
|
202
|
+
disabled={item?.step === 4 || item?.step === 5 ? false : true}
|
|
202
203
|
onPress={() => {
|
|
203
204
|
if (item?.step === 4) {
|
|
204
205
|
navigation.push(ScreenNames.OCR, {
|
|
@@ -206,15 +207,15 @@ export default function DigitalTopupItem({
|
|
|
206
207
|
front: true,
|
|
207
208
|
});
|
|
208
209
|
} else if (item?.step === 5) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
210
|
+
navigation.push(ScreenNames.TopupLoanInfo, {
|
|
211
|
+
loan: item,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
213
214
|
}}
|
|
214
215
|
>
|
|
215
216
|
{item?.step < 4 ? (
|
|
216
217
|
<IconStep2Disable />
|
|
217
|
-
) : item?.step === 4 || item?.step === 5
|
|
218
|
+
) : item?.step === 4 || item?.step === 5 ? (
|
|
218
219
|
<IconStep2 />
|
|
219
220
|
) : (
|
|
220
221
|
<IconStep2Success />
|
|
@@ -227,7 +228,7 @@ export default function DigitalTopupItem({
|
|
|
227
228
|
color:
|
|
228
229
|
item?.step < 4
|
|
229
230
|
? '#999999'
|
|
230
|
-
: item?.step === 4 || item?.step === 5
|
|
231
|
+
: item?.step === 4 || item?.step === 5
|
|
231
232
|
? '#EF592E'
|
|
232
233
|
: '#333333',
|
|
233
234
|
}}
|
|
@@ -314,7 +315,7 @@ export default function DigitalTopupItem({
|
|
|
314
315
|
marginTop: 16,
|
|
315
316
|
}}
|
|
316
317
|
>
|
|
317
|
-
<IconQuestion/>
|
|
318
|
+
<IconQuestion />
|
|
318
319
|
<MText
|
|
319
320
|
style={{
|
|
320
321
|
fontSize: 10,
|
|
@@ -377,7 +378,7 @@ export default function DigitalTopupItem({
|
|
|
377
378
|
? 'Chờ cập nhật thông tin tài sản'
|
|
378
379
|
: item?.step === 3
|
|
379
380
|
? `Chờ cập nhật thông tin khoản vay`
|
|
380
|
-
: item?.step === 4 || item?.step === 5
|
|
381
|
+
: item?.step === 4 || item?.step === 5
|
|
381
382
|
? `Chờ cập nhật thông tin cá nhân`
|
|
382
383
|
: item?.step === 9
|
|
383
384
|
? `Chờ cập nhật eKYC`
|
|
@@ -389,17 +390,16 @@ export default function DigitalTopupItem({
|
|
|
389
390
|
{item?.step <= 1 ? (
|
|
390
391
|
<TouchableOpacity
|
|
391
392
|
onPress={() => {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
}
|
|
393
|
+
if (item?.step === 0) {
|
|
394
|
+
navigation.push(ScreenNames.VehicleCamera, {
|
|
395
|
+
loan: item,
|
|
396
|
+
front: true,
|
|
397
|
+
});
|
|
398
|
+
} else {
|
|
399
|
+
navigation.push(ScreenNames.AssetInformation, {
|
|
400
|
+
loan: item,
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
403
|
}}
|
|
404
404
|
>
|
|
405
405
|
<LinearGradient
|
|
@@ -452,7 +452,7 @@ export default function DigitalTopupItem({
|
|
|
452
452
|
</MText>
|
|
453
453
|
</LinearGradient>
|
|
454
454
|
</TouchableOpacity>
|
|
455
|
-
) : item?.step === 4 || item?.step === 5? (
|
|
455
|
+
) : item?.step === 4 || item?.step === 5 ? (
|
|
456
456
|
<TouchableOpacity
|
|
457
457
|
onPress={() => {
|
|
458
458
|
if (item?.step === 4) {
|
|
@@ -461,11 +461,9 @@ export default function DigitalTopupItem({
|
|
|
461
461
|
front: true,
|
|
462
462
|
});
|
|
463
463
|
} else if (item?.step === 5) {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
});
|
|
468
|
-
|
|
464
|
+
navigation.push(ScreenNames.TopupLoanInfo, {
|
|
465
|
+
loan: item,
|
|
466
|
+
});
|
|
469
467
|
}
|
|
470
468
|
}}
|
|
471
469
|
>
|
|
@@ -580,7 +578,7 @@ export default function DigitalTopupItem({
|
|
|
580
578
|
? 'Vui lòng cập nhật thông tin tài sản để được giải ngân sớm nhất!'
|
|
581
579
|
: item?.step === 3
|
|
582
580
|
? `Vui lòng cập nhật thông tin khoản vay để được giải ngân sớm nhất!`
|
|
583
|
-
: item?.step === 4 || item?.step === 5
|
|
581
|
+
: item?.step === 4 || item?.step === 5
|
|
584
582
|
? `Vui lòng cập nhật thông tin cá nhân để được giải ngân sớm nhất!`
|
|
585
583
|
: item?.step === 9
|
|
586
584
|
? `Bước cuối cùng rồi, vui lòng ký hợp đồng để được giải ngân sớm nhất nhé!`
|
|
@@ -301,12 +301,11 @@ export default function ItemMotoBikeLoan({
|
|
|
301
301
|
paddingVertical: 10,
|
|
302
302
|
}}
|
|
303
303
|
>
|
|
304
|
-
<IconQuestion/>
|
|
304
|
+
<IconQuestion />
|
|
305
305
|
<MText
|
|
306
306
|
style={{
|
|
307
307
|
fontSize: 10,
|
|
308
308
|
flex: 1,
|
|
309
|
-
|
|
310
309
|
}}
|
|
311
310
|
>
|
|
312
311
|
Hướng dẫn các bước hoàn thiện đơn vay
|
|
@@ -710,7 +709,7 @@ export default function ItemMotoBikeLoan({
|
|
|
710
709
|
justifyContent: 'center',
|
|
711
710
|
}}
|
|
712
711
|
>
|
|
713
|
-
<
|
|
712
|
+
<Icon3 />
|
|
714
713
|
</View>
|
|
715
714
|
<View>
|
|
716
715
|
<MText
|
|
@@ -746,7 +745,7 @@ export default function ItemMotoBikeLoan({
|
|
|
746
745
|
justifyContent: 'center',
|
|
747
746
|
}}
|
|
748
747
|
>
|
|
749
|
-
<
|
|
748
|
+
<Icon2 />
|
|
750
749
|
</View>
|
|
751
750
|
<View>
|
|
752
751
|
<MText
|
|
@@ -764,6 +763,47 @@ export default function ItemMotoBikeLoan({
|
|
|
764
763
|
</MText>
|
|
765
764
|
</View>
|
|
766
765
|
|
|
766
|
+
<View>
|
|
767
|
+
<View
|
|
768
|
+
style={{
|
|
769
|
+
flexDirection: 'row',
|
|
770
|
+
alignItems: 'center',
|
|
771
|
+
gap: 8,
|
|
772
|
+
marginTop: 16,
|
|
773
|
+
}}
|
|
774
|
+
>
|
|
775
|
+
<View
|
|
776
|
+
style={{
|
|
777
|
+
width: 30,
|
|
778
|
+
height: 30,
|
|
779
|
+
borderRadius: 4,
|
|
780
|
+
backgroundColor: '#FFF2F2',
|
|
781
|
+
alignItems: 'center',
|
|
782
|
+
justifyContent: 'center',
|
|
783
|
+
}}
|
|
784
|
+
>
|
|
785
|
+
<Icon2 />
|
|
786
|
+
</View>
|
|
787
|
+
<View>
|
|
788
|
+
<MText
|
|
789
|
+
style={{ fontWeight: 'bold', fontSize: 8, color: '#EF592E' }}
|
|
790
|
+
>
|
|
791
|
+
Bước 3
|
|
792
|
+
</MText>
|
|
793
|
+
<MText style={{ fontWeight: 'bold', fontSize: 10 }}>
|
|
794
|
+
NỘP HỒ SƠ VAY
|
|
795
|
+
</MText>
|
|
796
|
+
</View>
|
|
797
|
+
</View>
|
|
798
|
+
<MText style={{ fontSize: 10, marginTop: 5 }}>
|
|
799
|
+
Xác nhận T&C{' '}
|
|
800
|
+
<MText style={{ fontSize: 10, color: '#EF592E' }}>
|
|
801
|
+
(Điều kiện & điều khoản)
|
|
802
|
+
</MText>{' '}
|
|
803
|
+
và nộp hồ sơ vay
|
|
804
|
+
</MText>
|
|
805
|
+
</View>
|
|
806
|
+
|
|
767
807
|
<View
|
|
768
808
|
style={{
|
|
769
809
|
backgroundColor: '#FFF8F2',
|
|
@@ -21,7 +21,10 @@ import {
|
|
|
21
21
|
RESULTS,
|
|
22
22
|
openSettings,
|
|
23
23
|
} from 'react-native-permissions';
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
Camera as VisionCamera,
|
|
26
|
+
useCameraDevice,
|
|
27
|
+
} from 'react-native-vision-camera';
|
|
25
28
|
import { IconBackFill, IconEkyc } from '../../assets/icons';
|
|
26
29
|
import { myLog } from '../../utils/log';
|
|
27
30
|
import { MText } from '../../components/MText';
|
|
@@ -50,6 +53,7 @@ export const LiveNess = observer(function LiveNess(props: any) {
|
|
|
50
53
|
const [flash, setFlash] = useState(false);
|
|
51
54
|
const [front, setFront] = useState(true);
|
|
52
55
|
const myCamera = useRef(null);
|
|
56
|
+
const device = useCameraDevice(front ? 'front' : 'back');
|
|
53
57
|
const loan = props.route.params?.loan;
|
|
54
58
|
const actions = [
|
|
55
59
|
'Ngẩng mặt lên trong 1 giây',
|
|
@@ -195,28 +199,41 @@ export const LiveNess = observer(function LiveNess(props: any) {
|
|
|
195
199
|
};
|
|
196
200
|
|
|
197
201
|
const recordVideo = async () => {
|
|
198
|
-
if (myCamera) {
|
|
202
|
+
if (myCamera.current) {
|
|
199
203
|
setRecording(true);
|
|
200
|
-
const videoFile =
|
|
201
|
-
CachesDirectoryPath + '/' + new Date().getTime() + '.mp4';
|
|
202
|
-
const options = {
|
|
203
|
-
quality: RNCamera.Constants.VideoQuality['720p'],
|
|
204
|
-
maxDuration: 13,
|
|
205
|
-
path: videoFile,
|
|
206
|
-
/** iOS only */
|
|
207
|
-
codec: 'H264',
|
|
208
|
-
fps: 30,
|
|
209
|
-
};
|
|
210
204
|
startLiveNess();
|
|
211
|
-
const data = await
|
|
212
|
-
|
|
205
|
+
const data = await new Promise((resolve, reject) => {
|
|
206
|
+
let stopped = false;
|
|
207
|
+
const timeout = setTimeout(() => {
|
|
208
|
+
if (!stopped) {
|
|
209
|
+
stopped = true;
|
|
210
|
+
myCamera.current?.stopRecording();
|
|
211
|
+
}
|
|
212
|
+
}, 13000);
|
|
213
|
+
myCamera.current.startRecording({
|
|
214
|
+
videoCodec: Platform.OS === 'ios' ? 'h264' : undefined,
|
|
215
|
+
onRecordingFinished: (video) => {
|
|
216
|
+
clearTimeout(timeout);
|
|
217
|
+
resolve(video);
|
|
218
|
+
},
|
|
219
|
+
onRecordingError: (error) => {
|
|
220
|
+
clearTimeout(timeout);
|
|
221
|
+
reject(error);
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
if (data.path) {
|
|
213
226
|
setRecording(false);
|
|
214
227
|
const newPath =
|
|
215
228
|
CachesDirectoryPath + '/' + new Date().getTime() + '.mp4';
|
|
216
|
-
await RNFS.copyFile(data.
|
|
229
|
+
await RNFS.copyFile(data.path, newPath).then(() => {
|
|
217
230
|
console.log('Copied to:', newPath);
|
|
218
231
|
});
|
|
219
|
-
captureFromVideo(
|
|
232
|
+
captureFromVideo(
|
|
233
|
+
Platform.OS === 'android'
|
|
234
|
+
? 'file://' + data?.path
|
|
235
|
+
: 'file://' + newPath
|
|
236
|
+
);
|
|
220
237
|
} else {
|
|
221
238
|
Alert.alert(
|
|
222
239
|
'Thông báo',
|
|
@@ -341,49 +358,21 @@ export const LiveNess = observer(function LiveNess(props: any) {
|
|
|
341
358
|
},
|
|
342
359
|
]}
|
|
343
360
|
>
|
|
344
|
-
{passPermission && (
|
|
345
|
-
<
|
|
361
|
+
{passPermission && device ? (
|
|
362
|
+
<VisionCamera
|
|
346
363
|
ref={myCamera}
|
|
347
|
-
defaultVideoQuality={RNCamera.Constants.VideoQuality['2160p']}
|
|
348
364
|
style={{
|
|
349
365
|
width: Dimensions.get('window').width,
|
|
350
366
|
height: (Dimensions.get('window').width * 4) / 3,
|
|
351
367
|
}}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
: RNCamera.Constants.FlashMode.off
|
|
361
|
-
}
|
|
362
|
-
androidCameraPermissionOptions={{
|
|
363
|
-
title: 'Permission to use camera',
|
|
364
|
-
message: 'We need your permission to use your camera',
|
|
365
|
-
buttonPositive: 'Ok',
|
|
366
|
-
buttonNegative: 'Cancel',
|
|
367
|
-
}}
|
|
368
|
-
androidRecordAudioPermissionOptions={{
|
|
369
|
-
title: 'Permission to use audio recording',
|
|
370
|
-
message: 'We need your permission to use your audio',
|
|
371
|
-
buttonPositive: 'Ok',
|
|
372
|
-
buttonNegative: 'Cancel',
|
|
373
|
-
}}
|
|
374
|
-
// onGoogleVisionBarcodesDetected={({ barcodes }) => {
|
|
375
|
-
// console.log(barcodes);
|
|
376
|
-
// }}
|
|
377
|
-
// onFacesDetected={handlerFace}
|
|
378
|
-
>
|
|
379
|
-
{({ camera, status, recordAudioPermissionStatus }) => {
|
|
380
|
-
if (status !== 'READY') return <ActivityIndicator />;
|
|
381
|
-
else if (status === 'READY' && livenessStore.ready === false) {
|
|
382
|
-
// startLiveNess()
|
|
383
|
-
console.log(status);
|
|
384
|
-
}
|
|
385
|
-
}}
|
|
386
|
-
</RNCamera>
|
|
368
|
+
device={device}
|
|
369
|
+
isActive={true}
|
|
370
|
+
video={true}
|
|
371
|
+
audio={false}
|
|
372
|
+
torch={flash && device.hasTorch ? 'on' : 'off'}
|
|
373
|
+
/>
|
|
374
|
+
) : (
|
|
375
|
+
<ActivityIndicator />
|
|
387
376
|
)}
|
|
388
377
|
</View>
|
|
389
378
|
}
|
|
@@ -24,7 +24,10 @@ import {
|
|
|
24
24
|
import DeviceInfo from 'react-native-device-info';
|
|
25
25
|
import { IconBackWhite, IconEkyc } from '../../assets/icons';
|
|
26
26
|
import { MText } from '../../components/MText';
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
Camera as VisionCamera,
|
|
29
|
+
useCameraDevice,
|
|
30
|
+
} from 'react-native-vision-camera';
|
|
28
31
|
import livenessStore from '../liveness/LivenessStore';
|
|
29
32
|
import { commonStyles } from '../CommonStyles';
|
|
30
33
|
import { ScreenNames } from '../../navigation';
|
|
@@ -51,6 +54,7 @@ export const LivenessV2 = observer(function LivenessV2(props: any) {
|
|
|
51
54
|
const interval = useRef<any>(null);
|
|
52
55
|
const [passPermission, setPassPermission] = useState(false);
|
|
53
56
|
const [isLoading, setIsLoading] = useState(false);
|
|
57
|
+
const device = useCameraDevice('front');
|
|
54
58
|
|
|
55
59
|
const renderHint = (key: string) => {
|
|
56
60
|
switch (key) {
|
|
@@ -356,28 +360,39 @@ export const LivenessV2 = observer(function LivenessV2(props: any) {
|
|
|
356
360
|
livenessStore.saveLiveness(loan.id);
|
|
357
361
|
return;
|
|
358
362
|
}
|
|
359
|
-
if (cameraRef) {
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
363
|
+
if (cameraRef.current) {
|
|
364
|
+
const data = await new Promise((resolve, reject) => {
|
|
365
|
+
let stopped = false;
|
|
366
|
+
const timeout = setTimeout(() => {
|
|
367
|
+
if (!stopped) {
|
|
368
|
+
stopped = true;
|
|
369
|
+
cameraRef.current?.stopRecording();
|
|
370
|
+
}
|
|
371
|
+
}, 3000);
|
|
372
|
+
cameraRef.current.startRecording({
|
|
373
|
+
videoCodec: Platform.OS === 'ios' ? 'h264' : undefined,
|
|
374
|
+
onRecordingFinished: (video) => {
|
|
375
|
+
clearTimeout(timeout);
|
|
376
|
+
resolve(video);
|
|
377
|
+
},
|
|
378
|
+
onRecordingError: (error) => {
|
|
379
|
+
clearTimeout(timeout);
|
|
380
|
+
reject(error);
|
|
381
|
+
},
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
if (data.path) {
|
|
372
385
|
setIsLoading(true);
|
|
373
386
|
// captureFromVideo(data.uri);
|
|
374
387
|
const newPath =
|
|
375
388
|
CachesDirectoryPath + '/' + new Date().getTime() + '.mp4';
|
|
376
|
-
await RNFS.copyFile(data.
|
|
389
|
+
await RNFS.copyFile(data.path, newPath).then(() => {
|
|
377
390
|
console.log('Copied to:', newPath);
|
|
378
391
|
});
|
|
379
392
|
const thump = await extractFramesFromVideo(
|
|
380
|
-
Platform.OS === 'android'
|
|
393
|
+
Platform.OS === 'android'
|
|
394
|
+
? 'file://' + data.path
|
|
395
|
+
: 'file://' + newPath
|
|
381
396
|
);
|
|
382
397
|
if (thump.length > 0) {
|
|
383
398
|
uploadLiveness(thump);
|
|
@@ -465,47 +480,36 @@ export const LivenessV2 = observer(function LivenessV2(props: any) {
|
|
|
465
480
|
</View>
|
|
466
481
|
|
|
467
482
|
<View style={styles.preview}>
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
buttonNegative: 'Cancel',
|
|
483
|
+
{passPermission && device ? (
|
|
484
|
+
<VisionCamera
|
|
485
|
+
ref={cameraRef}
|
|
486
|
+
style={StyleSheet.absoluteFill}
|
|
487
|
+
device={device}
|
|
488
|
+
isActive={true}
|
|
489
|
+
video={true}
|
|
490
|
+
audio={false}
|
|
491
|
+
/>
|
|
492
|
+
) : null}
|
|
493
|
+
<View
|
|
494
|
+
style={{
|
|
495
|
+
height: '100%',
|
|
496
|
+
width: '100%',
|
|
497
|
+
justifyContent: 'center',
|
|
498
|
+
alignItems: 'center',
|
|
485
499
|
}}
|
|
486
|
-
autoFocus="on"
|
|
487
500
|
>
|
|
488
|
-
|
|
501
|
+
{renderImg(livenessStore.hintAction)}
|
|
502
|
+
<MText
|
|
489
503
|
style={{
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
504
|
+
color: 'white',
|
|
505
|
+
fontSize: 16,
|
|
506
|
+
marginTop: 8,
|
|
507
|
+
fontWeight: '400',
|
|
494
508
|
}}
|
|
495
509
|
>
|
|
496
|
-
{
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
color: 'white',
|
|
500
|
-
fontSize: 16,
|
|
501
|
-
marginTop: 8,
|
|
502
|
-
fontWeight: '400',
|
|
503
|
-
}}
|
|
504
|
-
>
|
|
505
|
-
{renderHint(livenessStore.hintAction)}
|
|
506
|
-
</MText>
|
|
507
|
-
</View>
|
|
508
|
-
</RNCamera>
|
|
510
|
+
{renderHint(livenessStore.hintAction)}
|
|
511
|
+
</MText>
|
|
512
|
+
</View>
|
|
509
513
|
</View>
|
|
510
514
|
|
|
511
515
|
<View style={styles.circularProgress}>
|
|
@@ -518,10 +522,10 @@ export const LivenessV2 = observer(function LivenessV2(props: any) {
|
|
|
518
522
|
livenessStore.listAction.length === 3
|
|
519
523
|
? 0
|
|
520
524
|
: livenessStore.listAction.length === 2
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
+
? 100 / 3
|
|
526
|
+
: livenessStore.listAction.length === 1
|
|
527
|
+
? (2 / 3) * 100
|
|
528
|
+
: 100
|
|
525
529
|
}
|
|
526
530
|
radius={PREVIEW_SIZE / 2}
|
|
527
531
|
inActiveStrokeOpacity={0.5}
|