react-native-timacare 2.0.2 → 2.0.3

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.
Files changed (84) hide show
  1. package/lib/commonjs/assets/img/blink.png +0 -0
  2. package/lib/commonjs/assets/img/down.png +0 -0
  3. package/lib/commonjs/assets/img/left.png +0 -0
  4. package/lib/commonjs/assets/img/mouth.png +0 -0
  5. package/lib/commonjs/assets/img/right.png +0 -0
  6. package/lib/commonjs/assets/img/up.png +0 -0
  7. package/lib/commonjs/navigation/primary-navigator.js +1 -1
  8. package/lib/commonjs/navigation/primary-navigator.js.flow +1 -1
  9. package/lib/commonjs/navigation/primary-navigator.js.map +1 -1
  10. package/lib/commonjs/screens/full-submit/selfie.js +1 -1
  11. package/lib/commonjs/screens/full-submit/selfie.js.flow +2 -1
  12. package/lib/commonjs/screens/full-submit/selfie.js.map +1 -1
  13. package/lib/commonjs/screens/home/index.js +1 -1
  14. package/lib/commonjs/screens/home/index.js.flow +1 -0
  15. package/lib/commonjs/screens/home/index.js.map +1 -1
  16. package/lib/commonjs/screens/liveness/LivenessStore.js +1 -1
  17. package/lib/commonjs/screens/liveness/LivenessStore.js.flow +146 -0
  18. package/lib/commonjs/screens/liveness/LivenessStore.js.map +1 -1
  19. package/lib/commonjs/screens/liveness/index.js +1 -1
  20. package/lib/commonjs/screens/liveness/index.js.flow +4 -0
  21. package/lib/commonjs/screens/liveness/index.js.map +1 -1
  22. package/lib/commonjs/screens/liveness-v2/index.js +2 -0
  23. package/lib/commonjs/screens/liveness-v2/index.js.flow +598 -0
  24. package/lib/commonjs/screens/liveness-v2/index.js.map +1 -0
  25. package/lib/commonjs/screens/mrz-scanner/index.js +1 -1
  26. package/lib/commonjs/screens/mrz-scanner/index.js.flow +1 -0
  27. package/lib/commonjs/screens/mrz-scanner/index.js.map +1 -1
  28. package/lib/commonjs/screens/selfie/index.js +1 -1
  29. package/lib/commonjs/screens/selfie/index.js.flow +12 -2
  30. package/lib/commonjs/screens/selfie/index.js.map +1 -1
  31. package/lib/commonjs/services/api/api.js +1 -1
  32. package/lib/commonjs/services/api/api.js.flow +68 -0
  33. package/lib/commonjs/services/api/api.js.map +1 -1
  34. package/lib/module/assets/img/blink.png +0 -0
  35. package/lib/module/assets/img/down.png +0 -0
  36. package/lib/module/assets/img/left.png +0 -0
  37. package/lib/module/assets/img/mouth.png +0 -0
  38. package/lib/module/assets/img/right.png +0 -0
  39. package/lib/module/assets/img/up.png +0 -0
  40. package/lib/module/navigation/primary-navigator.js +1 -1
  41. package/lib/module/navigation/primary-navigator.js.map +1 -1
  42. package/lib/module/screens/full-submit/selfie.js +1 -1
  43. package/lib/module/screens/full-submit/selfie.js.map +1 -1
  44. package/lib/module/screens/home/index.js +1 -1
  45. package/lib/module/screens/home/index.js.map +1 -1
  46. package/lib/module/screens/liveness/LivenessStore.js +1 -1
  47. package/lib/module/screens/liveness/LivenessStore.js.map +1 -1
  48. package/lib/module/screens/liveness/index.js +1 -1
  49. package/lib/module/screens/liveness/index.js.map +1 -1
  50. package/lib/module/screens/liveness-v2/index.js +2 -0
  51. package/lib/module/screens/liveness-v2/index.js.map +1 -0
  52. package/lib/module/screens/mrz-scanner/index.js +1 -1
  53. package/lib/module/screens/mrz-scanner/index.js.map +1 -1
  54. package/lib/module/screens/selfie/index.js +1 -1
  55. package/lib/module/screens/selfie/index.js.map +1 -1
  56. package/lib/module/services/api/api.js +1 -1
  57. package/lib/module/services/api/api.js.map +1 -1
  58. package/lib/typescript/screens/full-submit/selfie.d.ts.map +1 -1
  59. package/lib/typescript/screens/home/index.d.ts.map +1 -1
  60. package/lib/typescript/screens/liveness/LivenessStore.d.ts +7 -0
  61. package/lib/typescript/screens/liveness/LivenessStore.d.ts.map +1 -1
  62. package/lib/typescript/screens/liveness/index.d.ts.map +1 -1
  63. package/lib/typescript/screens/liveness-v2/index.d.ts +2 -0
  64. package/lib/typescript/screens/liveness-v2/index.d.ts.map +1 -0
  65. package/lib/typescript/screens/mrz-scanner/index.d.ts.map +1 -1
  66. package/lib/typescript/screens/selfie/index.d.ts.map +1 -1
  67. package/lib/typescript/services/api/api.d.ts +64 -0
  68. package/lib/typescript/services/api/api.d.ts.map +1 -1
  69. package/package.json +2 -1
  70. package/src/assets/img/blink.png +0 -0
  71. package/src/assets/img/down.png +0 -0
  72. package/src/assets/img/left.png +0 -0
  73. package/src/assets/img/mouth.png +0 -0
  74. package/src/assets/img/right.png +0 -0
  75. package/src/assets/img/up.png +0 -0
  76. package/src/navigation/primary-navigator.tsx +1 -1
  77. package/src/screens/full-submit/selfie.tsx +2 -1
  78. package/src/screens/home/index.tsx +1 -0
  79. package/src/screens/liveness/LivenessStore.tsx +146 -0
  80. package/src/screens/liveness/index.tsx +4 -0
  81. package/src/screens/liveness-v2/index.tsx +598 -0
  82. package/src/screens/mrz-scanner/index.tsx +1 -0
  83. package/src/screens/selfie/index.tsx +12 -2
  84. package/src/services/api/api.ts +68 -0
