@trustchex/react-native-sdk 1.381.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.
Files changed (111) hide show
  1. package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraView.kt +1 -12
  2. package/android/src/main/java/com/trustchex/reactnativesdk/mlkit/MLKitModule.kt +1 -1
  3. package/ios/Camera/TrustchexCameraView.swift +1 -12
  4. package/ios/MLKit/MLKitModule.swift +1 -1
  5. package/lib/module/Screens/Debug/BarcodeTestScreen.js +308 -0
  6. package/lib/module/Screens/Debug/MRZTestScreen.js +105 -13
  7. package/lib/module/Screens/Dynamic/ContractAcceptanceScreen.js +49 -29
  8. package/lib/module/Screens/Dynamic/IdentityDocumentEIDScanningScreen.js +5 -0
  9. package/lib/module/Screens/Dynamic/IdentityDocumentScanningScreen.js +5 -0
  10. package/lib/module/Screens/Dynamic/LivenessDetectionScreen.js +26 -6
  11. package/lib/module/Screens/Dynamic/VideoCallScreen.js +676 -0
  12. package/lib/module/Screens/Static/OTPVerificationScreen.js +6 -0
  13. package/lib/module/Screens/Static/QrCodeScanningScreen.js +7 -1
  14. package/lib/module/Screens/Static/ResultScreen.js +27 -13
  15. package/lib/module/Screens/Static/VerificationSessionCheckScreen.js +51 -51
  16. package/lib/module/Shared/Animations/video-call.json +1 -0
  17. package/lib/module/Shared/Components/DebugNavigationPanel.js +180 -14
  18. package/lib/module/Shared/Components/EIDScanner.js +1 -4
  19. package/lib/module/Shared/Components/IdentityDocumentCamera.js +29 -8
  20. package/lib/module/Shared/Components/NavigationManager.js +15 -3
  21. package/lib/module/Shared/Contexts/AppContext.js +1 -0
  22. package/lib/module/Shared/Libs/SignalingClient.js +128 -0
  23. package/lib/module/Shared/Libs/analytics.utils.js +4 -0
  24. package/lib/module/Shared/Libs/deeplink.utils.js +9 -1
  25. package/lib/module/Shared/Libs/http-client.js +9 -0
  26. package/lib/module/Shared/Libs/promise.utils.js +16 -2
  27. package/lib/module/Shared/Libs/status-bar.utils.js +21 -0
  28. package/lib/module/Shared/Services/DataUploadService.js +294 -0
  29. package/lib/module/Shared/Services/VideoSessionService.js +156 -0
  30. package/lib/module/Shared/Services/WebRTCService.js +510 -0
  31. package/lib/module/Shared/Types/analytics.types.js +2 -0
  32. package/lib/module/Translation/Resources/en.js +20 -0
  33. package/lib/module/Translation/Resources/tr.js +20 -0
  34. package/lib/module/Trustchex.js +10 -0
  35. package/lib/module/version.js +1 -1
  36. package/lib/typescript/src/Screens/Debug/BarcodeTestScreen.d.ts +3 -0
  37. package/lib/typescript/src/Screens/Debug/BarcodeTestScreen.d.ts.map +1 -0
  38. package/lib/typescript/src/Screens/Debug/MRZTestScreen.d.ts.map +1 -1
  39. package/lib/typescript/src/Screens/Dynamic/ContractAcceptanceScreen.d.ts.map +1 -1
  40. package/lib/typescript/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.d.ts.map +1 -1
  41. package/lib/typescript/src/Screens/Dynamic/IdentityDocumentScanningScreen.d.ts.map +1 -1
  42. package/lib/typescript/src/Screens/Dynamic/LivenessDetectionScreen.d.ts.map +1 -1
  43. package/lib/typescript/src/Screens/Dynamic/VideoCallScreen.d.ts +3 -0
  44. package/lib/typescript/src/Screens/Dynamic/VideoCallScreen.d.ts.map +1 -0
  45. package/lib/typescript/src/Screens/Static/OTPVerificationScreen.d.ts.map +1 -1
  46. package/lib/typescript/src/Screens/Static/QrCodeScanningScreen.d.ts.map +1 -1
  47. package/lib/typescript/src/Screens/Static/ResultScreen.d.ts.map +1 -1
  48. package/lib/typescript/src/Screens/Static/VerificationSessionCheckScreen.d.ts.map +1 -1
  49. package/lib/typescript/src/Shared/Components/DebugNavigationPanel.d.ts.map +1 -1
  50. package/lib/typescript/src/Shared/Components/EIDScanner.d.ts.map +1 -1
  51. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
  52. package/lib/typescript/src/Shared/Components/NavigationManager.d.ts.map +1 -1
  53. package/lib/typescript/src/Shared/Contexts/AppContext.d.ts +1 -0
  54. package/lib/typescript/src/Shared/Contexts/AppContext.d.ts.map +1 -1
  55. package/lib/typescript/src/Shared/Libs/SignalingClient.d.ts +24 -0
  56. package/lib/typescript/src/Shared/Libs/SignalingClient.d.ts.map +1 -0
  57. package/lib/typescript/src/Shared/Libs/analytics.utils.d.ts.map +1 -1
  58. package/lib/typescript/src/Shared/Libs/deeplink.utils.d.ts.map +1 -1
  59. package/lib/typescript/src/Shared/Libs/http-client.d.ts.map +1 -1
  60. package/lib/typescript/src/Shared/Libs/promise.utils.d.ts.map +1 -1
  61. package/lib/typescript/src/Shared/Libs/status-bar.utils.d.ts +9 -0
  62. package/lib/typescript/src/Shared/Libs/status-bar.utils.d.ts.map +1 -0
  63. package/lib/typescript/src/Shared/Services/DataUploadService.d.ts +25 -0
  64. package/lib/typescript/src/Shared/Services/DataUploadService.d.ts.map +1 -0
  65. package/lib/typescript/src/Shared/Services/VideoSessionService.d.ts +33 -0
  66. package/lib/typescript/src/Shared/Services/VideoSessionService.d.ts.map +1 -0
  67. package/lib/typescript/src/Shared/Services/WebRTCService.d.ts +58 -0
  68. package/lib/typescript/src/Shared/Services/WebRTCService.d.ts.map +1 -0
  69. package/lib/typescript/src/Shared/Types/analytics.types.d.ts +2 -0
  70. package/lib/typescript/src/Shared/Types/analytics.types.d.ts.map +1 -1
  71. package/lib/typescript/src/Shared/Types/identificationInfo.d.ts +4 -1
  72. package/lib/typescript/src/Shared/Types/identificationInfo.d.ts.map +1 -1
  73. package/lib/typescript/src/Translation/Resources/en.d.ts +20 -0
  74. package/lib/typescript/src/Translation/Resources/en.d.ts.map +1 -1
  75. package/lib/typescript/src/Translation/Resources/tr.d.ts +20 -0
  76. package/lib/typescript/src/Translation/Resources/tr.d.ts.map +1 -1
  77. package/lib/typescript/src/Trustchex.d.ts.map +1 -1
  78. package/lib/typescript/src/version.d.ts +1 -1
  79. package/package.json +29 -2
  80. package/src/Screens/Debug/BarcodeTestScreen.tsx +317 -0
  81. package/src/Screens/Debug/MRZTestScreen.tsx +107 -13
  82. package/src/Screens/Dynamic/ContractAcceptanceScreen.tsx +59 -33
  83. package/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.tsx +6 -0
  84. package/src/Screens/Dynamic/IdentityDocumentScanningScreen.tsx +6 -0
  85. package/src/Screens/Dynamic/LivenessDetectionScreen.tsx +34 -6
  86. package/src/Screens/Dynamic/VideoCallScreen.tsx +764 -0
  87. package/src/Screens/Static/OTPVerificationScreen.tsx +6 -0
  88. package/src/Screens/Static/QrCodeScanningScreen.tsx +7 -1
  89. package/src/Screens/Static/ResultScreen.tsx +58 -23
  90. package/src/Screens/Static/VerificationSessionCheckScreen.tsx +58 -72
  91. package/src/Shared/Animations/video-call.json +1 -0
  92. package/src/Shared/Components/DebugNavigationPanel.tsx +185 -9
  93. package/src/Shared/Components/EIDScanner.tsx +1 -5
  94. package/src/Shared/Components/IdentityDocumentCamera.tsx +29 -8
  95. package/src/Shared/Components/NavigationManager.tsx +14 -1
  96. package/src/Shared/Contexts/AppContext.ts +2 -0
  97. package/src/Shared/Libs/SignalingClient.ts +189 -0
  98. package/src/Shared/Libs/analytics.utils.ts +4 -0
  99. package/src/Shared/Libs/deeplink.utils.ts +12 -1
  100. package/src/Shared/Libs/http-client.ts +10 -0
  101. package/src/Shared/Libs/promise.utils.ts +16 -2
  102. package/src/Shared/Libs/status-bar.utils.ts +19 -0
  103. package/src/Shared/Services/DataUploadService.ts +395 -0
  104. package/src/Shared/Services/VideoSessionService.ts +190 -0
  105. package/src/Shared/Services/WebRTCService.ts +636 -0
  106. package/src/Shared/Types/analytics.types.ts +2 -0
  107. package/src/Shared/Types/identificationInfo.ts +5 -1
  108. package/src/Translation/Resources/en.ts +25 -0
  109. package/src/Translation/Resources/tr.ts +27 -0
  110. package/src/Trustchex.tsx +12 -2
  111. package/src/version.ts +1 -1
