@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
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { RTCPeerConnection, RTCIceCandidate, RTCSessionDescription, mediaDevices, MediaStream } from 'react-native-webrtc';
|
|
4
|
+
import { SignalingClient } from "../Libs/SignalingClient.js";
|
|
5
|
+
export class WebRTCService {
|
|
6
|
+
peerConnection = null;
|
|
7
|
+
localStream = null;
|
|
8
|
+
remoteStream = null;
|
|
9
|
+
isFlashOn = false;
|
|
10
|
+
pendingCandidates = [];
|
|
11
|
+
hasRemoteDescription = false;
|
|
12
|
+
isProcessingOffer = false;
|
|
13
|
+
lastProcessedOfferSdp = null;
|
|
14
|
+
tracksAdded = false;
|
|
15
|
+
pendingOffer = null;
|
|
16
|
+
isSwitchingCamera = false;
|
|
17
|
+
lastSwitchTime = 0;
|
|
18
|
+
facingMode = 'user';
|
|
19
|
+
videoTrackEndedHandler = null;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.onRemoteStream = config.onRemoteStream;
|
|
22
|
+
this.onConnectionStateChange = config.onConnectionStateChange;
|
|
23
|
+
this.onCommand = config.onCommand;
|
|
24
|
+
this.onSnapshotRequest = config.onSnapshotRequest;
|
|
25
|
+
this.onLocalStreamUpdate = config.onLocalStreamUpdate;
|
|
26
|
+
this.baseUrl = config.baseUrl;
|
|
27
|
+
this.sessionId = config.sessionId;
|
|
28
|
+
this.identificationId = config.identificationId;
|
|
29
|
+
this.signalingClient = new SignalingClient(config.baseUrl, config.sessionId, this.handleSignalingMessage.bind(this), config.identificationId, config.onSessionEnded);
|
|
30
|
+
}
|
|
31
|
+
async fetchIceServers() {
|
|
32
|
+
try {
|
|
33
|
+
const params = this.identificationId ? `?identificationId=${this.identificationId}` : '';
|
|
34
|
+
const response = await fetch(`${this.baseUrl}/api/app/mobile/video-sessions/${this.sessionId}/ice-servers${params}`);
|
|
35
|
+
if (!response.ok) return [];
|
|
36
|
+
const data = await response.json();
|
|
37
|
+
return Array.isArray(data.iceServers) ? data.iceServers : [];
|
|
38
|
+
} catch {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async initialize() {
|
|
43
|
+
console.log('[WebRTCService] Initializing...');
|
|
44
|
+
try {
|
|
45
|
+
// Fetch ICE servers before getUserMedia so peer connection is ready sooner
|
|
46
|
+
const iceServers = await this.fetchIceServers();
|
|
47
|
+
|
|
48
|
+
// Initialize PeerConnection before getUserMedia so signaling can start
|
|
49
|
+
// immediately — avoids missing the agent's offer while camera init blocks.
|
|
50
|
+
this.peerConnection = new RTCPeerConnection({
|
|
51
|
+
iceServers,
|
|
52
|
+
iceCandidatePoolSize: 2
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Set up event handlers before signaling connects.
|
|
56
|
+
// Use addEventListener instead of property assignment for reliable
|
|
57
|
+
// delivery in react-native-webrtc (property may be overwritten).
|
|
58
|
+
this.peerConnection.addEventListener('track', event => {
|
|
59
|
+
if (event.streams && event.streams[0]) {
|
|
60
|
+
this.remoteStream = event.streams[0];
|
|
61
|
+
this.onRemoteStream(this.remoteStream);
|
|
62
|
+
} else if (event.track) {
|
|
63
|
+
const existingTracks = this.remoteStream ? this.remoteStream.getTracks() : [];
|
|
64
|
+
this.remoteStream = new MediaStream([...existingTracks, event.track]);
|
|
65
|
+
this.onRemoteStream(this.remoteStream);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
this.peerConnection.addEventListener('icecandidate', event => {
|
|
69
|
+
if (event.candidate) {
|
|
70
|
+
this.signalingClient.send('ice-candidate', event.candidate.toJSON());
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// react-native-webrtc often does not fire connectionstatechange or sets
|
|
75
|
+
// connectionState to undefined. Use iceconnectionstatechange which is
|
|
76
|
+
// reliably implemented across all versions.
|
|
77
|
+
this.peerConnection.addEventListener('iceconnectionstatechange', () => {
|
|
78
|
+
if (!this.peerConnection) return;
|
|
79
|
+
const iceState = this.peerConnection.iceConnectionState || 'new';
|
|
80
|
+
// Map ICE states to the connection states the UI expects
|
|
81
|
+
const mapped = iceState === 'connected' || iceState === 'completed' ? 'connected' : iceState === 'failed' ? 'failed' : iceState === 'disconnected' ? 'disconnected' : iceState === 'closed' ? 'closed' : iceState;
|
|
82
|
+
this.onConnectionStateChange(mapped);
|
|
83
|
+
if (mapped === 'connected') {
|
|
84
|
+
this.sendTorchAvailability();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Connect signaling now — peer connection + handlers are ready.
|
|
89
|
+
// Any offer that arrives before local tracks are added is buffered in
|
|
90
|
+
// pendingOffer and processed once tracks are attached below.
|
|
91
|
+
this.signalingClient.connect();
|
|
92
|
+
|
|
93
|
+
// Get local stream. Avoid strict min constraints that hang on some Android
|
|
94
|
+
// devices when the camera cannot satisfy the combination.
|
|
95
|
+
const stream = await mediaDevices.getUserMedia({
|
|
96
|
+
audio: true,
|
|
97
|
+
video: {
|
|
98
|
+
facingMode: 'user',
|
|
99
|
+
frameRate: {
|
|
100
|
+
ideal: 30
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
this.localStream = stream;
|
|
105
|
+
|
|
106
|
+
// Add local tracks
|
|
107
|
+
stream.getTracks().forEach(track => {
|
|
108
|
+
this.peerConnection?.addTrack(track, stream);
|
|
109
|
+
});
|
|
110
|
+
this.tracksAdded = true;
|
|
111
|
+
|
|
112
|
+
// If the agent's offer arrived while getUserMedia was pending, process it now.
|
|
113
|
+
if (this.pendingOffer) {
|
|
114
|
+
const buffered = this.pendingOffer;
|
|
115
|
+
this.pendingOffer = null;
|
|
116
|
+
await this.handleSignalingMessage(buffered);
|
|
117
|
+
}
|
|
118
|
+
this.sendTorchAvailability();
|
|
119
|
+
return stream;
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.error('[WebRTCService] Initialization failed:', error);
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async handleSignalingMessage(message) {
|
|
126
|
+
if (!this.peerConnection) return;
|
|
127
|
+
try {
|
|
128
|
+
switch (message.type) {
|
|
129
|
+
case 'offer':
|
|
130
|
+
{
|
|
131
|
+
// Buffer the offer until local tracks have been added so the answer
|
|
132
|
+
// includes the mobile's audio/video tracks.
|
|
133
|
+
if (!this.tracksAdded) {
|
|
134
|
+
console.log('[WebRTCService] Offer received before tracks ready, buffering');
|
|
135
|
+
this.pendingOffer = message;
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Skip if we're already processing an offer
|
|
140
|
+
if (this.isProcessingOffer) {
|
|
141
|
+
console.log('[WebRTCService] Skipping offer - already processing one');
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const offerSdp = message.payload?.sdp;
|
|
145
|
+
if (offerSdp && this.lastProcessedOfferSdp === offerSdp) {
|
|
146
|
+
console.log('[WebRTCService] Skipping offer - duplicate SDP');
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
this.isProcessingOffer = true;
|
|
150
|
+
console.log('[WebRTCService] Received offer');
|
|
151
|
+
try {
|
|
152
|
+
await this.peerConnection.setRemoteDescription(new RTCSessionDescription(message.payload));
|
|
153
|
+
this.hasRemoteDescription = true;
|
|
154
|
+
// Add any pending candidates
|
|
155
|
+
await this.addPendingCandidates();
|
|
156
|
+
const answer = await this.peerConnection.createAnswer();
|
|
157
|
+
await this.peerConnection.setLocalDescription(answer);
|
|
158
|
+
await this.signalingClient.send('answer', {
|
|
159
|
+
type: answer.type,
|
|
160
|
+
sdp: answer.sdp
|
|
161
|
+
});
|
|
162
|
+
this.lastProcessedOfferSdp = offerSdp ?? null;
|
|
163
|
+
} finally {
|
|
164
|
+
this.isProcessingOffer = false;
|
|
165
|
+
}
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
case 'answer':
|
|
169
|
+
console.log('[WebRTCService] Received answer');
|
|
170
|
+
await this.peerConnection.setRemoteDescription(new RTCSessionDescription(message.payload));
|
|
171
|
+
this.hasRemoteDescription = true;
|
|
172
|
+
// Add any pending candidates
|
|
173
|
+
await this.addPendingCandidates();
|
|
174
|
+
break;
|
|
175
|
+
case 'ice-candidate':
|
|
176
|
+
if (message.payload) {
|
|
177
|
+
const candidate = new RTCIceCandidate(message.payload);
|
|
178
|
+
if (this.hasRemoteDescription) {
|
|
179
|
+
console.log('[WebRTCService] Adding ICE candidate');
|
|
180
|
+
await this.peerConnection.addIceCandidate(candidate);
|
|
181
|
+
} else {
|
|
182
|
+
this.pendingCandidates.push(candidate);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
break;
|
|
186
|
+
case 'command':
|
|
187
|
+
this.handleCommand(message.payload);
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
} catch (error) {
|
|
191
|
+
console.error('[WebRTCService] Error handling signaling:', error);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
handleCommand(payload) {
|
|
195
|
+
console.log('[WebRTCService] Received command:', payload);
|
|
196
|
+
if (this.onCommand) {
|
|
197
|
+
this.onCommand(payload);
|
|
198
|
+
}
|
|
199
|
+
switch (payload.type) {
|
|
200
|
+
case 'switchCamera':
|
|
201
|
+
this.switchCamera();
|
|
202
|
+
break;
|
|
203
|
+
case 'toggleFlash':
|
|
204
|
+
this.toggleFlash();
|
|
205
|
+
break;
|
|
206
|
+
case 'captureSnapshot':
|
|
207
|
+
this.captureSnapshot(payload.requestId);
|
|
208
|
+
break;
|
|
209
|
+
case 'takeSnapshot':
|
|
210
|
+
this.captureSnapshot(payload.requestId);
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
async addPendingCandidates() {
|
|
215
|
+
if (this.pendingCandidates.length > 0 && this.peerConnection) {
|
|
216
|
+
console.log(`[WebRTCService] Adding ${this.pendingCandidates.length} pending ICE candidates`);
|
|
217
|
+
for (const candidate of this.pendingCandidates) {
|
|
218
|
+
try {
|
|
219
|
+
await this.peerConnection.addIceCandidate(candidate);
|
|
220
|
+
} catch (error) {
|
|
221
|
+
console.error('[WebRTCService] Error adding pending candidate:', error);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
this.pendingCandidates = [];
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
cleanup() {
|
|
228
|
+
this.localStream?.getTracks().forEach(t => t.stop());
|
|
229
|
+
this.peerConnection?.close();
|
|
230
|
+
this.signalingClient.disconnect();
|
|
231
|
+
this.localStream = null;
|
|
232
|
+
this.remoteStream = null;
|
|
233
|
+
this.peerConnection = null;
|
|
234
|
+
this.pendingCandidates = [];
|
|
235
|
+
this.hasRemoteDescription = false;
|
|
236
|
+
this.lastProcessedOfferSdp = null;
|
|
237
|
+
this.isProcessingOffer = false;
|
|
238
|
+
this.tracksAdded = false;
|
|
239
|
+
this.pendingOffer = null;
|
|
240
|
+
}
|
|
241
|
+
async switchCamera() {
|
|
242
|
+
// Debounce: ignore if already switching or within 2s cooldown
|
|
243
|
+
const now = Date.now();
|
|
244
|
+
if (this.isSwitchingCamera || now - this.lastSwitchTime < 2000) {
|
|
245
|
+
console.warn('[WebRTCService] switchCamera ignored — cooldown');
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
if (!this.localStream || !this.peerConnection) return;
|
|
249
|
+
const videoTrack = this.localStream.getVideoTracks()[0];
|
|
250
|
+
if (!videoTrack) return;
|
|
251
|
+
this.isSwitchingCamera = true;
|
|
252
|
+
this.lastSwitchTime = now;
|
|
253
|
+
try {
|
|
254
|
+
const newFacing = this.facingMode === 'user' ? 'environment' : 'user';
|
|
255
|
+
|
|
256
|
+
// First, remove the video track from the sender (set to null).
|
|
257
|
+
// This signals to the encoder to stop, which releases the camera HAL.
|
|
258
|
+
const senders = this.peerConnection.getSenders?.();
|
|
259
|
+
let videoSender = null;
|
|
260
|
+
if (senders) {
|
|
261
|
+
for (const sender of senders) {
|
|
262
|
+
if (sender.track?.kind === 'video') {
|
|
263
|
+
videoSender = sender;
|
|
264
|
+
await sender.replaceTrack(null);
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Stop the old track to fully release the camera hardware.
|
|
271
|
+
videoTrack.stop();
|
|
272
|
+
|
|
273
|
+
// Small delay to let the camera HAL fully release on Android.
|
|
274
|
+
await new Promise(res => setTimeout(res, 200));
|
|
275
|
+
|
|
276
|
+
// Acquire a new stream from the target camera. Now that the old camera
|
|
277
|
+
// is fully released, there's no concurrent camera conflict.
|
|
278
|
+
const newStream = await mediaDevices.getUserMedia({
|
|
279
|
+
audio: false,
|
|
280
|
+
video: {
|
|
281
|
+
facingMode: newFacing,
|
|
282
|
+
frameRate: {
|
|
283
|
+
ideal: 30
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
const newVideoTrack = newStream.getVideoTracks()[0];
|
|
288
|
+
if (!newVideoTrack) {
|
|
289
|
+
console.warn('[WebRTCService] switchCamera: no video track from getUserMedia');
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Replace the null track in the sender with the new camera track.
|
|
294
|
+
// This properly notifies the WebRTC encoder to start encoding from
|
|
295
|
+
// the new camera — unlike _switchCamera() which only changes the
|
|
296
|
+
// hardware source without informing the encoder/remote side.
|
|
297
|
+
if (videoSender) {
|
|
298
|
+
await videoSender.replaceTrack(newVideoTrack);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Build a new MediaStream with existing audio + new video.
|
|
302
|
+
const audioTracks = this.localStream.getAudioTracks();
|
|
303
|
+
this.localStream = new MediaStream([...audioTracks, newVideoTrack]);
|
|
304
|
+
this.facingMode = newFacing;
|
|
305
|
+
|
|
306
|
+
// Listen for the track ending unexpectedly (Android camera HAL power
|
|
307
|
+
// management can kill the rear camera mid-call). Re-acquire on ended.
|
|
308
|
+
if (this.videoTrackEndedHandler) {
|
|
309
|
+
videoTrack.removeEventListener?.('ended', this.videoTrackEndedHandler);
|
|
310
|
+
}
|
|
311
|
+
this.videoTrackEndedHandler = () => {
|
|
312
|
+
console.warn('[WebRTCService] video track ended unexpectedly — re-acquiring');
|
|
313
|
+
this.reacquireVideoTrack();
|
|
314
|
+
};
|
|
315
|
+
newVideoTrack.addEventListener?.('ended', this.videoTrackEndedHandler);
|
|
316
|
+
|
|
317
|
+
// Notify the screen to update its local stream reference and remount RTCView
|
|
318
|
+
this.onLocalStreamUpdate?.(this.localStream);
|
|
319
|
+
} catch (error) {
|
|
320
|
+
console.warn('[WebRTCService] switchCamera failed:', error);
|
|
321
|
+
} finally {
|
|
322
|
+
this.isSwitchingCamera = false;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
async reacquireVideoTrack() {
|
|
326
|
+
if (!this.localStream || !this.peerConnection) return;
|
|
327
|
+
try {
|
|
328
|
+
const newStream = await mediaDevices.getUserMedia({
|
|
329
|
+
audio: false,
|
|
330
|
+
video: {
|
|
331
|
+
facingMode: this.facingMode,
|
|
332
|
+
frameRate: {
|
|
333
|
+
ideal: 30
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
const newVideoTrack = newStream.getVideoTracks()[0];
|
|
338
|
+
if (!newVideoTrack) return;
|
|
339
|
+
const senders = this.peerConnection.getSenders?.();
|
|
340
|
+
if (senders) {
|
|
341
|
+
for (const sender of senders) {
|
|
342
|
+
if (sender.track?.kind === 'video' || sender.track === null) {
|
|
343
|
+
await sender.replaceTrack(newVideoTrack);
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
if (this.videoTrackEndedHandler) {
|
|
349
|
+
newVideoTrack.addEventListener?.('ended', this.videoTrackEndedHandler);
|
|
350
|
+
}
|
|
351
|
+
const audioTracks = this.localStream.getAudioTracks();
|
|
352
|
+
this.localStream = new MediaStream([...audioTracks, newVideoTrack]);
|
|
353
|
+
this.onLocalStreamUpdate?.(this.localStream);
|
|
354
|
+
} catch (error) {
|
|
355
|
+
console.warn('[WebRTCService] reacquireVideoTrack failed:', error);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
async toggleFlash() {
|
|
359
|
+
const videoTrack = this.localStream?.getVideoTracks()[0];
|
|
360
|
+
if (!videoTrack) {
|
|
361
|
+
console.warn('[WebRTCService] No video track available for flash toggle');
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
this.isFlashOn = !this.isFlashOn;
|
|
365
|
+
|
|
366
|
+
// applyConstraints is the only reliable method for torch on Android.
|
|
367
|
+
// Retry up to 3 times with 300ms delay to handle "Camera switch already in progress" race.
|
|
368
|
+
let success = false;
|
|
369
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
370
|
+
try {
|
|
371
|
+
await videoTrack.applyConstraints({
|
|
372
|
+
advanced: [{
|
|
373
|
+
torch: this.isFlashOn
|
|
374
|
+
}]
|
|
375
|
+
});
|
|
376
|
+
success = true;
|
|
377
|
+
break;
|
|
378
|
+
} catch (error) {
|
|
379
|
+
const msg = error?.message || '';
|
|
380
|
+
if (msg.includes('Camera switch') && attempt < 2) {
|
|
381
|
+
await new Promise(res => setTimeout(res, 300));
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
console.warn('[WebRTCService] Failed to toggle flash:', error);
|
|
385
|
+
this.isFlashOn = !this.isFlashOn; // revert
|
|
386
|
+
this.signalingClient.send('command', {
|
|
387
|
+
type: 'torch_availability',
|
|
388
|
+
available: false
|
|
389
|
+
});
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
if (!success) {
|
|
394
|
+
this.isFlashOn = !this.isFlashOn; // revert
|
|
395
|
+
this.signalingClient.send('command', {
|
|
396
|
+
type: 'torch_availability',
|
|
397
|
+
available: false
|
|
398
|
+
});
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Confirm flash is available now that we know it works
|
|
403
|
+
this.signalingClient.send('command', {
|
|
404
|
+
type: 'torch_availability',
|
|
405
|
+
available: true
|
|
406
|
+
});
|
|
407
|
+
this.signalingClient.send('command', {
|
|
408
|
+
type: 'flash_state',
|
|
409
|
+
isFlashOn: this.isFlashOn
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
sendTorchAvailability() {
|
|
413
|
+
const videoTrack = this.localStream?.getVideoTracks()[0];
|
|
414
|
+
if (!videoTrack) {
|
|
415
|
+
this.signalingClient.send('command', {
|
|
416
|
+
type: 'torch_availability',
|
|
417
|
+
available: false
|
|
418
|
+
});
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
let capabilities;
|
|
422
|
+
try {
|
|
423
|
+
capabilities = videoTrack.getCapabilities?.();
|
|
424
|
+
} catch {
|
|
425
|
+
capabilities = undefined;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Only trust getCapabilities().torch — _setTorch exists on every Android
|
|
429
|
+
// track regardless of whether the camera actually has a flash.
|
|
430
|
+
const available = !!capabilities?.torch;
|
|
431
|
+
this.signalingClient.send('command', {
|
|
432
|
+
type: 'torch_availability',
|
|
433
|
+
available
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Handle snapshot capture request. Captures a frame from the local video track directly.
|
|
439
|
+
*/
|
|
440
|
+
async captureSnapshot(requestId) {
|
|
441
|
+
console.log('[WebRTCService] Snapshot requested, requestId:', requestId);
|
|
442
|
+
if (this.onSnapshotRequest && requestId) {
|
|
443
|
+
// Delegate to parent component which has access to the RTCView
|
|
444
|
+
this.onSnapshotRequest(requestId);
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Capture directly from local video track via react-native-webrtc captureFrame()
|
|
449
|
+
const videoTrack = this.localStream?.getVideoTracks()[0];
|
|
450
|
+
if (!videoTrack) {
|
|
451
|
+
console.error('[WebRTCService] No local video track for snapshot');
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
try {
|
|
455
|
+
const frame = await videoTrack.captureFrame();
|
|
456
|
+
const base64 = frame?.data;
|
|
457
|
+
if (!base64) {
|
|
458
|
+
console.error('[WebRTCService] captureFrame returned no data');
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
await this.uploadSnapshot(requestId, base64);
|
|
462
|
+
} catch (error) {
|
|
463
|
+
console.error('[WebRTCService] captureFrame failed:', error);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Upload a captured snapshot image (called by parent component after capturing RTCView).
|
|
469
|
+
*/
|
|
470
|
+
async uploadSnapshot(requestId, base64Image) {
|
|
471
|
+
console.log('[WebRTCService] Uploading snapshot, requestId:', requestId);
|
|
472
|
+
try {
|
|
473
|
+
const formData = new FormData();
|
|
474
|
+
// Convert base64 to Blob via fetch data URL (works in React Native)
|
|
475
|
+
const dataResponse = await fetch(`data:image/jpeg;base64,${base64Image}`);
|
|
476
|
+
const blob = await dataResponse.blob();
|
|
477
|
+
formData.append('image', blob);
|
|
478
|
+
const uploadUrl = `${this.baseUrl}/api/app/mobile/video-sessions/${this.sessionId}/snapshots?identificationId=${this.identificationId}`;
|
|
479
|
+
const response = await fetch(uploadUrl, {
|
|
480
|
+
method: 'POST',
|
|
481
|
+
body: formData
|
|
482
|
+
});
|
|
483
|
+
if (response.ok) {
|
|
484
|
+
const result = await response.json();
|
|
485
|
+
console.log('[WebRTCService] Snapshot uploaded:', result);
|
|
486
|
+
await this.signalingClient.send('command', {
|
|
487
|
+
type: 'snapshotReady',
|
|
488
|
+
snapshotId: result.snapshotId,
|
|
489
|
+
url: result.url,
|
|
490
|
+
createdAt: new Date().toISOString()
|
|
491
|
+
});
|
|
492
|
+
} else {
|
|
493
|
+
const errorText = await response.text();
|
|
494
|
+
console.error('[WebRTCService] Snapshot upload failed:', response.status, errorText);
|
|
495
|
+
await this.signalingClient.send('command', {
|
|
496
|
+
type: 'snapshotError',
|
|
497
|
+
requestId,
|
|
498
|
+
error: `Upload failed: ${response.status}`
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
} catch (error) {
|
|
502
|
+
console.error('[WebRTCService] Snapshot upload error:', error);
|
|
503
|
+
await this.signalingClient.send('command', {
|
|
504
|
+
type: 'snapshotError',
|
|
505
|
+
requestId,
|
|
506
|
+
error: String(error)
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
@@ -68,6 +68,8 @@ export let AnalyticsEventName = /*#__PURE__*/function (AnalyticsEventName) {
|
|
|
68
68
|
AnalyticsEventName["IDENTITY_DOCUMENT_EID_SCAN_COMPLETED"] = "identity_document_eid_scan_completed";
|
|
69
69
|
AnalyticsEventName["LIVENESS_CHECK_STARTED"] = "liveness_check_started";
|
|
70
70
|
AnalyticsEventName["LIVENESS_CHECK_COMPLETED"] = "liveness_check_completed";
|
|
71
|
+
AnalyticsEventName["VIDEO_CALL_STARTED"] = "video_call_started";
|
|
72
|
+
AnalyticsEventName["VIDEO_CALL_COMPLETED"] = "video_call_completed";
|
|
71
73
|
// NFC Scan Events (used by trackNFCScan* helpers)
|
|
72
74
|
AnalyticsEventName["NFC_SCAN_STARTED"] = "nfc_scan_started";
|
|
73
75
|
AnalyticsEventName["NFC_SCAN_COMPLETED"] = "nfc_scan_completed";
|
|
@@ -127,6 +127,26 @@ export default {
|
|
|
127
127
|
'identityDocumentCamera.documentTooLarge': 'Too close. Move back.',
|
|
128
128
|
'identityDocumentCamera.holdSteady': 'Keep device steady',
|
|
129
129
|
'identityDocumentCamera.centerDocument': 'Center document in the frame',
|
|
130
|
+
'videoCallScreen.guideHeader': 'Get Ready for Video Call',
|
|
131
|
+
'videoCallScreen.guideText': 'Before you begin, please note the following:',
|
|
132
|
+
'videoCallScreen.guidePoint1': 'Ensure you are in a quiet environment with good lighting',
|
|
133
|
+
'videoCallScreen.guidePoint2': 'Have your identity document ready if requested',
|
|
134
|
+
'videoCallScreen.guidePoint3': 'Make sure your internet connection is stable',
|
|
135
|
+
'videoCallScreen.guidePoint4': 'The agent will guide you through the verification process',
|
|
136
|
+
'videoCallScreen.waitingForAgent': 'Waiting for agent...',
|
|
137
|
+
'videoCallScreen.queuePosition': 'Queue position: {position}',
|
|
138
|
+
'videoCallScreen.new': 'Initializing connection...',
|
|
139
|
+
'videoCallScreen.connecting': 'Connecting...',
|
|
140
|
+
'videoCallScreen.connected': 'Connected',
|
|
141
|
+
'videoCallScreen.disconnected': 'Disconnected',
|
|
142
|
+
'videoCallScreen.failed': 'Connection failed',
|
|
143
|
+
'videoCallScreen.closed': 'Connection closed',
|
|
144
|
+
'videoCallScreen.permissions_denied': 'Camera permissions required',
|
|
145
|
+
'videoCallScreen.leaveQueue': 'Leave Queue',
|
|
146
|
+
'videoCallScreen.closeSession': 'Close Session',
|
|
147
|
+
'videoCallScreen.closeSessionHint': 'You can close this session and start a new verification',
|
|
148
|
+
'videoCallScreen.agentInstructions': 'Instructions from Agent',
|
|
149
|
+
'videoCallScreen.callNotCompleted': 'Video call was not completed. This step is required to proceed.',
|
|
130
150
|
'navigationManager.skipStepWarning': 'Completing this step is recommended for successful verification. Skip anyway?',
|
|
131
151
|
'navigationManager.skipStepLabel': 'Skip This Step'
|
|
132
152
|
};
|
|
@@ -127,6 +127,26 @@ export default {
|
|
|
127
127
|
'identityDocumentCamera.documentTooLarge': 'Belge çok yakın. Uzaklaşın.',
|
|
128
128
|
'identityDocumentCamera.holdSteady': 'Cihazı sabit tutun',
|
|
129
129
|
'identityDocumentCamera.centerDocument': 'Belgeyi çerçevede ortalayın',
|
|
130
|
+
'videoCallScreen.guideHeader': 'Görüntülü Görüşme İçin Hazırlanın',
|
|
131
|
+
'videoCallScreen.guideText': 'Başlamadan önce lütfen aşağıdaki hususlara dikkat edin:',
|
|
132
|
+
'videoCallScreen.guidePoint1': 'Sessiz ve iyi aydınlatılmış bir ortamda olduğunuzdan emin olun',
|
|
133
|
+
'videoCallScreen.guidePoint2': 'İstendiğinde kimlik belgenizi hazır bulundurun',
|
|
134
|
+
'videoCallScreen.guidePoint3': 'İnternet bağlantınızın stabil olduğundan emin olun',
|
|
135
|
+
'videoCallScreen.guidePoint4': 'Temsilci sizi doğrulama sürecinde yönlendirecektir',
|
|
136
|
+
'videoCallScreen.waitingForAgent': 'Temsilci bekleniyor...',
|
|
137
|
+
'videoCallScreen.queuePosition': 'Sıra konumu: {position}',
|
|
138
|
+
'videoCallScreen.new': 'Bağlantı başlatılıyor...',
|
|
139
|
+
'videoCallScreen.connecting': 'Bağlanıyor...',
|
|
140
|
+
'videoCallScreen.connected': 'Bağlandı',
|
|
141
|
+
'videoCallScreen.disconnected': 'Bağlantı kesildi',
|
|
142
|
+
'videoCallScreen.failed': 'Bağlantı başarısız',
|
|
143
|
+
'videoCallScreen.closed': 'Bağlantı kapatıldı',
|
|
144
|
+
'videoCallScreen.permissions_denied': 'Kamera izni gerekiyor',
|
|
145
|
+
'videoCallScreen.leaveQueue': 'Kuyruktan Çık',
|
|
146
|
+
'videoCallScreen.closeSession': 'Oturumu Kapat',
|
|
147
|
+
'videoCallScreen.closeSessionHint': 'Bu oturumu kapatıp yeni bir doğrulama başlatabilirsiniz',
|
|
148
|
+
'videoCallScreen.agentInstructions': 'Temsilciden Talimatlar',
|
|
149
|
+
'videoCallScreen.callNotCompleted': 'Görüntülü görüşme tamamlanmadı. Devam etmek için bu adım zorunludur.',
|
|
130
150
|
'navigationManager.skipStepWarning': 'Başarılı bir doğrulama için bu adımı tamamlamanız önerilir. Yine de atlamak istiyor musunuz?',
|
|
131
151
|
'navigationManager.skipStepLabel': 'Bu Adımı Atla'
|
|
132
152
|
};
|
package/lib/module/Trustchex.js
CHANGED
|
@@ -6,6 +6,7 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
|
|
6
6
|
import { View, ActivityIndicator, StyleSheet } from 'react-native';
|
|
7
7
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
8
8
|
import 'react-native-get-random-values';
|
|
9
|
+
import { registerGlobals } from 'react-native-webrtc';
|
|
9
10
|
import { ThemeProvider } from "./Shared/Contexts/ThemeContext.js";
|
|
10
11
|
import { setDebugMode, setLogLevel, logWarn } from "./Shared/Libs/debug.utils.js";
|
|
11
12
|
import IdentityDocumentEIDScanningScreen from "./Screens/Dynamic/IdentityDocumentEIDScanningScreen.js";
|
|
@@ -15,8 +16,10 @@ import ResultScreen from "./Screens/Static/ResultScreen.js";
|
|
|
15
16
|
import ContractAcceptanceScreen from "./Screens/Dynamic/ContractAcceptanceScreen.js";
|
|
16
17
|
import VerificationSessionCheckScreen from "./Screens/Static/VerificationSessionCheckScreen.js";
|
|
17
18
|
import QrCodeScanningScreen from "./Screens/Static/QrCodeScanningScreen.js";
|
|
19
|
+
import VideoCallScreen from "./Screens/Dynamic/VideoCallScreen.js";
|
|
18
20
|
import OTPVerificationScreen from "./Screens/Static/OTPVerificationScreen.js";
|
|
19
21
|
import MRZTestScreen from "./Screens/Debug/MRZTestScreen.js";
|
|
22
|
+
import BarcodeTestScreen from "./Screens/Debug/BarcodeTestScreen.js";
|
|
20
23
|
import AppContext from "./Shared/Contexts/AppContext.js";
|
|
21
24
|
import DebugNavigationPanel from "./Shared/Components/DebugNavigationPanel.js";
|
|
22
25
|
import i18n from "./Translation/index.js";
|
|
@@ -24,6 +27,7 @@ import { initializeTTS } from "./Shared/Libs/tts.utils.js";
|
|
|
24
27
|
import { analyticsService } from "./Shared/Services/AnalyticsService.js";
|
|
25
28
|
import { AnalyticsEventCategory, AnalyticsEventName } from "./Shared/Types/analytics.types.js";
|
|
26
29
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
30
|
+
registerGlobals();
|
|
27
31
|
const Stack = createNativeStackNavigator();
|
|
28
32
|
const DEFAULT_BRANDING = {
|
|
29
33
|
logoUrl: '',
|
|
@@ -166,9 +170,15 @@ const Trustchex = ({
|
|
|
166
170
|
}), /*#__PURE__*/_jsx(Stack.Screen, {
|
|
167
171
|
name: "QrCodeScanningScreen",
|
|
168
172
|
component: QrCodeScanningScreen
|
|
173
|
+
}), /*#__PURE__*/_jsx(Stack.Screen, {
|
|
174
|
+
name: "VideoCallScreen",
|
|
175
|
+
component: VideoCallScreen
|
|
169
176
|
}), /*#__PURE__*/_jsx(Stack.Screen, {
|
|
170
177
|
name: "MRZTestScreen",
|
|
171
178
|
component: MRZTestScreen
|
|
179
|
+
}), /*#__PURE__*/_jsx(Stack.Screen, {
|
|
180
|
+
name: "BarcodeTestScreen",
|
|
181
|
+
component: BarcodeTestScreen
|
|
172
182
|
})]
|
|
173
183
|
}), /*#__PURE__*/_jsx(DebugNavigationPanel, {})]
|
|
174
184
|
})
|
package/lib/module/version.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BarcodeTestScreen.d.ts","sourceRoot":"","sources":["../../../../../src/Screens/Debug/BarcodeTestScreen.tsx"],"names":[],"mappings":"AAgDA,QAAA,MAAM,iBAAiB,+CAuJtB,CAAC;AAqHF,eAAe,iBAAiB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MRZTestScreen.d.ts","sourceRoot":"","sources":["../../../../../src/Screens/Debug/MRZTestScreen.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MRZTestScreen.d.ts","sourceRoot":"","sources":["../../../../../src/Screens/Debug/MRZTestScreen.tsx"],"names":[],"mappings":"AAyBA,QAAA,MAAM,aAAa,+CA6LlB,CAAC;AAwFF,eAAe,aAAa,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContractAcceptanceScreen.d.ts","sourceRoot":"","sources":["../../../../../src/Screens/Dynamic/ContractAcceptanceScreen.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ContractAcceptanceScreen.d.ts","sourceRoot":"","sources":["../../../../../src/Screens/Dynamic/ContractAcceptanceScreen.tsx"],"names":[],"mappings":"AA6BA,QAAA,MAAM,wBAAwB,+CAyK7B,CAAC;AAiCF,eAAe,wBAAwB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IdentityDocumentEIDScanningScreen.d.ts","sourceRoot":"","sources":["../../../../../src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"IdentityDocumentEIDScanningScreen.d.ts","sourceRoot":"","sources":["../../../../../src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.tsx"],"names":[],"mappings":"AAqBA,QAAA,MAAM,iCAAiC,+CA2MtC,CAAC;AAoBF,eAAe,iCAAiC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IdentityDocumentScanningScreen.d.ts","sourceRoot":"","sources":["../../../../../src/Screens/Dynamic/IdentityDocumentScanningScreen.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"IdentityDocumentScanningScreen.d.ts","sourceRoot":"","sources":["../../../../../src/Screens/Dynamic/IdentityDocumentScanningScreen.tsx"],"names":[],"mappings":"AAqBA,QAAA,MAAM,8BAA8B,+CAuJnC,CAAC;AAgBF,eAAe,8BAA8B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LivenessDetectionScreen.d.ts","sourceRoot":"","sources":["../../../../../src/Screens/Dynamic/LivenessDetectionScreen.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LivenessDetectionScreen.d.ts","sourceRoot":"","sources":["../../../../../src/Screens/Dynamic/LivenessDetectionScreen.tsx"],"names":[],"mappings":"AAwFA,QAAA,MAAM,uBAAuB,+CA02B5B,CAAC;AAoFF,eAAe,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VideoCallScreen.d.ts","sourceRoot":"","sources":["../../../../../src/Screens/Dynamic/VideoCallScreen.tsx"],"names":[],"mappings":"AAiCA,QAAA,MAAM,eAAe,GAAI,gBAAgB,GAAG,4CAiiB3C,CAAC;AAyLF,eAAe,eAAe,CAAC"}
|