@trustchex/react-native-sdk 1.361.0 → 1.362.1
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/TrustchexSDK.podspec +3 -1
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/com/trustchex/reactnativesdk/TrustchexSDKPackage.kt +0 -13
- package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraManager.kt +0 -8
- package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraView.kt +60 -39
- package/android/src/main/java/com/trustchex/reactnativesdk/opencv/OpenCVModule.kt +94 -13
- package/ios/Camera/TrustchexCameraManager.m +0 -2
- package/ios/Camera/TrustchexCameraManager.swift +0 -7
- package/ios/Camera/TrustchexCameraView.swift +16 -47
- package/ios/OpenCV/OpenCVHelper.h +17 -0
- package/ios/OpenCV/OpenCVHelper.mm +128 -0
- package/ios/OpenCV/OpenCVModule.h +6 -0
- package/ios/OpenCV/OpenCVModule.mm +141 -0
- package/ios/TrustchexSDK-Bridging-Header.h +8 -0
- package/lib/module/Screens/Debug/MRZTestScreen.js +175 -0
- package/lib/module/Shared/Components/DebugNavigationPanel.js +4 -0
- package/lib/module/Shared/Components/EIDScanner.js +0 -78
- package/lib/module/Shared/Components/IdentityDocumentCamera.js +188 -150
- package/lib/module/Shared/Components/QrCodeScannerCamera.js +0 -3
- package/lib/module/Shared/Libs/mrz.utils.js +265 -0
- package/lib/module/Trustchex.js +4 -0
- package/lib/module/index.js +1 -0
- package/lib/module/version.js +1 -1
- package/lib/typescript/src/Screens/Debug/MRZTestScreen.d.ts +3 -0
- package/lib/typescript/src/Screens/Debug/MRZTestScreen.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Components/DebugNavigationPanel.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/EIDScanner.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts +3 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/QrCodeScannerCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/TrustchexCamera.d.ts +0 -19
- package/lib/typescript/src/Shared/Components/TrustchexCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts +18 -1
- package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts.map +1 -1
- package/lib/typescript/src/Trustchex.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +3 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +2 -1
- package/src/Screens/Debug/MRZTestScreen.tsx +209 -0
- package/src/Shared/Components/DebugNavigationPanel.tsx +5 -0
- package/src/Shared/Components/EIDScanner.tsx +0 -53
- package/src/Shared/Components/IdentityDocumentCamera.tsx +228 -146
- package/src/Shared/Components/QrCodeScannerCamera.tsx +0 -9
- package/src/Shared/Components/TrustchexCamera.tsx +0 -20
- package/src/Shared/Libs/mrz.utils.ts +289 -1
- package/src/Trustchex.tsx +5 -0
- package/src/index.tsx +3 -0
- package/src/version.ts +1 -1
- package/android/src/main/java/com/trustchex/reactnativesdk/mrz/MRZValidationModule.kt +0 -785
- package/android/src/main/java/com/trustchex/reactnativesdk/mrz/MRZValidator.kt +0 -419
- package/ios/MRZValidation.m +0 -39
- package/ios/MRZValidation.swift +0 -802
- package/ios/MRZValidator.swift +0 -466
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import React, { useState, useRef, useCallback } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
StyleSheet,
|
|
5
|
+
Text,
|
|
6
|
+
ScrollView,
|
|
7
|
+
StatusBar,
|
|
8
|
+
TouchableOpacity,
|
|
9
|
+
type NativeSyntheticEvent,
|
|
10
|
+
} from 'react-native';
|
|
11
|
+
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
12
|
+
import {
|
|
13
|
+
TrustchexCamera,
|
|
14
|
+
type TrustchexCameraHandle,
|
|
15
|
+
type Frame,
|
|
16
|
+
} from '../../Shared/Components/TrustchexCamera';
|
|
17
|
+
import mrzUtils from '../../Shared/Libs/mrz.utils';
|
|
18
|
+
|
|
19
|
+
const MRZTestScreen = () => {
|
|
20
|
+
const cameraRef = useRef<TrustchexCameraHandle>(null);
|
|
21
|
+
const [mrzText, setMrzText] = useState<string>('Waiting for MRZ...');
|
|
22
|
+
const [mrzRawText, setMrzRawText] = useState<string>('');
|
|
23
|
+
const [mrzValid, setMrzValid] = useState<boolean>(false);
|
|
24
|
+
const [rawHistory, setRawHistory] = useState<string[]>([]);
|
|
25
|
+
const [isPaused, setIsPaused] = useState<boolean>(false);
|
|
26
|
+
|
|
27
|
+
const handleFrame = useCallback(
|
|
28
|
+
(event: NativeSyntheticEvent<{ frame: Frame }>) => {
|
|
29
|
+
if (isPaused) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const frame = event.nativeEvent.frame;
|
|
34
|
+
|
|
35
|
+
if (frame.resultText) {
|
|
36
|
+
setRawHistory((prev) => {
|
|
37
|
+
if (prev[0] === frame.resultText) {
|
|
38
|
+
return prev;
|
|
39
|
+
}
|
|
40
|
+
const next = [frame.resultText, ...prev];
|
|
41
|
+
return next.slice(0, 20);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (frame.resultText && frame.resultText.includes('<')) {
|
|
46
|
+
// Extract MRZ-only text from detected blocks
|
|
47
|
+
let mrzOnlyText = '';
|
|
48
|
+
if (frame.textBlocks && frame.textBlocks.length > 0) {
|
|
49
|
+
// Filter blocks that look like MRZ (contain < and are in bottom half of frame)
|
|
50
|
+
const frameHeight = frame.height;
|
|
51
|
+
const bottomThreshold = frameHeight * 0.5;
|
|
52
|
+
|
|
53
|
+
const mrzBlocks = frame.textBlocks.filter((block) => {
|
|
54
|
+
const blockText = block.text || '';
|
|
55
|
+
const hasFillers = blockText.includes('<');
|
|
56
|
+
const isInBottomArea = block.blockFrame
|
|
57
|
+
? block.blockFrame.y > bottomThreshold
|
|
58
|
+
: false;
|
|
59
|
+
const isLongEnough = blockText.length >= 12;
|
|
60
|
+
return hasFillers && isInBottomArea && isLongEnough;
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
if (mrzBlocks.length > 0) {
|
|
64
|
+
mrzOnlyText = mrzBlocks.map((b) => b.text).join('\n');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Fallback to full text if no MRZ blocks detected
|
|
69
|
+
if (!mrzOnlyText) {
|
|
70
|
+
mrzOnlyText = frame.resultText;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const fixedMrz = mrzUtils.fixMRZ(mrzOnlyText);
|
|
74
|
+
setMrzRawText(mrzOnlyText);
|
|
75
|
+
setMrzText(fixedMrz);
|
|
76
|
+
setMrzValid(mrzUtils.validateMRZWithCorrections(fixedMrz).valid);
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
[isPaused]
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<View style={styles.container}>
|
|
84
|
+
<StatusBar
|
|
85
|
+
barStyle="light-content"
|
|
86
|
+
backgroundColor="transparent"
|
|
87
|
+
translucent
|
|
88
|
+
/>
|
|
89
|
+
<TrustchexCamera
|
|
90
|
+
ref={cameraRef}
|
|
91
|
+
style={styles.camera}
|
|
92
|
+
cameraType="back"
|
|
93
|
+
enableFrameProcessing={true}
|
|
94
|
+
enableFaceDetection={false}
|
|
95
|
+
enableTextRecognition={true}
|
|
96
|
+
enableBarcodeScanning={false}
|
|
97
|
+
includeBase64={false}
|
|
98
|
+
targetFps={10}
|
|
99
|
+
onFrameAvailable={handleFrame}
|
|
100
|
+
/>
|
|
101
|
+
|
|
102
|
+
<SafeAreaView style={styles.mrzPanel} edges={['bottom']}>
|
|
103
|
+
<ScrollView style={styles.scrollView}>
|
|
104
|
+
<View style={styles.panelContent}>
|
|
105
|
+
<TouchableOpacity
|
|
106
|
+
style={styles.pauseButton}
|
|
107
|
+
onPress={() => setIsPaused(!isPaused)}
|
|
108
|
+
>
|
|
109
|
+
<Text style={styles.pauseButtonText}>
|
|
110
|
+
{isPaused ? 'Resume Processing' : 'Pause Processing'}
|
|
111
|
+
</Text>
|
|
112
|
+
</TouchableOpacity>
|
|
113
|
+
<Text style={styles.title}>MRZ Text Read</Text>
|
|
114
|
+
<Text style={styles.sectionTitle}>MRZ Raw Text</Text>
|
|
115
|
+
<Text style={styles.mrzText}>
|
|
116
|
+
{mrzRawText
|
|
117
|
+
? mrzRawText
|
|
118
|
+
.split('\n')
|
|
119
|
+
.map(
|
|
120
|
+
(line, i) =>
|
|
121
|
+
`Line ${i + 1}: ${line} (${line.length} chars)`
|
|
122
|
+
)
|
|
123
|
+
.join('\n')
|
|
124
|
+
: 'No MRZ raw text'}
|
|
125
|
+
</Text>
|
|
126
|
+
<Text style={styles.sectionTitle}>MRZ Corrected Text</Text>
|
|
127
|
+
<Text style={[styles.mrzText, mrzValid ? styles.mrzValid : null]}>
|
|
128
|
+
{mrzText
|
|
129
|
+
.split('\n')
|
|
130
|
+
.map(
|
|
131
|
+
(line, i) => `Line ${i + 1}: ${line} (${line.length} chars)`
|
|
132
|
+
)
|
|
133
|
+
.join('\n')}
|
|
134
|
+
</Text>
|
|
135
|
+
<Text style={styles.sectionTitle}>Raw Text History</Text>
|
|
136
|
+
<Text style={styles.mrzText}>
|
|
137
|
+
{rawHistory.length > 0
|
|
138
|
+
? rawHistory
|
|
139
|
+
.map((text, i) => `#${i + 1}: ${text.replace(/\n/g, ' ')}`)
|
|
140
|
+
.join('\n')
|
|
141
|
+
: 'No history'}
|
|
142
|
+
</Text>
|
|
143
|
+
</View>
|
|
144
|
+
</ScrollView>
|
|
145
|
+
</SafeAreaView>
|
|
146
|
+
</View>
|
|
147
|
+
);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const styles = StyleSheet.create({
|
|
151
|
+
container: {
|
|
152
|
+
flex: 1,
|
|
153
|
+
backgroundColor: '#000000',
|
|
154
|
+
},
|
|
155
|
+
camera: {
|
|
156
|
+
flex: 2,
|
|
157
|
+
},
|
|
158
|
+
mrzPanel: {
|
|
159
|
+
flex: 1,
|
|
160
|
+
backgroundColor: 'rgba(0, 0, 0, 0.95)',
|
|
161
|
+
borderTopWidth: 2,
|
|
162
|
+
borderTopColor: '#FFA500',
|
|
163
|
+
},
|
|
164
|
+
scrollView: {
|
|
165
|
+
flex: 1,
|
|
166
|
+
},
|
|
167
|
+
panelContent: {
|
|
168
|
+
padding: 10,
|
|
169
|
+
},
|
|
170
|
+
pauseButton: {
|
|
171
|
+
alignSelf: 'center',
|
|
172
|
+
borderWidth: 1,
|
|
173
|
+
borderColor: '#FFA500',
|
|
174
|
+
borderRadius: 4,
|
|
175
|
+
paddingVertical: 6,
|
|
176
|
+
paddingHorizontal: 12,
|
|
177
|
+
marginBottom: 8,
|
|
178
|
+
},
|
|
179
|
+
pauseButtonText: {
|
|
180
|
+
color: '#FFA500',
|
|
181
|
+
fontSize: 10,
|
|
182
|
+
fontWeight: 'bold',
|
|
183
|
+
},
|
|
184
|
+
title: {
|
|
185
|
+
color: '#FFA500',
|
|
186
|
+
fontSize: 12,
|
|
187
|
+
fontWeight: 'bold',
|
|
188
|
+
marginBottom: 8,
|
|
189
|
+
textAlign: 'center',
|
|
190
|
+
},
|
|
191
|
+
sectionTitle: {
|
|
192
|
+
color: '#FFA500',
|
|
193
|
+
fontSize: 10,
|
|
194
|
+
fontWeight: 'bold',
|
|
195
|
+
marginTop: 6,
|
|
196
|
+
marginBottom: 4,
|
|
197
|
+
},
|
|
198
|
+
mrzText: {
|
|
199
|
+
color: '#FFFFFF',
|
|
200
|
+
fontSize: 9,
|
|
201
|
+
fontFamily: 'monospace',
|
|
202
|
+
lineHeight: 16,
|
|
203
|
+
},
|
|
204
|
+
mrzValid: {
|
|
205
|
+
color: '#00C853',
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
export default MRZTestScreen;
|
|
@@ -13,7 +13,6 @@ import StyledButton from './StyledButton';
|
|
|
13
13
|
import LottieView from 'lottie-react-native';
|
|
14
14
|
import { useKeepAwake } from '../Libs/native-keep-awake.utils';
|
|
15
15
|
import { speak, resetLastMessage } from '../Libs/tts.utils';
|
|
16
|
-
import { isDebugEnabled } from '../Libs/debug.utils';
|
|
17
16
|
import {
|
|
18
17
|
trackEIDScanStart,
|
|
19
18
|
trackEIDScanComplete,
|
|
@@ -618,58 +617,6 @@ const EIDScanner = ({
|
|
|
618
617
|
</StyledButton>
|
|
619
618
|
</View>
|
|
620
619
|
)}
|
|
621
|
-
|
|
622
|
-
{isDebugEnabled() && (
|
|
623
|
-
<View
|
|
624
|
-
style={{
|
|
625
|
-
position: 'absolute',
|
|
626
|
-
top: insets.top + 10,
|
|
627
|
-
right: 10,
|
|
628
|
-
backgroundColor: 'rgba(0, 0, 0, 0.85)',
|
|
629
|
-
padding: 10,
|
|
630
|
-
borderRadius: 8,
|
|
631
|
-
borderWidth: 1,
|
|
632
|
-
borderColor: '#FF6B6B',
|
|
633
|
-
maxWidth: 200,
|
|
634
|
-
zIndex: 1001,
|
|
635
|
-
}}
|
|
636
|
-
>
|
|
637
|
-
<Text
|
|
638
|
-
style={{
|
|
639
|
-
color: '#FF6B6B',
|
|
640
|
-
fontSize: 11,
|
|
641
|
-
fontWeight: 'bold',
|
|
642
|
-
marginBottom: 6,
|
|
643
|
-
}}
|
|
644
|
-
>
|
|
645
|
-
🐛 DEBUG MODE
|
|
646
|
-
</Text>
|
|
647
|
-
<Text style={{ color: '#88D8B0', fontSize: 9, marginBottom: 2 }}>
|
|
648
|
-
{`NFC: ${hasNfc ? '✓' : '✗'}`}
|
|
649
|
-
</Text>
|
|
650
|
-
<Text style={{ color: '#88D8B0', fontSize: 9, marginBottom: 2 }}>
|
|
651
|
-
{`Enabled: ${isEnabled ? '✓' : '✗'}`}
|
|
652
|
-
</Text>
|
|
653
|
-
<Text style={{ color: '#88D8B0', fontSize: 9, marginBottom: 2 }}>
|
|
654
|
-
{`Scanning: ${isScanning ? '✓' : '○'}`}
|
|
655
|
-
</Text>
|
|
656
|
-
<Text style={{ color: '#88D8B0', fontSize: 9, marginBottom: 2 }}>
|
|
657
|
-
{`Scanned: ${isScanned ? '✓' : '○'}`}
|
|
658
|
-
</Text>
|
|
659
|
-
<Text style={{ color: '#88D8B0', fontSize: 9, marginBottom: 2 }}>
|
|
660
|
-
{`Progress: ${Math.round(progress)}%`}
|
|
661
|
-
</Text>
|
|
662
|
-
<Text style={{ color: '#88D8B0', fontSize: 9, marginBottom: 2 }}>
|
|
663
|
-
{`Face Image: ${documentFaceImage ? '✓' : '✗'}`}
|
|
664
|
-
</Text>
|
|
665
|
-
<Text style={{ color: '#88D8B0', fontSize: 9, marginBottom: 2 }}>
|
|
666
|
-
{`MRZ Info: ${documentMRZInfo ? '✓' : '✗'}`}
|
|
667
|
-
</Text>
|
|
668
|
-
<Text style={{ color: '#88D8B0', fontSize: 9 }}>
|
|
669
|
-
{`Doc Type: ${documentType}`}
|
|
670
|
-
</Text>
|
|
671
|
-
</View>
|
|
672
|
-
)}
|
|
673
620
|
</>
|
|
674
621
|
)}
|
|
675
622
|
</View>
|