@@ -99,19 +99,8 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
99
99
  BarcodeScanning.getClient(
100
100
  BarcodeScannerOptions.Builder()
101
101
  .setBarcodeFormats(
102
- Barcode.FORMAT_PDF417,
103
- Barcode.FORMAT_QR_CODE,
104
- Barcode.FORMAT_CODABAR,
105
102
  Barcode.FORMAT_CODE_128,
106
- Barcode.FORMAT_CODE_39,
107
- Barcode.FORMAT_CODE_93,
108
- Barcode.FORMAT_EAN_13,
109
- Barcode.FORMAT_EAN_8,
110
- Barcode.FORMAT_ITF,
111
- Barcode.FORMAT_UPC_A,
112
- Barcode.FORMAT_UPC_E,
113
- Barcode.FORMAT_AZTEC,
114
- Barcode.FORMAT_DATA_MATRIX
103
+ Barcode.FORMAT_QR_CODE
115
104
  )
116
105
  .build()
117
106
  )
@@ -30,7 +30,7 @@ class MLKitModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaM
30
30
  )
31
31
  private val barcodeScanner = BarcodeScanning.getClient(
32
32
  BarcodeScannerOptions.Builder()
33
- .setBarcodeFormats(Barcode.FORMAT_PDF417, Barcode.FORMAT_QR_CODE)
33
+ .setBarcodeFormats(Barcode.FORMAT_CODE_128, Barcode.FORMAT_QR_CODE)
34
34
  .build()
35
35
  )