@@ -0,0 +1,598 @@
1
+ //@ts-nocheck
2
+ import React, { useRef, useState } from 'react';
3
+ import { CommonActions, useNavigation } from '@react-navigation/native';
4
+ import { Observer, observer } from 'mobx-react-lite';
5
+ import {
6
+ ActivityIndicator,
7
+ Alert,
8
+ Dimensions,
9
+ Image,
10
+ Modal,
11
+ Platform,
12
+ StyleSheet,
13
+ TouchableOpacity,
14
+ View,
15
+ } from 'react-native';
16
+ import CircularProgress from 'react-native-circular-progress-indicator';
17
+ import RNFS, { CachesDirectoryPath } from 'react-native-fs';
18
+ import { RNFFmpeg } from 'react-native-ffmpeg';
19
+ import {
20
+ PERMISSIONS,
21
+ RESULTS,
22
+ openSettings,
23
+ request,
24
+ } from 'react-native-permissions';
25
+ import DeviceInfo from 'react-native-device-info';
26
+ import { IconBackWhite, IconEkyc } from '../../assets/icons';
27
+ import { MText } from '../../components/MText';
28
+ import { RNCamera } from 'react-native-camera';
29
+ import livenessStore from '../liveness/LivenessStore';
30
+ import { commonStyles } from '../CommonStyles';
31
+ import { ScreenNames } from '../../navigation';
32
+ import { color } from '../../theme';
33
+
34
+ const { width: windowWidth } = Dimensions.get('window');
35
+
36
+ const PREVIEW_SIZE = 320;
37
+ const PREVIEW_RECT = {
38
+ minX: (windowWidth - PREVIEW_SIZE) / 2,
39
+ minY: 240,
40
+ width: PREVIEW_SIZE,
41
+ height: PREVIEW_SIZE,
42
+ };
43
+ export const LivenessV2 = observer(function LivenessV2(props: any) {
44
+ const loan = props.route.params?.loan;
45
+ const navigation = useNavigation();
46
+ const cameraRef = useRef<any>(null);
47
+ const interval = useRef<any>(null);
48
+ const [passPermission, setPassPermission] = useState(false);
49
+ const [isLoading, setIsLoading] = useState(false);
50
+
51
+ const renderHint = (key: string) => {
52
+ switch (key) {
53
+ case 'blink':
54
+ return 'Nhắm mắt trong 3 giây';
55
+ case 'right':
56
+ return 'Quay sang phải 3 giây';
57
+ case 'left':
58
+ return 'Quay sang trái 3 giây';
59
+ case 'up':
60
+ return 'Nhìn lên trên 3 giây';
61
+ case 'down':
62
+ return 'Nhìn xuống dưới 3 giây';
63
+ case 'mouth':
64
+ return 'Há miệng trong 3 giây';
65
+ default:
66
+ return '';
67
+ }
68
+ };
69
+ const renderImg = (key: string) => {
70
+ switch (key) {
71
+ case 'blink':
72
+ return (
73
+ <Image
74
+ source={require('../../assets/img/blink.png')}
75
+ style={{
76
+ height: 24,
77
+ width: 50,
78
+ resizeMode: 'contain',
79
+ marginTop: 40,
80
+ }}
81
+ />
82
+ );
83
+ case 'right':
84
+ return (
85
+ <Image
86
+ source={require('../../assets/img/right.png')}
87
+ style={{
88
+ height: 24,
89
+ width: 50,
90
+ resizeMode: 'contain',
91
+ marginTop: 40,
92
+ }}
93
+ />
94
+ );
95
+ case 'left':
96
+ return (
97
+ <Image
98
+ source={require('../../assets/img/left.png')}
99
+ style={{
100
+ height: 24,
101
+ width: 50,
102
+ resizeMode: 'contain',
103
+ marginTop: 40,
104
+ }}
105
+ />
106
+ );
107
+ case 'up':
108
+ return (
109
+ <Image
110
+ source={require('../../assets/img/up.png')}
111
+ style={{
112
+ height: 24,
113
+ width: 50,
114
+ resizeMode: 'contain',
115
+ marginTop: 40,
116
+ }}
117
+ />
118
+ );
119
+ case 'down':
120
+ return (
121
+ <Image
122
+ source={require('../../assets/img/down.png')}
123
+ style={{
124
+ height: 24,
125
+ width: 50,
126
+ resizeMode: 'contain',
127
+ marginTop: 40,
128
+ }}
129
+ />
130
+ );
131
+ case 'mouth':
132
+ return (
133
+ <Image
134
+ source={require('../../assets/img/mouth.png')}
135
+ style={{
136
+ height: 24,
137
+ width: 50,
138
+ resizeMode: 'contain',
139
+ marginTop: 40,
140
+ }}
141
+ />
142
+ );
143
+ default:
144
+ return <></>;
145
+ }
146
+ };
147
+
148
+ const requestPermissions = () => {
149
+ request(
150
+ Platform.OS === 'ios'
151
+ ? PERMISSIONS.IOS.CAMERA
152
+ : PERMISSIONS.ANDROID.CAMERA
153
+ ).then((result) => {
154
+ switch (result) {
155
+ case RESULTS.UNAVAILABLE:
156
+ console.log(
157
+ 'This feature is not available (on this device / in this context)'
158
+ );
159
+ Alert.alert(
160
+ 'Thông báo',
161
+ 'Máy ảnh trên thiết bị không tương thích.\nVui lòng kiểm tra lại thiết bị!',
162
+ [{ text: 'Đồng ý' }]
163
+ );
164
+ break;
165
+ case RESULTS.DENIED:
166
+ console.log(
167
+ 'The permission has not been requested / is denied but requestable'
168
+ );
169
+ Alert.alert(
170
+ 'Thông báo',
171
+ 'Bạn đã từ chối quyền máy ảnh. Vui lòng cấp quyền máy ảnh để tiếp tục!',
172
+ [
173
+ {
174
+ text: 'Đồng ý',
175
+ onPress: () => {
176
+ if (Platform.OS === 'ios') {
177
+ openSettings();
178
+ } else {
179
+ requestPermissions();
180
+ }
181
+ },
182
+ },
183
+ ]
184
+ );
185
+ break;
186
+
187
+ case RESULTS.GRANTED:
188
+ console.log('The permission is granted');
189
+ setPassPermission(true);
190
+ break;
191
+ case RESULTS.BLOCKED:
192
+ console.log('The permission is denied and not requestable anymore');
193
+ Alert.alert(
194
+ 'Thông báo',
195
+ 'Bạn đã từ chối quyền máy ảnh. Vui lòng cấp quyền máy ảnh để tiếp tục!',
196
+ [
197
+ {
198
+ text: 'Đồng ý',
199
+ onPress: () => {
200
+ if (Platform.OS === 'ios') {
201
+ openSettings();
202
+ } else {
203
+ openSettings();
204
+ }
205
+ },
206
+ },
207
+ ]
208
+ );
209
+ break;
210
+ }
211
+ });
212
+ };
213
+
214
+ let second = 3;
215
+
216
+ const start = () => {
217
+ requestPermissions();
218
+ livenessStore.getListAction(() => {
219
+ if (passPermission) {
220
+ interval.current = setInterval(() => {
221
+ second--;
222
+ if (second === 0) {
223
+ clearInterval(interval.current);
224
+ startLiveness();
225
+ }
226
+ }, 1000);
227
+ }
228
+ });
229
+ };
230
+
231
+ useEffect(() => {
232
+ start();
233
+ }, [passPermission]);
234
+
235
+ const uploadLiveness = async (template: any) => {
236
+ try {
237
+ const listImage = [];
238
+ for (let i = 1; i <= 3; i++) {
239
+ const file = 'file://' + template + `_img_${('000' + i).slice(-4)}.jpg`;
240
+ const imgBase64 = await RNFS.readFile(file, 'base64');
241
+ listImage.push(imgBase64);
242
+ }
243
+ await livenessStore.verifyLiveness(
244
+ loan?.id,
245
+ listImage,
246
+ () => {
247
+ setTimeout(() => {
248
+ startLiveness();
249
+ }, 2000);
250
+ setIsLoading(false);
251
+ },
252
+ () => {
253
+ setTimeout(() => {
254
+ startLiveness();
255
+ }, 2000);
256
+ setIsLoading(false);
257
+ }
258
+ );
259
+ } catch (error) {
260
+ setIsLoading(false);
261
+ }
262
+ };
263
+
264
+ const captureFromVideo = async (uri: any) => {
265
+ try {
266
+ const time = new Date().getTime();
267
+ const template = CachesDirectoryPath + '/' + time;
268
+ const output = template + '_img_%04d.jpg';
269
+ RNFFmpeg.execute(`-i ${uri} -r 2 ${output}`)
270
+ .then((result) => {
271
+ console.log(`FFmpeg process exited with rc=${result}.`);
272
+ if (result === 0) {
273
+ uploadLiveness(template);
274
+ console.log('FFmpeg template', template);
275
+ } else {
276
+ setIsLoading(false);
277
+ Alert.alert(
278
+ 'Thông báo',
279
+ 'Quá trình xử lý hình ảnh bị lỗi. Vui lòng thử lại.',
280
+ [
281
+ {
282
+ text: 'Đồng ý',
283
+ onPress: () => {
284
+ startLiveness;
285
+ },
286
+ },
287
+ ]
288
+ );
289
+ }
290
+ })
291
+ .catch((err) => {
292
+ console.log(err);
293
+ });
294
+ } catch (error) {
295
+ setIsLoading(false);
296
+ }
297
+ };
298
+
299
+ const startLiveness = async () => {
300
+ livenessStore.ekycSuccess = false;
301
+ if (livenessStore.listAction.length === 0) {
302
+ livenessStore.ekycSuccess = true;
303
+ livenessStore.saveLiveness(loan.id);
304
+ return;
305
+ }
306
+ if (cameraRef) {
307
+ const videoFile =
308
+ CachesDirectoryPath + '/' + new Date().getTime() + '.mp4';
309
+ const options = {
310
+ quality: RNCamera.Constants.VideoQuality['720p'],
311
+ maxDuration: 3,
312
+ path: videoFile,
313
+ /** iOS only */
314
+ codec: 'H264',
315
+ fps: 30,
316
+ };
317
+ const data = await cameraRef.current.recordAsync(options);
318
+ if (data.uri) {
319
+ setIsLoading(true);
320
+ captureFromVideo(data.uri);
321
+ } else {
322
+ Alert.alert('Thông báo', 'Quá trình xác thực thất bại', [
323
+ {
324
+ text: 'Thử lại',
325
+ onPress: () => {
326
+ startLiveness();
327
+ },
328
+ },
329
+ ]);
330
+ }
331
+ }
332
+ };
333
+ return (
334
+ <View style={styles.container}>
335
+ <TouchableOpacity
336
+ onPress={() => {
337
+ navigation.goBack();
338
+ }}
339
+ style={{
340
+ position: 'absolute',
341
+ left: 16,
342
+ top: DeviceInfo.hasNotch() ? 70 : 16,
343
+ width: 40,
344
+ height: 40,
345
+ zIndex: 1000,
346
+ }}
347
+ >
348
+ <IconBackWhite />
349
+ </TouchableOpacity>
350
+ <View style={styles.topOverlay}>
351
+ <MText
352
+ style={{
353
+ color: 'white',
354
+ fontWeight: '600',
355
+ fontSize: 16,
356
+ }}
357
+ >
358
+ Xác thực khuôn mặt
359
+ </MText>
360
+ <Observer>
361
+ {() => (
362
+ <>
363
+ {isLoading ? (
364
+ <View style={{ marginTop: 24 }}>
365
+ <MText
366
+ style={{
367
+ textAlign: 'center',
368
+ fontSize: 16,
369
+ color: 'white',
370
+ }}
371
+ >
372
+ Đang xác thực
373
+ </MText>
374
+ <ActivityIndicator
375
+ size={'large'}
376
+ color={'white'}
377
+ style={{ marginTop: 8 }}
378
+ />
379
+ </View>
380
+ ) : (
381
+ <></>
382
+ )}
383
+ </>
384
+ )}
385
+ </Observer>
386
+ </View>
387
+
388
+ <View style={styles.preview}>
389
+ <RNCamera
390
+ playSoundOnCapture={false}
391
+ ref={cameraRef}
392
+ style={StyleSheet.absoluteFill}
393
+ captureAudio={false}
394
+ type={RNCamera.Constants.Type.front}
395
+ androidCameraPermissionOptions={{
396
+ title: 'Permission to use camera',
397
+ message: 'We need your permission to use your camera',
398
+ buttonPositive: 'Ok',
399
+ buttonNegative: 'Cancel',
400
+ }}
401
+ androidRecordAudioPermissionOptions={{
402
+ title: 'Permission to use audio recording',
403
+ message: 'We need your permission to use your audio',
404
+ buttonPositive: 'Ok',
405
+ buttonNegative: 'Cancel',
406
+ }}
407
+ autoFocus="on"
408
+ >
409
+ <View
410
+ style={{
411
+ height: '100%',
412
+ width: '100%',
413
+ justifyContent: 'center',
414
+ alignItems: 'center',
415
+ }}
416
+ >
417
+ {renderImg(livenessStore.hintAction)}
418
+ <MText
419
+ style={{
420
+ color: 'white',
421
+ fontSize: 16,
422
+ marginTop: 8,
423
+ fontWeight: '400',
424
+ }}
425
+ >
426
+ {renderHint(livenessStore.hintAction)}
427
+ </MText>
428
+ </View>
429
+ </RNCamera>
430
+ </View>
431
+
432
+ <View style={styles.circularProgress}>
433
+ <CircularProgress
434
+ dashedStrokeConfig={{
435
+ count: 100,
436
+ width: 7,
437
+ }}
438
+ value={
439
+ livenessStore.listAction.length === 3
440
+ ? 0
441
+ : livenessStore.listAction.length === 2
442
+ ? 100 / 3
443
+ : livenessStore.listAction.length === 1
444
+ ? (2 / 3) * 100
445
+ : 100
446
+ }
447
+ radius={PREVIEW_SIZE / 2}
448
+ inActiveStrokeOpacity={0.5}
449
+ activeStrokeWidth={13}
450
+ inActiveStrokeWidth={13}
451
+ showProgressValue={false}
452
+ activeStrokeColor="#F05123"
453
+ inActiveStrokeColor="#F05123"
454
+ duration={800}
455
+ />
456
+ </View>
457
+ <Observer>
458
+ {() => (
459
+ <View style={styles.bottomOverlay}>
460
+ <MText style={styles.instructionText}>
461
+ Vui lòng điều chỉnh khuôn mặt nằm gọn trong vòng tròn ở trên
462
+ </MText>
463
+ </View>
464
+ )}
465
+ </Observer>
466
+
467
+ <Modal
468
+ visible={livenessStore.ekycSuccess}
469
+ animationType={'fade'}
470
+ transparent
471
+ >
472
+ <View
473
+ style={[
474
+ commonStyles.alignCenter,
475
+ commonStyles.justifyCenter,
476
+ { backgroundColor: 'transparent', height: '100%' },
477
+ ]}
478
+ >
479
+ <View
480
+ style={[
481
+ commonStyles.alignCenter,
482
+ commonStyles.justifyCenter,
483
+ {
484
+ backgroundColor: 'white',
485
+ borderRadius: 8,
486
+ padding: 16,
487
+ marginHorizontal: 16,
488
+ },
489
+ ]}
490
+ >
491
+ <IconEkyc />
492
+ <MText
493
+ style={[
494
+ commonStyles.textNormalBold,
495
+ { marginTop: 16, textAlign: 'center' },
496
+ ]}
497
+ >
498
+ Chúc mừng bạn đã thực hiện xác thực khách hàng{'\n'}thành công.
499
+ </MText>
500
+ <TouchableOpacity
501
+ style={{
502
+ marginTop: 16,
503
+ backgroundColor: color.primary,
504
+ height: 40,
505
+ alignItems: 'center',
506
+ borderRadius: 30,
507
+ width: 150,
508
+ justifyContent: 'center',
509
+ }}
510
+ onPress={() => {
511
+ livenessStore.ekycSuccess = false;
512
+ navigation.dispatch(
513
+ CommonActions.reset({
514
+ index: 1,
515
+ routes: [{ name: ScreenNames.Main }],
516
+ })
517
+ );
518
+ }}
519
+ >
520
+ <MText style={[commonStyles.textNormalBold, { color: 'white' }]}>
521
+ Đồng ý
522
+ </MText>
523
+ </TouchableOpacity>
524
+ </View>
525
+ </View>
526
+ </Modal>
527
+ </View>
528
+ );
529
+ });
530
+
531
+ const styles = StyleSheet.create({
532
+ instructionText: {
533
+ color: 'white',
534
+ fontSize: 12,
535
+ textAlign: 'center',
536
+ paddingHorizontal: 50,
537
+ marginTop: 16,
538
+ },
539
+ bottomOverlay: {
540
+ marginTop: 24,
541
+ },
542
+ maskedView: {
543
+ flex: 1,
544
+ flexDirection: 'row',
545
+ height: '100%',
546
+ },
547
+ maskWrapper: {
548
+ backgroundColor: 'transparent',
549
+ flex: 1,
550
+ justifyContent: 'center',
551
+ alignItems: 'center',
552
+ },
553
+ mask: {
554
+ borderRadius: PREVIEW_SIZE / 2,
555
+ height: PREVIEW_SIZE - 10,
556
+ width: PREVIEW_SIZE - 10,
557
+ marginTop: PREVIEW_RECT.minY,
558
+ alignSelf: 'center',
559
+ },
560
+ container: {
561
+ flex: 1,
562
+ flexDirection: 'column',
563
+ backgroundColor: '#333333',
564
+ },
565
+ topOverlay: {
566
+ position: 'absolute',
567
+ top: DeviceInfo.hasNotch() ? 70 : 16,
568
+ right: 0,
569
+ left: 0,
570
+ justifyContent: 'center',
571
+ alignItems: 'center',
572
+ },
573
+ captureFrame: {
574
+ height: Dimensions.get('window').width - 50,
575
+ marginHorizontal: 16,
576
+ marginTop: '50%',
577
+ borderRadius: 50,
578
+ },
579
+ preview: {
580
+ width: PREVIEW_SIZE - 29,
581
+ height: PREVIEW_SIZE - 28,
582
+ marginTop: PREVIEW_RECT.minY + 14,
583
+ marginLeft: PREVIEW_RECT.minX + 14,
584
+ borderRadius: PREVIEW_SIZE / 2,
585
+ overflow: 'hidden',
586
+ },
587
+ circularProgress: {
588
+ width: PREVIEW_SIZE,
589
+ height: PREVIEW_SIZE,
590
+ marginTop: PREVIEW_RECT.minY,
591
+ marginLeft: PREVIEW_RECT.minX,
592
+ zIndex: 100,
593
+ position: 'absolute',
594
+ top: 0,
595
+ left: 0,
596
+ right: 0,
597
+ },
598
+ });
@@ -26,6 +26,7 @@ import MButton from '../../components/MButton';
26
26
  import { IconBackWhite } from '../../assets/icons';
