@trustchex/react-native-sdk 1.381.0 → 1.464.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 (204) hide show
  1. package/android/src/main/java/com/trustchex/reactnativesdk/TrustchexSDKModule.kt +2 -8
  2. package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraView.kt +60 -13
  3. package/android/src/main/java/com/trustchex/reactnativesdk/mlkit/MLKitModule.kt +1 -1
  4. package/ios/Camera/TrustchexCameraView.swift +10 -13
  5. package/ios/MLKit/MLKitModule.swift +1 -1
  6. package/lib/module/Screens/Debug/BarcodeTestScreen.js +308 -0
  7. package/lib/module/Screens/Debug/MRZTestScreen.js +105 -13
  8. package/lib/module/Screens/Debug/NFCScanTestScreen.js +635 -0
  9. package/lib/module/Screens/Dynamic/ContractAcceptanceScreen.js +49 -32
  10. package/lib/module/Screens/Dynamic/IdentityDocumentEIDScanningScreen.js +22 -4
  11. package/lib/module/Screens/Dynamic/IdentityDocumentScanningScreen.js +5 -0
  12. package/lib/module/Screens/Dynamic/LivenessDetectionScreen.js +126 -27
  13. package/lib/module/Screens/Dynamic/VerbalConsentScreen.js +1079 -0
  14. package/lib/module/Screens/Dynamic/VideoCallScreen.js +678 -0
  15. package/lib/module/Screens/Static/OTPVerificationScreen.js +6 -0
  16. package/lib/module/Screens/Static/QrCodeScanningScreen.js +7 -1
  17. package/lib/module/Screens/Static/ResultScreen.js +154 -34
  18. package/lib/module/Screens/Static/VerificationSessionCheckScreen.js +59 -51
  19. package/lib/module/Shared/Animations/recording.json +1 -0
  20. package/lib/module/Shared/Animations/video-call.json +1 -0
  21. package/lib/module/Shared/Components/DebugNavigationPanel.js +231 -67
  22. package/lib/module/Shared/Components/EIDScanner.js +213 -112
  23. package/lib/module/Shared/Components/IdentityDocumentCamera.flows.js +5 -3
  24. package/lib/module/Shared/Components/IdentityDocumentCamera.js +77 -39
  25. package/lib/module/Shared/Components/IdentityDocumentCamera.utils.js +13 -4
  26. package/lib/module/Shared/Components/NavigationManager.js +39 -19
  27. package/lib/module/Shared/Contexts/AppContext.js +1 -0
  28. package/lib/module/Shared/EIDReader/aesSecureMessagingWrapper.js +51 -0
  29. package/lib/module/Shared/EIDReader/apduLevelPACECapable.js +3 -0
  30. package/lib/module/Shared/EIDReader/bacKey.js +16 -2
  31. package/lib/module/Shared/EIDReader/eidReader.js +354 -13
  32. package/lib/module/Shared/EIDReader/eidService.js +25 -1
  33. package/lib/module/Shared/EIDReader/nfcManagerCardService.js +4 -7
  34. package/lib/module/Shared/EIDReader/paceInfo.js +85 -0
  35. package/lib/module/Shared/EIDReader/paceKeySpec.js +51 -0
  36. package/lib/module/Shared/EIDReader/protocol/paceAPDUSender.js +100 -0
  37. package/lib/module/Shared/EIDReader/protocol/paceProtocol.js +655 -0
  38. package/lib/module/Shared/EIDReader/protocol/paceResult.js +37 -0
  39. package/lib/module/Shared/EIDReader/secureMessagingWrapper.js +27 -4
  40. package/lib/module/Shared/EIDReader/smartcards/commandAPDU.js +2 -1
  41. package/lib/module/Shared/EIDReader/tlv/tlv.helpers.js +1 -1
  42. package/lib/module/Shared/EIDReader/tlv/tlv.utils.js +6 -3
  43. package/lib/module/Shared/EIDReader/utils/aesCrypto.utils.js +189 -0
  44. package/lib/module/Shared/Libs/SignalingClient.js +128 -0
  45. package/lib/module/Shared/Libs/analytics.utils.js +8 -0
  46. package/lib/module/Shared/Libs/contains.js +1 -40
  47. package/lib/module/Shared/Libs/country-display.utils.js +34 -0
  48. package/lib/module/Shared/Libs/deeplink.utils.js +9 -1
  49. package/lib/module/Shared/Libs/demo.utils.js +8 -0
  50. package/lib/module/Shared/Libs/http-client.js +9 -0
  51. package/lib/module/Shared/Libs/mrz.utils.js +3 -2
  52. package/lib/module/Shared/Libs/promise.utils.js +16 -2
  53. package/lib/module/Shared/Libs/status-bar.utils.js +23 -0
  54. package/lib/module/Shared/Services/DataUploadService.js +294 -0
  55. package/lib/module/Shared/Services/VideoSessionService.js +156 -0
  56. package/lib/module/Shared/Services/WebRTCService.js +510 -0
  57. package/lib/module/Shared/Types/analytics.types.js +4 -0
  58. package/lib/module/Translation/Resources/en.js +61 -2
  59. package/lib/module/Translation/Resources/tr.js +61 -2
  60. package/lib/module/Trustchex.js +64 -20
  61. package/lib/module/version.js +1 -1
  62. package/lib/typescript/src/Screens/Debug/BarcodeTestScreen.d.ts +3 -0
  63. package/lib/typescript/src/Screens/Debug/BarcodeTestScreen.d.ts.map +1 -0
  64. package/lib/typescript/src/Screens/Debug/MRZTestScreen.d.ts.map +1 -1
  65. package/lib/typescript/src/Screens/Debug/NFCScanTestScreen.d.ts +3 -0
  66. package/lib/typescript/src/Screens/Debug/NFCScanTestScreen.d.ts.map +1 -0
  67. package/lib/typescript/src/Screens/Dynamic/ContractAcceptanceScreen.d.ts.map +1 -1
  68. package/lib/typescript/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.d.ts.map +1 -1
  69. package/lib/typescript/src/Screens/Dynamic/IdentityDocumentScanningScreen.d.ts.map +1 -1
  70. package/lib/typescript/src/Screens/Dynamic/LivenessDetectionScreen.d.ts.map +1 -1
  71. package/lib/typescript/src/Screens/Dynamic/VerbalConsentScreen.d.ts +3 -0
  72. package/lib/typescript/src/Screens/Dynamic/VerbalConsentScreen.d.ts.map +1 -0
  73. package/lib/typescript/src/Screens/Dynamic/VideoCallScreen.d.ts +3 -0
  74. package/lib/typescript/src/Screens/Dynamic/VideoCallScreen.d.ts.map +1 -0
  75. package/lib/typescript/src/Screens/Static/OTPVerificationScreen.d.ts.map +1 -1
  76. package/lib/typescript/src/Screens/Static/QrCodeScanningScreen.d.ts.map +1 -1
  77. package/lib/typescript/src/Screens/Static/ResultScreen.d.ts.map +1 -1
  78. package/lib/typescript/src/Screens/Static/VerificationSessionCheckScreen.d.ts.map +1 -1
  79. package/lib/typescript/src/Shared/Components/DebugNavigationPanel.d.ts.map +1 -1
  80. package/lib/typescript/src/Shared/Components/EIDScanner.d.ts.map +1 -1
  81. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
  82. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts +1 -1
  83. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts.map +1 -1
  84. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts +5 -0
  85. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts.map +1 -1
  86. package/lib/typescript/src/Shared/Components/NavigationManager.d.ts.map +1 -1
  87. package/lib/typescript/src/Shared/Contexts/AppContext.d.ts +1 -0
  88. package/lib/typescript/src/Shared/Contexts/AppContext.d.ts.map +1 -1
  89. package/lib/typescript/src/Shared/EIDReader/aesSecureMessagingWrapper.d.ts +18 -0
  90. package/lib/typescript/src/Shared/EIDReader/aesSecureMessagingWrapper.d.ts.map +1 -0
  91. package/lib/typescript/src/Shared/EIDReader/apduLevelPACECapable.d.ts +23 -0
  92. package/lib/typescript/src/Shared/EIDReader/apduLevelPACECapable.d.ts.map +1 -0
  93. package/lib/typescript/src/Shared/EIDReader/bacKey.d.ts +6 -0
  94. package/lib/typescript/src/Shared/EIDReader/bacKey.d.ts.map +1 -1
  95. package/lib/typescript/src/Shared/EIDReader/eidReader.d.ts.map +1 -1
  96. package/lib/typescript/src/Shared/EIDReader/eidService.d.ts +9 -0
  97. package/lib/typescript/src/Shared/EIDReader/eidService.d.ts.map +1 -1
  98. package/lib/typescript/src/Shared/EIDReader/nfcManagerCardService.d.ts.map +1 -1
  99. package/lib/typescript/src/Shared/EIDReader/paceInfo.d.ts +50 -0
  100. package/lib/typescript/src/Shared/EIDReader/paceInfo.d.ts.map +1 -0
  101. package/lib/typescript/src/Shared/EIDReader/paceKeySpec.d.ts +30 -0
  102. package/lib/typescript/src/Shared/EIDReader/paceKeySpec.d.ts.map +1 -0
  103. package/lib/typescript/src/Shared/EIDReader/protocol/paceAPDUSender.d.ts +17 -0
  104. package/lib/typescript/src/Shared/EIDReader/protocol/paceAPDUSender.d.ts.map +1 -0
  105. package/lib/typescript/src/Shared/EIDReader/protocol/paceProtocol.d.ts +105 -0
  106. package/lib/typescript/src/Shared/EIDReader/protocol/paceProtocol.d.ts.map +1 -0
  107. package/lib/typescript/src/Shared/EIDReader/protocol/paceResult.d.ts +24 -0
  108. package/lib/typescript/src/Shared/EIDReader/protocol/paceResult.d.ts.map +1 -0
  109. package/lib/typescript/src/Shared/EIDReader/secureMessagingWrapper.d.ts +15 -0
  110. package/lib/typescript/src/Shared/EIDReader/secureMessagingWrapper.d.ts.map +1 -1
  111. package/lib/typescript/src/Shared/EIDReader/smartcards/commandAPDU.d.ts.map +1 -1
  112. package/lib/typescript/src/Shared/EIDReader/tlv/tlv.utils.d.ts.map +1 -1
  113. package/lib/typescript/src/Shared/EIDReader/utils/aesCrypto.utils.d.ts +39 -0
  114. package/lib/typescript/src/Shared/EIDReader/utils/aesCrypto.utils.d.ts.map +1 -0
  115. package/lib/typescript/src/Shared/Libs/SignalingClient.d.ts +24 -0
  116. package/lib/typescript/src/Shared/Libs/SignalingClient.d.ts.map +1 -0
  117. package/lib/typescript/src/Shared/Libs/analytics.utils.d.ts.map +1 -1
  118. package/lib/typescript/src/Shared/Libs/contains.d.ts +0 -7
  119. package/lib/typescript/src/Shared/Libs/contains.d.ts.map +1 -1
  120. package/lib/typescript/src/Shared/Libs/country-display.utils.d.ts +2 -0
  121. package/lib/typescript/src/Shared/Libs/country-display.utils.d.ts.map +1 -0
  122. package/lib/typescript/src/Shared/Libs/deeplink.utils.d.ts.map +1 -1
  123. package/lib/typescript/src/Shared/Libs/demo.utils.d.ts.map +1 -1
  124. package/lib/typescript/src/Shared/Libs/http-client.d.ts +1 -1
  125. package/lib/typescript/src/Shared/Libs/http-client.d.ts.map +1 -1
  126. package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts.map +1 -1
  127. package/lib/typescript/src/Shared/Libs/promise.utils.d.ts.map +1 -1
  128. package/lib/typescript/src/Shared/Libs/status-bar.utils.d.ts +9 -0
  129. package/lib/typescript/src/Shared/Libs/status-bar.utils.d.ts.map +1 -0
  130. package/lib/typescript/src/Shared/Services/DataUploadService.d.ts +25 -0
  131. package/lib/typescript/src/Shared/Services/DataUploadService.d.ts.map +1 -0
  132. package/lib/typescript/src/Shared/Services/VideoSessionService.d.ts +33 -0
  133. package/lib/typescript/src/Shared/Services/VideoSessionService.d.ts.map +1 -0
  134. package/lib/typescript/src/Shared/Services/WebRTCService.d.ts +58 -0
  135. package/lib/typescript/src/Shared/Services/WebRTCService.d.ts.map +1 -0
  136. package/lib/typescript/src/Shared/Types/analytics.types.d.ts +4 -0
  137. package/lib/typescript/src/Shared/Types/analytics.types.d.ts.map +1 -1
  138. package/lib/typescript/src/Shared/Types/identificationInfo.d.ts +13 -1
  139. package/lib/typescript/src/Shared/Types/identificationInfo.d.ts.map +1 -1
  140. package/lib/typescript/src/Translation/Resources/en.d.ts +60 -1
  141. package/lib/typescript/src/Translation/Resources/en.d.ts.map +1 -1
  142. package/lib/typescript/src/Translation/Resources/tr.d.ts +60 -1
  143. package/lib/typescript/src/Translation/Resources/tr.d.ts.map +1 -1
  144. package/lib/typescript/src/Trustchex.d.ts.map +1 -1
  145. package/lib/typescript/src/version.d.ts +1 -1
  146. package/package.json +35 -5
  147. package/src/Screens/Debug/BarcodeTestScreen.tsx +317 -0
  148. package/src/Screens/Debug/MRZTestScreen.tsx +107 -13
  149. package/src/Screens/Debug/NFCScanTestScreen.tsx +692 -0
  150. package/src/Screens/Dynamic/ContractAcceptanceScreen.tsx +58 -35
  151. package/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.tsx +27 -4
  152. package/src/Screens/Dynamic/IdentityDocumentScanningScreen.tsx +6 -0
  153. package/src/Screens/Dynamic/LivenessDetectionScreen.tsx +156 -27
  154. package/src/Screens/Dynamic/VerbalConsentScreen.tsx +1401 -0
  155. package/src/Screens/Dynamic/VideoCallScreen.tsx +766 -0
  156. package/src/Screens/Static/OTPVerificationScreen.tsx +6 -0
  157. package/src/Screens/Static/QrCodeScanningScreen.tsx +7 -1
  158. package/src/Screens/Static/ResultScreen.tsx +235 -48
  159. package/src/Screens/Static/VerificationSessionCheckScreen.tsx +67 -72
  160. package/src/Shared/Animations/recording.json +1 -0
  161. package/src/Shared/Animations/video-call.json +1 -0
  162. package/src/Shared/Components/DebugNavigationPanel.tsx +252 -51
  163. package/src/Shared/Components/EIDScanner.tsx +223 -116
  164. package/src/Shared/Components/IdentityDocumentCamera.flows.ts +7 -4
  165. package/src/Shared/Components/IdentityDocumentCamera.tsx +224 -188
  166. package/src/Shared/Components/IdentityDocumentCamera.utils.ts +13 -4
  167. package/src/Shared/Components/NavigationManager.tsx +41 -19
  168. package/src/Shared/Contexts/AppContext.ts +2 -0
  169. package/src/Shared/EIDReader/aesSecureMessagingWrapper.ts +69 -0
  170. package/src/Shared/EIDReader/apduLevelPACECapable.ts +34 -0
  171. package/src/Shared/EIDReader/bacKey.ts +24 -8
  172. package/src/Shared/EIDReader/eidReader.ts +398 -12
  173. package/src/Shared/EIDReader/eidService.ts +49 -1
  174. package/src/Shared/EIDReader/nfcManagerCardService.ts +4 -6
  175. package/src/Shared/EIDReader/paceInfo.ts +159 -0
  176. package/src/Shared/EIDReader/paceKeySpec.ts +56 -0
  177. package/src/Shared/EIDReader/protocol/paceAPDUSender.ts +163 -0
  178. package/src/Shared/EIDReader/protocol/paceProtocol.ts +946 -0
  179. package/src/Shared/EIDReader/protocol/paceResult.ts +62 -0
  180. package/src/Shared/EIDReader/secureMessagingWrapper.ts +28 -10
  181. package/src/Shared/EIDReader/smartcards/commandAPDU.ts +2 -1
  182. package/src/Shared/EIDReader/tlv/tlv.helpers.ts +1 -1
  183. package/src/Shared/EIDReader/tlv/tlv.utils.ts +8 -5
  184. package/src/Shared/EIDReader/utils/aesCrypto.utils.ts +217 -0
  185. package/src/Shared/Libs/SignalingClient.ts +189 -0
  186. package/src/Shared/Libs/analytics.utils.ts +8 -0
  187. package/src/Shared/Libs/contains.ts +0 -53
  188. package/src/Shared/Libs/country-display.utils.ts +55 -0
  189. package/src/Shared/Libs/crypto.utils.ts +2 -2
  190. package/src/Shared/Libs/deeplink.utils.ts +12 -1
  191. package/src/Shared/Libs/demo.utils.ts +10 -0
  192. package/src/Shared/Libs/http-client.ts +19 -1
  193. package/src/Shared/Libs/mrz.utils.ts +3 -2
  194. package/src/Shared/Libs/promise.utils.ts +16 -2
  195. package/src/Shared/Libs/status-bar.utils.ts +21 -0
  196. package/src/Shared/Services/DataUploadService.ts +395 -0
  197. package/src/Shared/Services/VideoSessionService.ts +190 -0
  198. package/src/Shared/Services/WebRTCService.ts +636 -0
  199. package/src/Shared/Types/analytics.types.ts +4 -0
  200. package/src/Shared/Types/identificationInfo.ts +16 -1
  201. package/src/Translation/Resources/en.ts +88 -3
  202. package/src/Translation/Resources/tr.ts +89 -3
  203. package/src/Trustchex.tsx +65 -19
  204. package/src/version.ts +1 -1