36
36
 
@@ -196,19 +196,8 @@ class TrustchexCameraView: UIView {
196
196
  let supportedTypes = metadataOutput.availableMetadataObjectTypes
197
197
  var typesToEnable: [AVMetadataObject.ObjectType] = []
198
198
 
199
- if supportedTypes.contains(.pdf417) { typesToEnable.append(.pdf417) }
200
- if supportedTypes.contains(.qr) { typesToEnable.append(.qr) }
201
199
  if supportedTypes.contains(.code128) { typesToEnable.append(.code128) }
202
- if supportedTypes.contains(.code39) { typesToEnable.append(.code39) }
203
- if supportedTypes.contains(.code39Mod43) { typesToEnable.append(.code39Mod43) }
204
- if supportedTypes.contains(.code93) { typesToEnable.append(.code93) }
205
- if supportedTypes.contains(.ean13) { typesToEnable.append(.ean13) }
206
- if supportedTypes.contains(.ean8) { typesToEnable.append(.ean8) }
207
- if supportedTypes.contains(.upce) { typesToEnable.append(.upce) }
208
- if supportedTypes.contains(.interleaved2of5) { typesToEnable.append(.interleaved2of5) }
209
- if supportedTypes.contains(.itf14) { typesToEnable.append(.itf14) }
210
- if supportedTypes.contains(.aztec) { typesToEnable.append(.aztec) }
211
- if supportedTypes.contains(.dataMatrix) { typesToEnable.append(.dataMatrix) }
200
+ if supportedTypes.contains(.qr) { typesToEnable.append(.qr) }
212
201
 
213
202
  metadataOutput.metadataObjectTypes = typesToEnable
214
203
  }
@@ -19,7 +19,7 @@ class MLKitModule: NSObject {
19
19
  return FaceDetector.faceDetector(options: options)
20
20
  }()
21
21
  private lazy var barcodeScanner: BarcodeScanner = {
22
- let formats: BarcodeFormat = [.PDF417, .qrCode]
22
+ let formats: BarcodeFormat = [.code128, .qrCode]
23
23
  let options = BarcodeScannerOptions(formats: formats)
24
24
  return BarcodeScanner.barcodeScanner(options: options)
25
25
  }()