27
27
  import { commonStyles } from '../CommonStyles';
28
28
  import nfcStore from './store';
29
+ import { ScreenNames } from '../../navigation';
29
30
 
30
31
  const { NFCReader } = NativeModules;
31
32
 
@@ -33,6 +33,7 @@ import selfieStore from './SelfieStore';
33
33
  import nationalIDStore from '../nationalID/Store';
34
34
  import Loading from '../../components/Loading';
35
35
  import LinearGradient from 'react-native-linear-gradient';
36
+ import livenessStore from '../liveness/LivenessStore';
36
37
 
37
38
  const logoView: ImageStyle = {
38
39
  position: 'absolute',
@@ -72,8 +73,17 @@ export const Selfie = observer(function Selfie(props: any) {
72
73
 
73
74
  selfieStore.checkSelfieImage(formSelfie, loan.id, () => {
74
75
  selfieStore.uploadImage(form, () => {
75
- //@ts-ignore
76
- navigation.push(ScreenNames.LiveNess, { loan });
76
+ livenessStore.getConfigLiveness((data) => {
77
+ if (data === 1) {
78
+ navigation.dispatch(
79
+ StackActions.push(ScreenNames.LiveNess, { loan })
80
+ );
81
+ } else {
82
+ navigation.dispatch(
83
+ StackActions.push(ScreenNames.LivenessV2, { loan })
84
+ );
85
+ }
86
+ });
77
87
  });
78
88
  });
79
89
  };
@@ -2375,4 +2375,72 @@ export class Api {
2375
2375
  }
2376
2376
  }
2377
2377
 
2378
+ async verifyLiveness(body: any) {
2379
+ // make the api call
2380
+ const response: ApiResponse<any> = await this.apisauce.post(`api/v1.0/timacare/livenessv2`, body)
2381
+ myLog(response)
2382
+ // the typical ways to die when calling an api
2383
+ if (!response.ok) {
2384
+ const problem = getGeneralApiProblem(response)
2385
+ if (problem) return problem
2386
+ }
2387
+ // transform the data into the format we are expecting
2388
+ try {
2389
+ return { kind: "ok", data: response.data }
2390
+ } catch {
2391
+ return { kind: "bad-data" }
2392
+ }
2393
+ }
2394
+
2395
+ async saveImages(body: any) {
2396
+ // make the api call
2397
+ const response: ApiResponse<any> = await this.apisauce.post(`api/v1.0/timacare/save_image_liveness`, body)
2398
+ myLog(response)
2399
+ // the typical ways to die when calling an api
2400
+ if (!response.ok) {
2401
+ const problem = getGeneralApiProblem(response)
2402
+ if (problem) return problem
2403
+ }
2404
+ // transform the data into the format we are expecting
2405
+ try {
2406
+ return { kind: "ok", data: response.data }
2407
+ } catch {
2408
+ return { kind: "bad-data" }
2409
+ }
2410
+ }
2411
+
2412
+ async getActionLiveness() {
2413
+ // make the api call
2414
+ const response: ApiResponse<any> = await this.apisauce.get(`api/v1.0/timacare/get_action_liveness`)
2415
+ myLog(response)
2416
+ // the typical ways to die when calling an api
2417
+ if (!response.ok) {
2418
+ const problem = getGeneralApiProblem(response)
2419
+ if (problem) return problem
2420
+ }
2421
+ // transform the data into the format we are expecting
2422
+ try {
2423
+ return { kind: "ok", data: response.data }
2424
+ } catch {
2425
+ return { kind: "bad-data" }
2426
+ }
2427
+ }
2428
+
2429
+ async getConfigLiveness() {
2430
+ // make the api call
2431
+ const response: ApiResponse<any> = await this.apisauce.get(`api/v1.0/timacare/get_config_liveness`)
2432
+ myLog(response)
2433
+ // the typical ways to die when calling an api
2434
+ if (!response.ok) {
2435
+ const problem = getGeneralApiProblem(response)
2436
+ if (problem) return problem
2437
+ }
2438
+ // transform the data into the format we are expecting
2439
+ try {
2440
+ return { kind: "ok", data: response.data }
2441
+ } catch {
2442
+ return { kind: "bad-data" }
2443
+ }
2444
+ }
2445
+
2378
2446
  }