@trustchex/react-native-sdk 1.374.0 → 1.409.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/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraView.kt +1 -21
- package/android/src/main/java/com/trustchex/reactnativesdk/mlkit/MLKitModule.kt +1 -1
- package/android/src/main/java/com/trustchex/reactnativesdk/opencv/OpenCVModule.kt +636 -301
- package/ios/Camera/TrustchexCameraView.swift +9 -20
- package/ios/MLKit/MLKitModule.swift +1 -1
- package/ios/OpenCV/OpenCVHelper.h +0 -7
- package/ios/OpenCV/OpenCVHelper.mm +0 -60
- package/ios/OpenCV/OpenCVModule.h +0 -4
- package/ios/OpenCV/OpenCVModule.mm +440 -358
- package/lib/module/Screens/Debug/BarcodeTestScreen.js +308 -0
- package/lib/module/Screens/Debug/MRZTestScreen.js +105 -13
- package/lib/module/Screens/Dynamic/ContractAcceptanceScreen.js +49 -29
- package/lib/module/Screens/Dynamic/IdentityDocumentEIDScanningScreen.js +5 -0
- package/lib/module/Screens/Dynamic/IdentityDocumentScanningScreen.js +5 -0
- package/lib/module/Screens/Dynamic/LivenessDetectionScreen.js +26 -6
- package/lib/module/Screens/Dynamic/VideoCallScreen.js +676 -0
- package/lib/module/Screens/Static/OTPVerificationScreen.js +6 -0
- package/lib/module/Screens/Static/QrCodeScanningScreen.js +7 -1
- package/lib/module/Screens/Static/ResultScreen.js +27 -13
- package/lib/module/Screens/Static/VerificationSessionCheckScreen.js +51 -51
- package/lib/module/Shared/Animations/video-call.json +1 -0
- package/lib/module/Shared/Components/DebugNavigationPanel.js +180 -14
- package/lib/module/Shared/Components/DebugOverlay.js +541 -0
- package/lib/module/Shared/Components/EIDScanner.js +1 -4
- package/lib/module/Shared/Components/IdentityDocumentCamera.constants.js +44 -0
- package/lib/module/Shared/Components/IdentityDocumentCamera.flows.js +270 -0
- package/lib/module/Shared/Components/IdentityDocumentCamera.js +702 -1703
- package/lib/module/Shared/Components/IdentityDocumentCamera.types.js +3 -0
- package/lib/module/Shared/Components/IdentityDocumentCamera.utils.js +273 -0
- package/lib/module/Shared/Components/NavigationManager.js +15 -3
- package/lib/module/Shared/Contexts/AppContext.js +1 -0
- package/lib/module/Shared/Libs/SignalingClient.js +128 -0
- package/lib/module/Shared/Libs/analytics.utils.js +4 -0
- package/lib/module/Shared/Libs/deeplink.utils.js +9 -1
- package/lib/module/Shared/Libs/http-client.js +9 -0
- package/lib/module/Shared/Libs/promise.utils.js +16 -2
- package/lib/module/Shared/Libs/status-bar.utils.js +21 -0
- package/lib/module/Shared/Services/DataUploadService.js +294 -0
- package/lib/module/Shared/Services/VideoSessionService.js +156 -0
- package/lib/module/Shared/Services/WebRTCService.js +510 -0
- package/lib/module/Shared/Types/analytics.types.js +2 -0
- package/lib/module/Translation/Resources/en.js +20 -0
- package/lib/module/Translation/Resources/tr.js +20 -0
- package/lib/module/Trustchex.js +10 -0
- package/lib/module/version.js +1 -1
- package/lib/typescript/src/Screens/Debug/BarcodeTestScreen.d.ts +3 -0
- package/lib/typescript/src/Screens/Debug/BarcodeTestScreen.d.ts.map +1 -0
- package/lib/typescript/src/Screens/Debug/MRZTestScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Dynamic/ContractAcceptanceScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Dynamic/IdentityDocumentScanningScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Dynamic/LivenessDetectionScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Dynamic/VideoCallScreen.d.ts +3 -0
- package/lib/typescript/src/Screens/Dynamic/VideoCallScreen.d.ts.map +1 -0
- package/lib/typescript/src/Screens/Static/OTPVerificationScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Static/QrCodeScanningScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Static/ResultScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Static/VerificationSessionCheckScreen.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/DebugNavigationPanel.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/DebugOverlay.d.ts +30 -0
- package/lib/typescript/src/Shared/Components/DebugOverlay.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Components/EIDScanner.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts +35 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts +3 -56
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts +88 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts +116 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts +93 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Components/NavigationManager.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Contexts/AppContext.d.ts +1 -0
- package/lib/typescript/src/Shared/Contexts/AppContext.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/SignalingClient.d.ts +24 -0
- package/lib/typescript/src/Shared/Libs/SignalingClient.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Libs/analytics.utils.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/deeplink.utils.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/http-client.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/promise.utils.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/status-bar.utils.d.ts +9 -0
- package/lib/typescript/src/Shared/Libs/status-bar.utils.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Services/DataUploadService.d.ts +25 -0
- package/lib/typescript/src/Shared/Services/DataUploadService.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Services/VideoSessionService.d.ts +33 -0
- package/lib/typescript/src/Shared/Services/VideoSessionService.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Services/WebRTCService.d.ts +58 -0
- package/lib/typescript/src/Shared/Services/WebRTCService.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Types/analytics.types.d.ts +2 -0
- package/lib/typescript/src/Shared/Types/analytics.types.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Types/identificationInfo.d.ts +4 -1
- package/lib/typescript/src/Shared/Types/identificationInfo.d.ts.map +1 -1
- package/lib/typescript/src/Translation/Resources/en.d.ts +20 -0
- package/lib/typescript/src/Translation/Resources/en.d.ts.map +1 -1
- package/lib/typescript/src/Translation/Resources/tr.d.ts +20 -0
- package/lib/typescript/src/Translation/Resources/tr.d.ts.map +1 -1
- package/lib/typescript/src/Trustchex.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +29 -2
- package/src/Screens/Debug/BarcodeTestScreen.tsx +317 -0
- package/src/Screens/Debug/MRZTestScreen.tsx +107 -13
- package/src/Screens/Dynamic/ContractAcceptanceScreen.tsx +59 -33
- package/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.tsx +6 -0
- package/src/Screens/Dynamic/IdentityDocumentScanningScreen.tsx +6 -0
- package/src/Screens/Dynamic/LivenessDetectionScreen.tsx +34 -6
- package/src/Screens/Dynamic/VideoCallScreen.tsx +764 -0
- package/src/Screens/Static/OTPVerificationScreen.tsx +6 -0
- package/src/Screens/Static/QrCodeScanningScreen.tsx +7 -1
- package/src/Screens/Static/ResultScreen.tsx +58 -23
- package/src/Screens/Static/VerificationSessionCheckScreen.tsx +58 -72
- package/src/Shared/Animations/video-call.json +1 -0
- package/src/Shared/Components/DebugNavigationPanel.tsx +185 -9
- package/src/Shared/Components/DebugOverlay.tsx +656 -0
- package/src/Shared/Components/EIDScanner.tsx +1 -5
- package/src/Shared/Components/IdentityDocumentCamera.constants.ts +44 -0
- package/src/Shared/Components/IdentityDocumentCamera.flows.ts +342 -0
- package/src/Shared/Components/IdentityDocumentCamera.tsx +1089 -2465
- package/src/Shared/Components/IdentityDocumentCamera.types.ts +136 -0
- package/src/Shared/Components/IdentityDocumentCamera.utils.ts +364 -0
- package/src/Shared/Components/NavigationManager.tsx +14 -1
- package/src/Shared/Contexts/AppContext.ts +2 -0
- package/src/Shared/Libs/SignalingClient.ts +189 -0
- package/src/Shared/Libs/analytics.utils.ts +4 -0
- package/src/Shared/Libs/deeplink.utils.ts +12 -1
- package/src/Shared/Libs/http-client.ts +10 -0
- package/src/Shared/Libs/promise.utils.ts +16 -2
- package/src/Shared/Libs/status-bar.utils.ts +19 -0
- package/src/Shared/Services/DataUploadService.ts +395 -0
- package/src/Shared/Services/VideoSessionService.ts +190 -0
- package/src/Shared/Services/WebRTCService.ts +636 -0
- package/src/Shared/Types/analytics.types.ts +2 -0
- package/src/Shared/Types/identificationInfo.ts +5 -1
- package/src/Translation/Resources/en.ts +25 -0
- package/src/Translation/Resources/tr.ts +27 -0
- package/src/Trustchex.tsx +12 -2
- package/src/version.ts +1 -1
|
@@ -7,22 +7,38 @@ import {
|
|
|
7
7
|
StatusBar,
|
|
8
8
|
TouchableOpacity,
|
|
9
9
|
type NativeSyntheticEvent,
|
|
10
|
+
type LayoutChangeEvent,
|
|
10
11
|
} from 'react-native';
|
|
11
12
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
12
13
|
import {
|
|
13
14
|
TrustchexCamera,
|
|
14
15
|
type TrustchexCameraHandle,
|
|
15
16
|
type Frame,
|
|
17
|
+
type NativeTextBlock,
|
|
16
18
|
} from '../../Shared/Components/TrustchexCamera';
|
|
17
19
|
import mrzUtils from '../../Shared/Libs/mrz.utils';
|
|
20
|
+
import { useKeepAwake } from '../../Shared/Libs/native-keep-awake.utils';
|
|
21
|
+
|
|
22
|
+
interface MrzOverlayBlock extends NativeTextBlock {
|
|
23
|
+
isMrz: boolean;
|
|
24
|
+
}
|
|
18
25
|
|
|
19
26
|
const MRZTestScreen = () => {
|
|
27
|
+
useKeepAwake();
|
|
20
28
|
const cameraRef = useRef<TrustchexCameraHandle>(null);
|
|
21
29
|
const [mrzText, setMrzText] = useState<string>('Waiting for MRZ...');
|
|
22
30
|
const [mrzRawText, setMrzRawText] = useState<string>('');
|
|
23
31
|
const [mrzValid, setMrzValid] = useState<boolean>(false);
|
|
24
32
|
const [rawHistory, setRawHistory] = useState<string[]>([]);
|
|
25
33
|
const [isPaused, setIsPaused] = useState<boolean>(false);
|
|
34
|
+
const [overlayBlocks, setOverlayBlocks] = useState<MrzOverlayBlock[]>([]);
|
|
35
|
+
const [cameraLayout, setCameraLayout] = useState({ width: 1, height: 1 });
|
|
36
|
+
const [frameSize, setFrameSize] = useState({ width: 1080, height: 1920 });
|
|
37
|
+
|
|
38
|
+
const handleCameraLayout = useCallback((e: LayoutChangeEvent) => {
|
|
39
|
+
const { width, height } = e.nativeEvent.layout;
|
|
40
|
+
setCameraLayout({ width, height });
|
|
41
|
+
}, []);
|
|
26
42
|
|
|
27
43
|
const handleFrame = useCallback(
|
|
28
44
|
(event: NativeSyntheticEvent<{ frame: Frame }>) => {
|
|
@@ -32,6 +48,28 @@ const MRZTestScreen = () => {
|
|
|
32
48
|
|
|
33
49
|
const frame = event.nativeEvent.frame;
|
|
34
50
|
|
|
51
|
+
if (frame.width && frame.height) {
|
|
52
|
+
setFrameSize({ width: frame.width, height: frame.height });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (frame.textBlocks && frame.textBlocks.length > 0) {
|
|
56
|
+
const frameHeight = frame.height;
|
|
57
|
+
const bottomThreshold = frameHeight * 0.5;
|
|
58
|
+
const blocks: MrzOverlayBlock[] = frame.textBlocks.map((block) => {
|
|
59
|
+
const blockText = block.text || '';
|
|
60
|
+
return {
|
|
61
|
+
...block,
|
|
62
|
+
isMrz:
|
|
63
|
+
blockText.includes('<') &&
|
|
64
|
+
blockText.length >= 12 &&
|
|
65
|
+
(block.blockFrame ? block.blockFrame.y > bottomThreshold : false),
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
setOverlayBlocks(blocks);
|
|
69
|
+
} else {
|
|
70
|
+
setOverlayBlocks([]);
|
|
71
|
+
}
|
|
72
|
+
|
|
35
73
|
if (frame.resultText) {
|
|
36
74
|
setRawHistory((prev) => {
|
|
37
75
|
if (prev[0] === frame.resultText) {
|
|
@@ -86,18 +124,47 @@ const MRZTestScreen = () => {
|
|
|
86
124
|
backgroundColor="transparent"
|
|
87
125
|
translucent
|
|
88
126
|
/>
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
127
|
+
<View style={styles.cameraWrapper} onLayout={handleCameraLayout}>
|
|
128
|
+
<TrustchexCamera
|
|
129
|
+
ref={cameraRef}
|
|
130
|
+
style={StyleSheet.absoluteFill}
|
|
131
|
+
cameraType="back"
|
|
132
|
+
enableFrameProcessing={true}
|
|
133
|
+
enableFaceDetection={false}
|
|
134
|
+
enableTextRecognition={true}
|
|
135
|
+
enableBarcodeScanning={false}
|
|
136
|
+
includeBase64={false}
|
|
137
|
+
targetFps={10}
|
|
138
|
+
onFrameAvailable={handleFrame}
|
|
139
|
+
/>
|
|
140
|
+
{overlayBlocks.map((block, i) => {
|
|
141
|
+
const bf = block.blockFrame;
|
|
142
|
+
if (!bf) return null;
|
|
143
|
+
const scaleX = cameraLayout.width / frameSize.width;
|
|
144
|
+
const scaleY = cameraLayout.height / frameSize.height;
|
|
145
|
+
return (
|
|
146
|
+
<View
|
|
147
|
+
key={i}
|
|
148
|
+
style={[
|
|
149
|
+
styles.boundingBox,
|
|
150
|
+
block.isMrz ? styles.boundingBoxMrz : styles.boundingBoxText,
|
|
151
|
+
{
|
|
152
|
+
left: bf.x * scaleX,
|
|
153
|
+
top: bf.y * scaleY,
|
|
154
|
+
width: bf.width * scaleX,
|
|
155
|
+
height: bf.height * scaleY,
|
|
156
|
+
},
|
|
157
|
+
]}
|
|
158
|
+
>
|
|
159
|
+
{block.isMrz && (
|
|
160
|
+
<View style={styles.blockLabel}>
|
|
161
|
+
<Text style={styles.blockLabelText}>MRZ</Text>
|
|
162
|
+
</View>
|
|
163
|
+
)}
|
|
164
|
+
</View>
|
|
165
|
+
);
|
|
166
|
+
})}
|
|
167
|
+
</View>
|
|
101
168
|
|
|
102
169
|
<SafeAreaView style={styles.mrzPanel} edges={['bottom']}>
|
|
103
170
|
<ScrollView style={styles.scrollView}>
|
|
@@ -152,8 +219,35 @@ const styles = StyleSheet.create({
|
|
|
152
219
|
flex: 1,
|
|
153
220
|
backgroundColor: '#000000',
|
|
154
221
|
},
|
|
155
|
-
|
|
222
|
+
cameraWrapper: {
|
|
156
223
|
flex: 2,
|
|
224
|
+
position: 'relative',
|
|
225
|
+
},
|
|
226
|
+
boundingBox: {
|
|
227
|
+
position: 'absolute',
|
|
228
|
+
borderWidth: 1.5,
|
|
229
|
+
},
|
|
230
|
+
boundingBoxText: {
|
|
231
|
+
borderColor: 'rgba(255, 255, 255, 0.25)',
|
|
232
|
+
},
|
|
233
|
+
boundingBoxMrz: {
|
|
234
|
+
borderColor: '#FFA500',
|
|
235
|
+
borderWidth: 2,
|
|
236
|
+
backgroundColor: 'rgba(255, 165, 0, 0.07)',
|
|
237
|
+
},
|
|
238
|
+
blockLabel: {
|
|
239
|
+
position: 'absolute',
|
|
240
|
+
top: -14,
|
|
241
|
+
left: 0,
|
|
242
|
+
backgroundColor: '#FFA500',
|
|
243
|
+
paddingHorizontal: 4,
|
|
244
|
+
paddingVertical: 1,
|
|
245
|
+
borderRadius: 2,
|
|
246
|
+
},
|
|
247
|
+
blockLabelText: {
|
|
248
|
+
color: '#000000',
|
|
249
|
+
fontSize: 8,
|
|
250
|
+
fontWeight: 'bold',
|
|
157
251
|
},
|
|
158
252
|
mrzPanel: {
|
|
159
253
|
flex: 1,
|
|
@@ -16,6 +16,7 @@ import { getI18n, useTranslation } from 'react-i18next';
|
|
|
16
16
|
import StyledButton from '../../Shared/Components/StyledButton';
|
|
17
17
|
import NativeDeviceInfo from '../../Shared/Libs/native-device-info.utils';
|
|
18
18
|
import { speakWithDebounce } from '../../Shared/Libs/tts.utils';
|
|
19
|
+
import { useStatusBarWhiteBackground } from '../../Shared/Libs/status-bar.utils';
|
|
19
20
|
import {
|
|
20
21
|
trackFunnelStep,
|
|
21
22
|
useScreenTracking,
|
|
@@ -24,8 +25,10 @@ import {
|
|
|
24
25
|
trackVerificationComplete,
|
|
25
26
|
trackError,
|
|
26
27
|
} from '../../Shared/Libs/analytics.utils';
|
|
28
|
+
import { useKeepAwake } from '../../Shared/Libs/native-keep-awake.utils';
|
|
27
29
|
|
|
28
30
|
const ContractAcceptanceScreen = () => {
|
|
31
|
+
useKeepAwake();
|
|
29
32
|
const [isEnabled, setIsEnabled] = useState(false);
|
|
30
33
|
const [isReady, setIsReady] = useState(false);
|
|
31
34
|
const appContext = useContext(AppContext);
|
|
@@ -39,6 +42,9 @@ const ContractAcceptanceScreen = () => {
|
|
|
39
42
|
// Track screen view and exit
|
|
40
43
|
useScreenTracking('contract_acceptance');
|
|
41
44
|
|
|
45
|
+
// Configure status bar for white background
|
|
46
|
+
useStatusBarWhiteBackground();
|
|
47
|
+
|
|
42
48
|
useEffect(() => {
|
|
43
49
|
const contracts = appContext.currentWorkflowStep?.data?.contracts;
|
|
44
50
|
if (!contracts) {
|
|
@@ -93,41 +99,58 @@ const ContractAcceptanceScreen = () => {
|
|
|
93
99
|
return await NativeDeviceInfo.generateHumanReadableIdentifier();
|
|
94
100
|
}, []);
|
|
95
101
|
|
|
102
|
+
// Early return if workflow step data is not available (after all hooks)
|
|
103
|
+
if (!appContext.currentWorkflowStep || !appContext.currentWorkflowStep.data) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
|
|
96
107
|
return (
|
|
97
108
|
<SafeAreaView style={styles.container}>
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
109
|
+
<View
|
|
110
|
+
style={[
|
|
111
|
+
styles.webViewContainer,
|
|
112
|
+
{
|
|
113
|
+
paddingHorizontal: Math.max(insets.left, insets.right),
|
|
114
|
+
paddingTop: insets.top,
|
|
115
|
+
},
|
|
116
|
+
]}
|
|
117
|
+
>
|
|
118
|
+
<WebView
|
|
119
|
+
source={{
|
|
120
|
+
uri: contractUrl || '',
|
|
121
|
+
}}
|
|
122
|
+
javaScriptEnabled={true}
|
|
123
|
+
domStorageEnabled={false}
|
|
124
|
+
scalesPageToFit={false}
|
|
125
|
+
scrollEnabled={true}
|
|
126
|
+
style={styles.webView}
|
|
127
|
+
onError={(syntheticEvent) => {
|
|
128
|
+
const { nativeEvent } = syntheticEvent;
|
|
129
|
+
trackError(
|
|
130
|
+
'CONTRACT_WEBVIEW_ERROR',
|
|
131
|
+
nativeEvent.description || 'Failed to load contract',
|
|
132
|
+
'contract_acceptance',
|
|
133
|
+
'medium',
|
|
134
|
+
{ recoverable: true, userAction: 'load_contract' }
|
|
135
|
+
);
|
|
136
|
+
}}
|
|
137
|
+
onLoadEnd={(event) => {
|
|
138
|
+
if (event.nativeEvent.url === contractUrl) {
|
|
139
|
+
setIsReady(true);
|
|
140
|
+
|
|
141
|
+
// Track contract acceptance started
|
|
142
|
+
trackVerificationStart('CONTRACT_ACCEPTANCE');
|
|
143
|
+
|
|
144
|
+
if (appContext.currentWorkflowStep?.data?.voiceGuidanceActive) {
|
|
145
|
+
speakWithDebounce(
|
|
146
|
+
t('termsOfUseAndDataPrivacyScreen.footerText')
|
|
147
|
+
);
|
|
148
|
+
}
|
|
126
149
|
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
150
|
+
}}
|
|
151
|
+
onScroll={hasReachedEnd}
|
|
152
|
+
/>
|
|
153
|
+
</View>
|
|
131
154
|
<View style={[styles.footer, { paddingBottom: insets.bottom }]}>
|
|
132
155
|
<Text style={styles.footerText}>
|
|
133
156
|
{t('termsOfUseAndDataPrivacyScreen.footerText')}
|
|
@@ -183,10 +206,13 @@ const styles = StyleSheet.create({
|
|
|
183
206
|
container: {
|
|
184
207
|
flex: 1,
|
|
185
208
|
},
|
|
209
|
+
webViewContainer: {
|
|
210
|
+
flex: 1,
|
|
211
|
+
width: '100%',
|
|
212
|
+
},
|
|
186
213
|
webView: {
|
|
187
214
|
flex: 1,
|
|
188
215
|
width: '100%',
|
|
189
|
-
height: '100%',
|
|
190
216
|
resizeMode: 'contain',
|
|
191
217
|
},
|
|
192
218
|
footer: {
|
|
@@ -17,8 +17,10 @@ import {
|
|
|
17
17
|
trackVerificationStart,
|
|
18
18
|
trackVerificationComplete,
|
|
19
19
|
} from '../../Shared/Libs/analytics.utils';
|
|
20
|
+
import { useKeepAwake } from '../../Shared/Libs/native-keep-awake.utils';
|
|
20
21
|
|
|
21
22
|
const IdentityDocumentEIDScanningScreen = () => {
|
|
23
|
+
useKeepAwake();
|
|
22
24
|
const appContext = useContext(AppContext);
|
|
23
25
|
const navigationManagerRef = React.useRef<NavigationManagerRef>(null);
|
|
24
26
|
const insets = useSafeAreaInsets();
|
|
@@ -77,6 +79,10 @@ const IdentityDocumentEIDScanningScreen = () => {
|
|
|
77
79
|
);
|
|
78
80
|
}, [appContext.currentWorkflowStep]);
|
|
79
81
|
|
|
82
|
+
if (!appContext.currentWorkflowStep) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
80
86
|
return (
|
|
81
87
|
<SafeAreaView style={styles.safeAreaContainer}>
|
|
82
88
|
{documentNumber && dateOfBirth && dateOfExpiry ? (
|
|
@@ -17,8 +17,10 @@ import {
|
|
|
17
17
|
trackVerificationStart,
|
|
18
18
|
trackVerificationComplete,
|
|
19
19
|
} from '../../Shared/Libs/analytics.utils';
|
|
20
|
+
import { useKeepAwake } from '../../Shared/Libs/native-keep-awake.utils';
|
|
20
21
|
|
|
21
22
|
const IdentityDocumentScanningScreen = () => {
|
|
23
|
+
useKeepAwake();
|
|
22
24
|
const [idFrontSideData, setIDFrontSideData] =
|
|
23
25
|
useState<DocumentScannedData | null>(null);
|
|
24
26
|
const [idBackSideData, setIDBackSideData] =
|
|
@@ -145,6 +147,10 @@ const IdentityDocumentScanningScreen = () => {
|
|
|
145
147
|
);
|
|
146
148
|
}, [appContext.currentWorkflowStep]);
|
|
147
149
|
|
|
150
|
+
if (!appContext.currentWorkflowStep) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
|
|
148
154
|
return (
|
|
149
155
|
<SafeAreaView style={styles.container}>
|
|
150
156
|
<IdentityDocumentCamera
|
|
@@ -8,7 +8,14 @@ import React, {
|
|
|
8
8
|
useCallback,
|
|
9
9
|
useRef,
|
|
10
10
|
} from 'react';
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
StyleSheet,
|
|
13
|
+
Text,
|
|
14
|
+
View,
|
|
15
|
+
Dimensions,
|
|
16
|
+
Vibration,
|
|
17
|
+
StatusBar,
|
|
18
|
+
} from 'react-native';
|
|
12
19
|
import {
|
|
13
20
|
useSafeAreaInsets,
|
|
14
21
|
SafeAreaView,
|
|
@@ -25,12 +32,14 @@ import { useTranslation } from 'react-i18next';
|
|
|
25
32
|
import StyledButton from '../../Shared/Components/StyledButton';
|
|
26
33
|
import LottieView from 'lottie-react-native';
|
|
27
34
|
import { speak, resetLastMessage } from '../../Shared/Libs/tts.utils';
|
|
35
|
+
import { useStatusBarWhiteBackground } from '../../Shared/Libs/status-bar.utils';
|
|
28
36
|
import {
|
|
29
37
|
trackFunnelStep,
|
|
30
38
|
useScreenTracking,
|
|
31
39
|
trackVerificationStart,
|
|
32
40
|
trackVerificationComplete,
|
|
33
41
|
} from '../../Shared/Libs/analytics.utils';
|
|
42
|
+
import { useKeepAwake } from '../../Shared/Libs/native-keep-awake.utils';
|
|
34
43
|
|
|
35
44
|
const { width: windowWidth, height: windowHeight } = Dimensions.get('window');
|
|
36
45
|
|
|
@@ -78,6 +87,7 @@ type PossibleActions = {
|
|
|
78
87
|
}[keyof Actions];
|
|
79
88
|
|
|
80
89
|
const LivenessDetectionScreen = () => {
|
|
90
|
+
useKeepAwake();
|
|
81
91
|
const [camera, setCamera] = useState<TrustchexCameraHandle | null>(null);
|
|
82
92
|
const navigation = useNavigation();
|
|
83
93
|
const appContext = useContext(AppContext);
|
|
@@ -90,6 +100,9 @@ const LivenessDetectionScreen = () => {
|
|
|
90
100
|
// Track screen view and exit
|
|
91
101
|
useScreenTracking('liveness_detection');
|
|
92
102
|
|
|
103
|
+
// Configure status bar for white background
|
|
104
|
+
useStatusBarWhiteBackground();
|
|
105
|
+
|
|
93
106
|
const [initialState, setInitialState] = useState<StateType>({
|
|
94
107
|
brightnessLow: false,
|
|
95
108
|
faceDetected: false,
|
|
@@ -142,7 +155,21 @@ const LivenessDetectionScreen = () => {
|
|
|
142
155
|
const [instructionList, setInstructionList] = useState<string[]>([]);
|
|
143
156
|
const [hasGuideShown, setHasGuideShown] = useState(false);
|
|
144
157
|
const stoppingRecordingRef = useRef(false); // Track if we're already stopping to prevent multiple calls
|
|
145
|
-
|
|
158
|
+
|
|
159
|
+
// Configure status bar for white background
|
|
160
|
+
useStatusBarWhiteBackground();
|
|
161
|
+
|
|
162
|
+
// Update status bar when guide visibility changes
|
|
163
|
+
useEffect(() => {
|
|
164
|
+
if (hasGuideShown) {
|
|
165
|
+
// Camera view - use light icons
|
|
166
|
+
StatusBar.setBarStyle('light-content', true);
|
|
167
|
+
} else {
|
|
168
|
+
// Guide screen with white background - use dark icons
|
|
169
|
+
StatusBar.setBarStyle('dark-content', true);
|
|
170
|
+
StatusBar.setBackgroundColor('#ffffff', true);
|
|
171
|
+
}
|
|
172
|
+
}, [hasGuideShown]);
|
|
146
173
|
|
|
147
174
|
useEffect(() => {
|
|
148
175
|
const il = Object.keys(instructions)
|
|
@@ -175,7 +202,6 @@ const LivenessDetectionScreen = () => {
|
|
|
175
202
|
processComplete: false,
|
|
176
203
|
videoPath: '',
|
|
177
204
|
});
|
|
178
|
-
lastVoiceGuidanceMessage.current = '';
|
|
179
205
|
resetLastMessage();
|
|
180
206
|
}, [
|
|
181
207
|
instructions,
|
|
@@ -350,7 +376,6 @@ const LivenessDetectionScreen = () => {
|
|
|
350
376
|
const nextInstruction = state.instructionList[nextInstructionIndex];
|
|
351
377
|
|
|
352
378
|
// Reset TTS state when moving to any new instruction to ensure it speaks
|
|
353
|
-
lastVoiceGuidanceMessage.current = '';
|
|
354
379
|
resetLastMessage();
|
|
355
380
|
|
|
356
381
|
// Calculate progress based on actual action steps (excluding START and FINISH)
|
|
@@ -404,8 +429,7 @@ const LivenessDetectionScreen = () => {
|
|
|
404
429
|
// Let the instruction advance first, then speak the next instruction
|
|
405
430
|
|
|
406
431
|
// Only speak if message changed and is not empty
|
|
407
|
-
if (text
|
|
408
|
-
lastVoiceGuidanceMessage.current = text;
|
|
432
|
+
if (text) {
|
|
409
433
|
// Bypass interval for liveness instructions to ensure all instructions are spoken
|
|
410
434
|
speak(text, true);
|
|
411
435
|
}
|
|
@@ -818,6 +842,10 @@ const LivenessDetectionScreen = () => {
|
|
|
818
842
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
819
843
|
}, []); // Empty array = only run on mount/unmount
|
|
820
844
|
|
|
845
|
+
if (!appContext.currentWorkflowStep || !appContext.currentWorkflowStep.data) {
|
|
846
|
+
return null;
|
|
847
|
+
}
|
|
848
|
+
|
|
821
849
|
return (
|
|
822
850
|
<>
|
|
823
851
|
{hasGuideShown ? (
|