@@ -0,0 +1,308 @@
1
+ "use strict";
2
+
3
+ import React, { useState, useRef, useCallback } from 'react';
4
+ import { View, StyleSheet, Text, ScrollView, StatusBar, TouchableOpacity } from 'react-native';
5
+ import { SafeAreaView } from 'react-native-safe-area-context';
6
+ import { TrustchexCamera } from "../../Shared/Components/TrustchexCamera.js";
7
+ import { useKeepAwake } from "../../Shared/Libs/native-keep-awake.utils.js";
8
+
9
+ // ML Kit barcode format constants
10
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
+ const BARCODE_FORMAT_NAMES = {
12
+ 1: 'Code 128',
13
+ 2: 'Code 39',
14
+ 4: 'Code 93',
15
+ 8: 'Codabar',
16
+ 16: 'Data Matrix',
17
+ 32: 'EAN-13',
18
+ 64: 'EAN-8',
19
+ 128: 'ITF',
20
+ 256: 'QR Code',
21
+ 512: 'UPC-A',
22
+ 1024: 'UPC-E',
23
+ 2048: 'PDF417',
24
+ 4096: 'Aztec'
25
+ };
26
+ function formatName(format) {
27
+ return BARCODE_FORMAT_NAMES[format] ?? `Format(${format})`;
28
+ }
29
+ const BarcodeTestScreen = () => {
30
+ useKeepAwake();
31
+ const cameraRef = useRef(null);
32
+ const [barcodes, setBarcodes] = useState([]);
33
+ const [history, setHistory] = useState([]);
34
+ const [isPaused, setIsPaused] = useState(false);
35
+ const [cameraLayout, setCameraLayout] = useState({
36
+ width: 1,
37
+ height: 1
38
+ });
39
+ const [frameSize, setFrameSize] = useState({
40
+ width: 1080,
41
+ height: 1920
42
+ });
43
+ const handleCameraLayout = useCallback(e => {
44
+ const {
45
+ width,
46
+ height
47
+ } = e.nativeEvent.layout;
48
+ setCameraLayout({
49
+ width,
50
+ height
51
+ });
52
+ }, []);
53
+ const handleFrame = useCallback(event => {
54
+ if (isPaused) return;
55
+ const frame = event.nativeEvent.frame;
56
+ if (frame.width && frame.height) {
57
+ setFrameSize({
58
+ width: frame.width,
59
+ height: frame.height
60
+ });
61
+ }
62
+ if (frame.barcodes && frame.barcodes.length > 0) {
63
+ setBarcodes(frame.barcodes);
64
+ setHistory(prev => {
65
+ const incoming = frame.barcodes;
66
+ const next = [...prev];
67
+ for (const b of incoming) {
68
+ const alreadyRecent = next.slice(0, 5).some(h => h.rawValue === b.rawValue);
69
+ if (!alreadyRecent) {
70
+ next.unshift({
71
+ rawValue: b.rawValue,
72
+ displayValue: b.displayValue,
73
+ format: b.format,
74
+ timestamp: Date.now()
75
+ });
76
+ }
77
+ }
78
+ return next.slice(0, 30);
79
+ });
80
+ } else {
81
+ setBarcodes([]);
82
+ }
83
+ }, [isPaused]);
84
+ return /*#__PURE__*/_jsxs(View, {
85
+ style: styles.container,
86
+ children: [/*#__PURE__*/_jsx(StatusBar, {
87
+ barStyle: "light-content",
88
+ backgroundColor: "transparent",
89
+ translucent: true
90
+ }), /*#__PURE__*/_jsxs(View, {
91
+ style: styles.cameraWrapper,
92
+ onLayout: handleCameraLayout,
93
+ children: [/*#__PURE__*/_jsx(TrustchexCamera, {
94
+ ref: cameraRef,
95
+ style: StyleSheet.absoluteFill,
96
+ cameraType: "back",
97
+ enableFrameProcessing: true,
98
+ enableFaceDetection: false,
99
+ enableTextRecognition: false,
100
+ enableBarcodeScanning: true,
101
+ includeBase64: false,
102
+ targetFps: 15,
103
+ onFrameAvailable: handleFrame
104
+ }), barcodes.map((b, i) => {
105
+ const bb = b.boundingBox;
106
+ if (!bb) return null;
107
+ const scaleX = cameraLayout.width / frameSize.width;
108
+ const scaleY = cameraLayout.height / frameSize.height;
109
+ const left = bb.left * scaleX;
110
+ const top = bb.top * scaleY;
111
+ const width = (bb.right - bb.left) * scaleX;
112
+ const height = (bb.bottom - bb.top) * scaleY;
113
+ return /*#__PURE__*/_jsx(View, {
114
+ style: [styles.barcodeBoundingBox, {
115
+ left,
116
+ top,
117
+ width,
118
+ height
119
+ }],
120
+ children: /*#__PURE__*/_jsx(View, {
121
+ style: styles.barcodeBoxLabel,
122
+ children: /*#__PURE__*/_jsx(Text, {
123
+ style: styles.barcodeBoxLabelText,
124
+ children: formatName(b.format)
125
+ })
126
+ })
127
+ }, i);
128
+ })]
129
+ }), /*#__PURE__*/_jsx(SafeAreaView, {
130
+ style: styles.panel,
131
+ edges: ['bottom'],
132
+ children: /*#__PURE__*/_jsx(ScrollView, {
133
+ style: styles.scrollView,
134
+ children: /*#__PURE__*/_jsxs(View, {
135
+ style: styles.panelContent,
136
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
137
+ style: styles.pauseButton,
138
+ onPress: () => setIsPaused(!isPaused),
139
+ children: /*#__PURE__*/_jsx(Text, {
140
+ style: styles.pauseButtonText,
141
+ children: isPaused ? 'Resume Processing' : 'Pause Processing'
142
+ })
143
+ }), /*#__PURE__*/_jsx(Text, {
144
+ style: styles.title,
145
+ children: "Barcode Scanner"
146
+ }), /*#__PURE__*/_jsx(Text, {
147
+ style: styles.sectionTitle,
148
+ children: "Live Detections"
149
+ }), barcodes.length === 0 ? /*#__PURE__*/_jsx(Text, {
150
+ style: styles.bodyText,
151
+ children: "No barcode in frame"
152
+ }) : barcodes.map((b, i) => /*#__PURE__*/_jsxs(View, {
153
+ style: styles.barcodeRow,
154
+ children: [/*#__PURE__*/_jsx(View, {
155
+ style: styles.formatBadge,
156
+ children: /*#__PURE__*/_jsx(Text, {
157
+ style: styles.formatBadgeText,
158
+ children: formatName(b.format)
159
+ })
160
+ }), /*#__PURE__*/_jsx(Text, {
161
+ style: styles.barcodeValue,
162
+ children: b.rawValue
163
+ })]
164
+ }, i)), /*#__PURE__*/_jsxs(Text, {
165
+ style: styles.sectionTitle,
166
+ children: ["History (", history.length, ")"]
167
+ }), history.length === 0 ? /*#__PURE__*/_jsx(Text, {
168
+ style: styles.bodyText,
169
+ children: "No barcodes detected yet"
170
+ }) : history.map((entry, i) => /*#__PURE__*/_jsxs(View, {
171
+ style: styles.historyRow,
172
+ children: [/*#__PURE__*/_jsxs(View, {
173
+ style: styles.historyMeta,
174
+ children: [/*#__PURE__*/_jsx(View, {
175
+ style: styles.formatBadge,
176
+ children: /*#__PURE__*/_jsx(Text, {
177
+ style: styles.formatBadgeText,
178
+ children: formatName(entry.format)
179
+ })
180
+ }), /*#__PURE__*/_jsx(Text, {
181
+ style: styles.historyTime,
182
+ children: new Date(entry.timestamp).toLocaleTimeString()
183
+ })]
184
+ }), /*#__PURE__*/_jsx(Text, {
185
+ style: styles.barcodeValue,
186
+ children: entry.rawValue
187
+ })]
188
+ }, i))]
189
+ })
190
+ })
191
+ })]
192
+ });
193
+ };
194
+ const styles = StyleSheet.create({
195
+ container: {
196
+ flex: 1,
197
+ backgroundColor: '#000000'
198
+ },
199
+ cameraWrapper: {
200
+ flex: 2,
201
+ position: 'relative'
202
+ },
203
+ barcodeBoundingBox: {
204
+ position: 'absolute',
205
+ borderWidth: 2,
206
+ borderColor: '#00C853',
207
+ backgroundColor: 'rgba(0, 200, 83, 0.07)'
208
+ },
209
+ barcodeBoxLabel: {
210
+ position: 'absolute',
211
+ top: -14,
212
+ left: 0,
213
+ backgroundColor: '#00C853',
214
+ paddingHorizontal: 4,
215
+ paddingVertical: 1,
216
+ borderRadius: 2
217
+ },
218
+ barcodeBoxLabelText: {
219
+ color: '#000000',
220
+ fontSize: 8,
221
+ fontWeight: 'bold'
222
+ },
223
+ panel: {
224
+ flex: 1,
225
+ backgroundColor: 'rgba(0, 0, 0, 0.95)',
226
+ borderTopWidth: 2,
227
+ borderTopColor: '#00C853'
228
+ },
229
+ scrollView: {
230
+ flex: 1
231
+ },
232
+ panelContent: {
233
+ padding: 10
234
+ },
235
+ pauseButton: {
236
+ alignSelf: 'center',
237
+ borderWidth: 1,
238
+ borderColor: '#00C853',
239
+ borderRadius: 4,
240
+ paddingVertical: 6,
241
+ paddingHorizontal: 12,
242
+ marginBottom: 8
243
+ },
244
+ pauseButtonText: {
245
+ color: '#00C853',
246
+ fontSize: 10,
247
+ fontWeight: 'bold'
248
+ },
249
+ title: {
250
+ color: '#00C853',
251
+ fontSize: 12,
252
+ fontWeight: 'bold',
253
+ marginBottom: 8,
254
+ textAlign: 'center'
255
+ },
256
+ sectionTitle: {
257
+ color: '#00C853',
258
+ fontSize: 10,
259
+ fontWeight: 'bold',
260
+ marginTop: 6,
261
+ marginBottom: 4
262
+ },
263
+ bodyText: {
264
+ color: '#888888',
265
+ fontSize: 9,
266
+ fontFamily: 'monospace'
267
+ },
268
+ barcodeRow: {
269
+ marginBottom: 6
270
+ },
271
+ historyRow: {
272
+ marginBottom: 8,
273
+ borderBottomWidth: 1,
274
+ borderBottomColor: '#333333',
275
+ paddingBottom: 6
276
+ },
277
+ historyMeta: {
278
+ flexDirection: 'row',
279
+ alignItems: 'center',
280
+ marginBottom: 2,
281
+ gap: 6
282
+ },
283
+ formatBadge: {
284
+ backgroundColor: '#00C853',
285
+ borderRadius: 3,
286
+ paddingHorizontal: 5,
287
+ paddingVertical: 2,
288
+ alignSelf: 'flex-start',
289
+ marginBottom: 2
290
+ },
291
+ formatBadgeText: {
292
+ color: '#000000',
293
+ fontSize: 8,
294
+ fontWeight: 'bold'
295
+ },
296
+ barcodeValue: {
297
+ color: '#FFFFFF',
298
+ fontSize: 9,
299
+ fontFamily: 'monospace',
300
+ lineHeight: 14
301
+ },
302
+ historyTime: {
303
+ color: '#888888',
304
+ fontSize: 8,
305
+ fontFamily: 'monospace'
306
+ }
307
+ });
308
+ export default BarcodeTestScreen;
@@ -5,19 +5,60 @@ import { View, StyleSheet, Text, ScrollView, StatusBar, TouchableOpacity } from
5
5
  import { SafeAreaView } from 'react-native-safe-area-context';