@@ -17,20 +17,14 @@ class TrustchexSDKModule(reactContext: ReactApplicationContext) :
17
17
  @ReactMethod
18
18
  override fun enableKeepAwake() {
19
19
  UiThreadUtil.runOnUiThread {
20
- val activity = currentActivity
21
- activity?.runOnUiThread {
22
- activity.window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
23
- }
20
+ currentActivity?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
24
21
  }
25
22
  }
26
23
 
27
24
  @ReactMethod
28
25
  override fun disableKeepAwake() {
29
26
  UiThreadUtil.runOnUiThread {
30
- val activity = currentActivity
31
- activity?.runOnUiThread {
32
- activity.window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
33
- }
27
+ currentActivity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
34
28
  }
35
29
  }
36
30
 
@@ -8,6 +8,8 @@ import android.graphics.Matrix
8
8
  import android.graphics.Rect
9
9
  import android.graphics.YuvImage
10
10
  import android.util.Base64
11
+ import android.hardware.camera2.CameraCharacteristics
12
+ import android.hardware.camera2.CameraManager
11
13
  import android.util.Size
12
14
  import android.widget.FrameLayout
13
15
  import androidx.annotation.OptIn
@@ -99,19 +101,8 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
99
101
  BarcodeScanning.getClient(
100
102
  BarcodeScannerOptions.Builder()
101
103
  .setBarcodeFormats(
102
- Barcode.FORMAT_PDF417,
103
- Barcode.FORMAT_QR_CODE,
104
- Barcode.FORMAT_CODABAR,
105
104
  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
105
+ Barcode.FORMAT_QR_CODE
115
106
  )
116
107
  .build()
117
108
  )