6
6
  import { TrustchexCamera } from "../../Shared/Components/TrustchexCamera.js";
7
7
  import mrzUtils from "../../Shared/Libs/mrz.utils.js";
8
+ import { useKeepAwake } from "../../Shared/Libs/native-keep-awake.utils.js";
8
9
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
10
  const MRZTestScreen = () => {
11
+ useKeepAwake();
10
12
  const cameraRef = useRef(null);
11
13
  const [mrzText, setMrzText] = useState('Waiting for MRZ...');
12
14
  const [mrzRawText, setMrzRawText] = useState('');
13
15
  const [mrzValid, setMrzValid] = useState(false);
14
16
  const [rawHistory, setRawHistory] = useState([]);
15
17
  const [isPaused, setIsPaused] = useState(false);
18
+ const [overlayBlocks, setOverlayBlocks] = useState([]);
19
+ const [cameraLayout, setCameraLayout] = useState({
20
+ width: 1,
21
+ height: 1
22
+ });
23
+ const [frameSize, setFrameSize] = useState({
24
+ width: 1080,
25
+ height: 1920
26
+ });
27
+ const handleCameraLayout = useCallback(e => {
28
+ const {
29
+ width,
30
+ height
31
+ } = e.nativeEvent.layout;
32
+ setCameraLayout({
33
+ width,
34
+ height
35
+ });
36
+ }, []);
16
37
  const handleFrame = useCallback(event => {
17
38
  if (isPaused) {
18
39
  return;
19
40
  }
20
41
  const frame = event.nativeEvent.frame;
42
+ if (frame.width && frame.height) {
43
+ setFrameSize({
44
+ width: frame.width,
45
+ height: frame.height
46
+ });
47
+ }
48
+ if (frame.textBlocks && frame.textBlocks.length > 0) {
49
+ const frameHeight = frame.height;
50
+ const bottomThreshold = frameHeight * 0.5;
51
+ const blocks = frame.textBlocks.map(block => {
52
+ const blockText = block.text || '';
53
+ return {
54
+ ...block,
55
+ isMrz: blockText.includes('<') && blockText.length >= 12 && (block.blockFrame ? block.blockFrame.y > bottomThreshold : false)
56
+ };
57
+ });
58
+ setOverlayBlocks(blocks);
59
+ } else {
60
+ setOverlayBlocks([]);
61
+ }
21
62
  if (frame.resultText) {
22
63
  setRawHistory(prev => {
23
64
  if (prev[0] === frame.resultText) {
@@ -62,17 +103,41 @@ const MRZTestScreen = () => {
62
103
  barStyle: "light-content",
63
104
  backgroundColor: "transparent",
64
105
  translucent: true
65
- }), /*#__PURE__*/_jsx(TrustchexCamera, {
66
- ref: cameraRef,
67
- style: styles.camera,
68
- cameraType: "back",
69
- enableFrameProcessing: true,
70
- enableFaceDetection: false,
71
- enableTextRecognition: true,
72
- enableBarcodeScanning: false,
73
- includeBase64: false,
74
- targetFps: 10,
75
- onFrameAvailable: handleFrame
106
+ }), /*#__PURE__*/_jsxs(View, {
107
+ style: styles.cameraWrapper,
108
+ onLayout: handleCameraLayout,
109
+ children: [/*#__PURE__*/_jsx(TrustchexCamera, {
110
+ ref: cameraRef,
111
+ style: StyleSheet.absoluteFill,
112
+ cameraType: "back",
113
+ enableFrameProcessing: true,
114
+ enableFaceDetection: false,
115
+ enableTextRecognition: true,
116
+ enableBarcodeScanning: false,
117
+ includeBase64: false,
118
+ targetFps: 10,
119
+ onFrameAvailable: handleFrame
120
+ }), overlayBlocks.map((block, i) => {
121
+ const bf = block.blockFrame;
122
+ if (!bf) return null;
123
+ const scaleX = cameraLayout.width / frameSize.width;
124
+ const scaleY = cameraLayout.height / frameSize.height;
125
+ return /*#__PURE__*/_jsx(View, {
126
+ style: [styles.boundingBox, block.isMrz ? styles.boundingBoxMrz : styles.boundingBoxText, {
127
+ left: bf.x * scaleX,
128
+ top: bf.y * scaleY,
129
+ width: bf.width * scaleX,
130
+ height: bf.height * scaleY
131
+ }],
132
+ children: block.isMrz && /*#__PURE__*/_jsx(View, {
133
+ style: styles.blockLabel,
134
+ children: /*#__PURE__*/_jsx(Text, {
135
+ style: styles.blockLabelText,
136
+ children: "MRZ"
137
+ })
138
+ })
139
+ }, i);
140
+ })]
76
141
  }), /*#__PURE__*/_jsx(SafeAreaView, {
77
142
  style: styles.mrzPanel,
78
143
  edges: ['bottom'],
@@ -119,8 +184,35 @@ const styles = StyleSheet.create({
119
184
  flex: 1,
120
185
  backgroundColor: '#000000'
121
186
  },
122
- camera: {
123
- flex: 2
187
+ cameraWrapper: {
188
+ flex: 2,
189
+ position: 'relative'
190
+ },
191
+ boundingBox: {
192
+ position: 'absolute',
193
+ borderWidth: 1.5
194
+ },
195
+ boundingBoxText: {
196
+ borderColor: 'rgba(255, 255, 255, 0.25)'
197
+ },
198
+ boundingBoxMrz: {
199
+ borderColor: '#FFA500',
200
+ borderWidth: 2,
201
+ backgroundColor: 'rgba(255, 165, 0, 0.07)'
202
+ },
203
+ blockLabel: {
204
+ position: 'absolute',
205
+ top: -14,
206
+ left: 0,
207
+ backgroundColor: '#FFA500',
208
+ paddingHorizontal: 4,
209
+ paddingVertical: 1,
210
+ borderRadius: 2
211
+ },
212
+ blockLabelText: {
213
+ color: '#000000',
214
+ fontSize: 8,
215
+ fontWeight: 'bold'
124
216
  },
125
217
  mrzPanel: {
126
218
  flex: 1,
@@ -10,9 +10,12 @@ import { getI18n, useTranslation } from 'react-i18next';
10
10
  import StyledButton from "../../Shared/Components/StyledButton.js";
11
11
  import NativeDeviceInfo from "../../Shared/Libs/native-device-info.utils.js";
12
12
  import { speakWithDebounce } from "../../Shared/Libs/tts.utils.js";
13
+ import { useStatusBarWhiteBackground } from "../../Shared/Libs/status-bar.utils.js";
13
14
  import { trackFunnelStep, useScreenTracking, trackConsentGiven, trackVerificationStart, trackVerificationComplete, trackError } from "../../Shared/Libs/analytics.utils.js";
15
+ import { useKeepAwake } from "../../Shared/Libs/native-keep-awake.utils.js";
14
16
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
17
  const ContractAcceptanceScreen = () => {
18
+ useKeepAwake();
16
19
  const [isEnabled, setIsEnabled] = useState(false);
17
20
  const [isReady, setIsReady] = useState(false);
18
21
  const appContext = useContext(AppContext);
@@ -27,6 +30,9 @@ const ContractAcceptanceScreen = () => {
27
30
 
28
31
  // Track screen view and exit
29
32
  useScreenTracking('contract_acceptance');
33
+
34
+ // Configure status bar for white background
35
+ useStatusBarWhiteBackground();
30
36
  useEffect(() => {
31
37
  const contracts = appContext.currentWorkflowStep?.data?.contracts;
32
38
  if (!contracts) {
@@ -65,38 +71,49 @@ const ContractAcceptanceScreen = () => {
65
71
  const generateHumanReadableIdentifier = useCallback(async () => {
66
72
  return await NativeDeviceInfo.generateHumanReadableIdentifier();
67
73
  }, []);
74
+
75
+ // Early return if workflow step data is not available (after all hooks)
76
+ if (!appContext.currentWorkflowStep || !appContext.currentWorkflowStep.data) {
77
+ return null;
78
+ }
68
79
  return /*#__PURE__*/_jsxs(SafeAreaView, {
69
80
  style: styles.container,
70
- children: [/*#__PURE__*/_jsx(WebView, {
71
- source: {
72
- uri: contractUrl || ''
73
- },
74
- javaScriptEnabled: true,
75
- domStorageEnabled: false,
76
- scalesPageToFit: false,
77
- scrollEnabled: true,
78
- style: styles.webView,
79
- onError: syntheticEvent => {
80
- const {
81
- nativeEvent
82
- } = syntheticEvent;
83
- trackError('CONTRACT_WEBVIEW_ERROR', nativeEvent.description || 'Failed to load contract', 'contract_acceptance', 'medium', {
84
- recoverable: true,
85
- userAction: 'load_contract'
86
- });
87
- },
88
- onLoadEnd: event => {
89
- if (event.nativeEvent.url === contractUrl) {
90
- setIsReady(true);
81
+ children: [/*#__PURE__*/_jsx(View, {
82
+ style: [styles.webViewContainer, {
83
+ paddingHorizontal: Math.max(insets.left, insets.right),
84
+ paddingTop: insets.top
85
+ }],
86
+ children: /*#__PURE__*/_jsx(WebView, {
87
+ source: {
88
+ uri: contractUrl || ''
89
+ },
90
+ javaScriptEnabled: true,
91
+ domStorageEnabled: false,
92
+ scalesPageToFit: false,
93
+ scrollEnabled: true,
94
+ style: styles.webView,
95
+ onError: syntheticEvent => {
96
+ const {
97
+ nativeEvent
98
+ } = syntheticEvent;
99
+ trackError('CONTRACT_WEBVIEW_ERROR', nativeEvent.description || 'Failed to load contract', 'contract_acceptance', 'medium', {
100
+ recoverable: true,
101
+ userAction: 'load_contract'
102
+ });
103
+ },
104
+ onLoadEnd: event => {
105
+ if (event.nativeEvent.url === contractUrl) {
106
+ setIsReady(true);
91
107
 
92
- // Track contract acceptance started
93
- trackVerificationStart('CONTRACT_ACCEPTANCE');
94
- if (appContext.currentWorkflowStep?.data?.voiceGuidanceActive) {
95
- speakWithDebounce(t('termsOfUseAndDataPrivacyScreen.footerText'));
108
+ // Track contract acceptance started
109
+ trackVerificationStart('CONTRACT_ACCEPTANCE');
110
+ if (appContext.currentWorkflowStep?.data?.voiceGuidanceActive) {
111
+ speakWithDebounce(t('termsOfUseAndDataPrivacyScreen.footerText'));
112
+ }
96
113
  }
97
- }
98
- },
99
- onScroll: hasReachedEnd
114
+ },
115
+ onScroll: hasReachedEnd
116
+ })
100
117
  }), /*#__PURE__*/_jsxs(View, {
101
118
  style: [styles.footer, {
102
119
  paddingBottom: insets.bottom
@@ -153,10 +170,13 @@ const styles = StyleSheet.create({
153
170
  container: {
154
171
  flex: 1
155
172
  },
173
+ webViewContainer: {
174
+ flex: 1,
175
+ width: '100%'
176
+ },
156
177
  webView: {
157
178
  flex: 1,
158
179
  width: '100%',
159
- height: '100%',
160
180
  resizeMode: 'contain'
161
181
  },
162
182
  footer: {
@@ -9,8 +9,10 @@ import AppContext from "../../Shared/Contexts/AppContext.js";
9
9
  import IdentityDocumentCamera from "../../Shared/Components/IdentityDocumentCamera.js";
10
10
  import { useTranslation } from 'react-i18next';
11
11
  import { trackFunnelStep, useScreenTracking, trackVerificationStart, trackVerificationComplete } from "../../Shared/Libs/analytics.utils.js";
12
+ import { useKeepAwake } from "../../Shared/Libs/native-keep-awake.utils.js";
12
13
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
14
  const IdentityDocumentEIDScanningScreen = () => {
15
+ useKeepAwake();
14
16
  const appContext = useContext(AppContext);
15
17
  const navigationManagerRef = React.useRef(null);
16
18
  const insets = useSafeAreaInsets();
@@ -55,6 +57,9 @@ const IdentityDocumentEIDScanningScreen = () => {
55
57
  setAllowedDocumentTypes(appContext.currentWorkflowStep?.data?.allowedDocumentTypes ?? null);
56
58
  setAllowedCountries(appContext.currentWorkflowStep?.data?.allowedCountries ?? null);
57
59
  }, [appContext.currentWorkflowStep]);
60
+ if (!appContext.currentWorkflowStep) {
61
+ return null;
62
+ }
58
63
  return /*#__PURE__*/_jsxs(SafeAreaView, {
59
64
  style: styles.safeAreaContainer,
60
65
  children: [documentNumber && dateOfBirth && dateOfExpiry ? /*#__PURE__*/_jsx(View, {
@@ -8,8 +8,10 @@ import AppContext from "../../Shared/Contexts/AppContext.js";
8
8
  import NavigationManager from "../../Shared/Components/NavigationManager.js";
9
9
  import { useTranslation } from 'react-i18next';
10
10
  import { trackFunnelStep, useScreenTracking, trackVerificationStart, trackVerificationComplete } from "../../Shared/Libs/analytics.utils.js";
11
+ import { useKeepAwake } from "../../Shared/Libs/native-keep-awake.utils.js";
11
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
13
  const IdentityDocumentScanningScreen = () => {
14
+ useKeepAwake();
13
15
  const [idFrontSideData, setIDFrontSideData] = useState(null);
14
16
  const [idBackSideData, setIDBackSideData] = useState(null);
15
17
  const [passportData, setPassportData] = useState();
@@ -83,6 +85,9 @@ const IdentityDocumentScanningScreen = () => {
83
85
  setAllowedDocumentTypes(appContext.currentWorkflowStep?.data?.allowedDocumentTypes ?? null);
84
86
  setAllowedCountries(appContext.currentWorkflowStep?.data?.allowedCountries ?? null);
85
87
  }, [appContext.currentWorkflowStep]);
88
+ if (!appContext.currentWorkflowStep) {
89
+ return null;
90
+ }
86
91
  return /*#__PURE__*/_jsxs(SafeAreaView, {
87
92
  style: styles.container,
88
93
  children: [/*#__PURE__*/_jsx(IdentityDocumentCamera, {