@@ -165,7 +156,7 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
165
156
 
166
157
  private fun selectBestCamera(type: String): CameraSelector {
167
158
  if (type == "front") {
168
- return CameraSelector.DEFAULT_FRONT_CAMERA
159
+ return selectWidestFrontCamera()
169
160
  }
170
161
 
171
162
  // For back camera, try to select Ultra Wide camera for document scanning
@@ -192,6 +183,62 @@ class TrustchexCameraView(context: ThemedReactContext) : FrameLayout(context) {
192
183
  return CameraSelector.DEFAULT_BACK_CAMERA
193
184
  }
194
185
 
186
+ /**
187
+ * Select the front camera with the widest field of view.
188
+ * Many devices (e.g. Pixel 9a, Samsung S24) have multiple front cameras;
189
+ * the wider lens gives a better framing experience for face detection.
190
+ */
191
+ @OptIn(androidx.camera.camera2.interop.ExperimentalCamera2Interop::class)
192
+ private fun selectWidestFrontCamera(): CameraSelector {
193
+ try {
194
+ val provider = cameraProvider ?: return CameraSelector.DEFAULT_FRONT_CAMERA
195
+ val cameraManager = context.getSystemService(android.content.Context.CAMERA_SERVICE) as? CameraManager
196
+ ?: return CameraSelector.DEFAULT_FRONT_CAMERA
197
+
198
+ val frontCameras = provider.availableCameraInfos.filter { info ->
199
+ try {
200
+ val c2Info = androidx.camera.camera2.interop.Camera2CameraInfo.from(info)
201
+ val chars = cameraManager.getCameraCharacteristics(c2Info.cameraId)
202
+ chars.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT
203
+ } catch (_: Exception) { false }
204
+ }
205
+
206
+ if (frontCameras.size <= 1) return CameraSelector.DEFAULT_FRONT_CAMERA
207
+
208
+ // Pick the camera with the shortest focal length (widest FoV)
209
+ var bestInfo: androidx.camera.core.CameraInfo? = null
210
+ var shortestFocal = Float.MAX_VALUE
211
+
212
+ for (info in frontCameras) {
213
+ try {
214
+ val c2Info = androidx.camera.camera2.interop.Camera2CameraInfo.from(info)
215
+ val chars = cameraManager.getCameraCharacteristics(c2Info.cameraId)
216
+ val focalLengths = chars.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)
217
+ if (focalLengths != null && focalLengths.isNotEmpty()) {
218
+ val minFocal = focalLengths.min()
219
+ if (minFocal < shortestFocal) {
220
+ shortestFocal = minFocal
221
+ bestInfo = info
222
+ }
223
+ }
224
+ } catch (_: Exception) { /* skip */ }
225
+ }
226
+
227
+ if (bestInfo != null) {
228
+ val selectedInfo = bestInfo
229
+ return CameraSelector.Builder()
230
+ .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
231
+ .addCameraFilter { cameraInfos ->
232
+ cameraInfos.filter { it == selectedInfo }.ifEmpty { cameraInfos }
233
+ }
234
+ .build()
235
+ }
236
+ } catch (_: Exception) {
237
+ // Fall back to default
238
+ }
239
+ return CameraSelector.DEFAULT_FRONT_CAMERA
240
+ }
241
+
195
242
  fun setTorchEnabled(enabled: Boolean) {
196
243
  torchEnabled = enabled
197
244
  camera?.cameraControl?.enableTorch(enabled)
@@ -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
  }
@@ -248,7 +237,15 @@ class TrustchexCameraView: UIView {
248
237
  // MARK: - Camera Selection
249
238
  private func selectBestCamera(for position: AVCaptureDevice.Position) -> AVCaptureDevice? {
250
239
  if position == .front {
251
- return AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front)
240
+ // Prefer the widest front camera available for better face framing
241
+ let discovery = AVCaptureDevice.DiscoverySession(
242
+ deviceTypes: [.builtInUltraWideCamera, .builtInWideAngleCamera],
243
+ mediaType: .video,
244
+ position: .front
245
+ )
246
+ // DiscoverySession lists in the order of deviceTypes, so ultra-wide comes first if available
247
+ return discovery.devices.first
248
+ ?? AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front)
252
249
  }
253
250
 
254
251
  // For document scanning, prefer wide angle camera for all models
@@ -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,