@sanctum-key/react-native-sdk 1.0.53 → 1.0.54
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/README.md +7 -2
- package/android/build/.transforms/3db9b15041d4285a820fc84462995ea1/results.bin +1 -0
- package/android/build/.transforms/3db9b15041d4285a820fc84462995ea1/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +1 -1
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/SanctumKeySdkModule$BarcodeRegion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/SanctumKeySdkModule$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$1$5$1.class → SanctumKeySdkModule$definition$1$6$1.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$1$5$2.class → SanctumKeySdkModule$definition$1$6$2.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunction$1.class → SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunction$1.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunction$5.class → SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunction$2.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunction$3.class → SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunction$3.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunction$4.class → SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunction$4.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunction$2.class → SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunction$5.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunction$6.class → SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunction$6.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunctionWithPromise$1.class → SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunctionWithPromise$1.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunctionWithPromise$3.class → SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunctionWithPromise$2.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunctionWithPromise$3.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunctionWithPromise$4.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunctionWithPromise$2.class → SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunctionWithPromise$5.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunctionWithPromise$6.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$5$$inlined$AsyncFunctionWithPromise$4.class → SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunctionWithPromise$7.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$5$$inlined$View$1.class → SanctumKeySdkModule$definition$lambda$16$$inlined$View$1.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$5$lambda$4$$inlined$Prop$1.class → SanctumKeySdkModule$definition$lambda$16$lambda$15$$inlined$Prop$1.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$5$lambda$4$$inlined$Prop$2.class → SanctumKeySdkModule$definition$lambda$16$lambda$15$$inlined$Prop$2.class} +0 -0
- package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/SanctumKeySdkModule.class +0 -0
- package/android/build.gradle +7 -0
- package/android/src/main/java/kyc/sanctumkey/com/SanctumKeySdkModule.kt +428 -1
- package/build/package.json +1 -1
- package/build/src/SanctumKeySdkModule.d.ts +1 -0
- package/build/src/SanctumKeySdkModule.d.ts.map +1 -1
- package/build/src/SanctumKeySdkModule.js.map +1 -1
- package/build/src/components/EnhancedCameraView.d.ts.map +1 -1
- package/build/src/components/EnhancedCameraView.js +50 -41
- package/build/src/components/EnhancedCameraView.js.map +1 -1
- package/build/src/components/EnhancedCameraView.web.d.ts +2 -0
- package/build/src/components/EnhancedCameraView.web.d.ts.map +1 -1
- package/build/src/components/EnhancedCameraView.web.js +11 -6
- package/build/src/components/EnhancedCameraView.web.js.map +1 -1
- package/build/src/components/KYCElements/IDCardCapture.d.ts.map +1 -1
- package/build/src/components/KYCElements/IDCardCapture.js +499 -78
- package/build/src/components/KYCElements/IDCardCapture.js.map +1 -1
- package/build/src/components/TemplateKYCExample.d.ts.map +1 -1
- package/build/src/components/TemplateKYCExample.js +3 -9
- package/build/src/components/TemplateKYCExample.js.map +1 -1
- package/build/src/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
- package/build/src/components/TemplateKYCFlowRefactored.js +0 -2
- package/build/src/components/TemplateKYCFlowRefactored.js.map +1 -1
- package/build/src/components/WebBarcodeScanner.d.ts +2 -0
- package/build/src/components/WebBarcodeScanner.d.ts.map +1 -1
- package/build/src/components/WebBarcodeScanner.js +99 -85
- package/build/src/components/WebBarcodeScanner.js.map +1 -1
- package/build/src/modules/api/KYCService.d.ts +1 -0
- package/build/src/modules/api/KYCService.d.ts.map +1 -1
- package/build/src/modules/api/KYCService.js +1 -1
- package/build/src/modules/api/KYCService.js.map +1 -1
- package/build/src/modules/api/types.d.ts +1 -0
- package/build/src/modules/api/types.d.ts.map +1 -1
- package/build/src/modules/api/types.js.map +1 -1
- package/package.json +1 -1
- package/plugin/build/withVisionCamera.d.ts +1 -0
- package/plugin/build/withVisionCamera.js +13 -1
- package/plugin/src/withVisionCamera.js +18 -2
- package/plugin/src/withVisionCamera.ts +19 -2
- package/src/SanctumKeySdkModule.ts +1 -0
- package/src/components/EnhancedCameraView.tsx +52 -41
- package/src/components/EnhancedCameraView.web.tsx +15 -5
- package/src/components/KYCElements/IDCardCapture.tsx +552 -75
- package/src/components/TemplateKYCExample.tsx +6 -14
- package/src/components/TemplateKYCFlowRefactored.tsx +0 -2
- package/src/components/WebBarcodeScanner.tsx +147 -198
- package/src/modules/api/KYCService.ts +3 -3
- package/src/modules/api/types.ts +1 -0
|
@@ -22,6 +22,7 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
22
22
|
silentCaptureResult,
|
|
23
23
|
isProcessing = false,
|
|
24
24
|
overlayComponent,
|
|
25
|
+
captureStabilizationDelayMs = 4000,
|
|
25
26
|
isScanningBarcode = false,
|
|
26
27
|
onBarcodeScanned,
|
|
27
28
|
barcodeTypes
|
|
@@ -32,6 +33,8 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
32
33
|
|
|
33
34
|
const isCapturingRef = useRef(false);
|
|
34
35
|
const isProcessingRef = useRef(isProcessing);
|
|
36
|
+
const isScanningBarcodeRef = useRef(isScanningBarcode);
|
|
37
|
+
const onBarcodeScannedRef = useRef(onBarcodeScanned);
|
|
35
38
|
// Ref-tracked isAnalyzing so captureSilentPhoto always reads the latest
|
|
36
39
|
// value — the prop-based closure goes stale on iOS between renders.
|
|
37
40
|
const isAnalyzingRef = useRef(silentCaptureResult?.isAnalyzing ?? false);
|
|
@@ -42,7 +45,7 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
42
45
|
const [refreshCamera] = useState(false);
|
|
43
46
|
|
|
44
47
|
const [isVideoFound, setIsVideoFound] = useState(false);
|
|
45
|
-
const scannedBarcodeRef = useRef<string | null>(null);
|
|
48
|
+
const scannedBarcodeRef = useRef<{ value: string | null; emittedAt: number }>({ value: null, emittedAt: 0 });
|
|
46
49
|
const containerRef = useRef<any>(null);
|
|
47
50
|
|
|
48
51
|
const [appState, setAppState] = useState<AppStateStatus>(AppState.currentState);
|
|
@@ -50,8 +53,14 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
50
53
|
const device = useCameraDevice(cameraType);
|
|
51
54
|
|
|
52
55
|
useEffect(() => { isProcessingRef.current = isProcessing; }, [isProcessing]);
|
|
56
|
+
useEffect(() => { isScanningBarcodeRef.current = isScanningBarcode; }, [isScanningBarcode]);
|
|
57
|
+
useEffect(() => { onBarcodeScannedRef.current = onBarcodeScanned; }, [onBarcodeScanned]);
|
|
53
58
|
useEffect(() => { isAnalyzingRef.current = silentCaptureResult?.isAnalyzing ?? false; }, [silentCaptureResult?.isAnalyzing]);
|
|
54
59
|
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
scannedBarcodeRef.current = { value: null, emittedAt: 0 };
|
|
62
|
+
}, [isScanningBarcode]);
|
|
63
|
+
|
|
55
64
|
useEffect(() => {
|
|
56
65
|
const subscription = AppState.addEventListener('change', nextAppState => {
|
|
57
66
|
setAppState(nextAppState);
|
|
@@ -100,7 +109,12 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
100
109
|
if (showCamera) checkPermissions();
|
|
101
110
|
}, [showCamera, refreshCamera]);
|
|
102
111
|
|
|
103
|
-
const onInitialized = useCallback(() =>
|
|
112
|
+
const onInitialized = useCallback(() => {
|
|
113
|
+
setIsInitialized(true);
|
|
114
|
+
if (isScanningBarcodeRef.current) {
|
|
115
|
+
console.log('📷 Barcode camera initialized');
|
|
116
|
+
}
|
|
117
|
+
}, []);
|
|
104
118
|
|
|
105
119
|
const onCameraError = useCallback((error: any) => {
|
|
106
120
|
console.warn("🎥 [Vision Camera Error Caught]:", error);
|
|
@@ -114,11 +128,15 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
114
128
|
const codeScanner = useCodeScanner({
|
|
115
129
|
codeTypes: barcodeTypes || ['pdf-417', 'qr', 'code-128', 'code-39'],
|
|
116
130
|
onCodeScanned: (codes) => {
|
|
117
|
-
if (!isProcessingRef.current &&
|
|
131
|
+
if (!isProcessingRef.current && isScanningBarcodeRef.current) {
|
|
118
132
|
for (const code of codes) {
|
|
119
|
-
if (code.value
|
|
120
|
-
|
|
121
|
-
|
|
133
|
+
if (!code.value) continue;
|
|
134
|
+
|
|
135
|
+
const now = Date.now();
|
|
136
|
+
const previous = scannedBarcodeRef.current;
|
|
137
|
+
if (previous.value !== code.value || now - previous.emittedAt > 1500) {
|
|
138
|
+
scannedBarcodeRef.current = { value: code.value, emittedAt: now };
|
|
139
|
+
onBarcodeScannedRef.current?.(code.value);
|
|
122
140
|
break;
|
|
123
141
|
}
|
|
124
142
|
}
|
|
@@ -137,8 +155,8 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
137
155
|
// Web handles its own stream via WebBarcodeScanner; do not run native camera methods on web.
|
|
138
156
|
if (Platform.OS === 'web') return;
|
|
139
157
|
|
|
140
|
-
//
|
|
141
|
-
//
|
|
158
|
+
// The scheduling effect waits for camera initialization and a positioning
|
|
159
|
+
// grace period before this function can run.
|
|
142
160
|
if (!camera.current || isProcessingRef.current || isCapturingRef.current) return;
|
|
143
161
|
if (isAnalyzingRef.current) return;
|
|
144
162
|
|
|
@@ -148,8 +166,14 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
148
166
|
const photo = await camera.current.takePhoto({
|
|
149
167
|
enableShutterSound: false,
|
|
150
168
|
flash: 'off',
|
|
151
|
-
|
|
152
|
-
|
|
169
|
+
...(Platform.OS === 'ios'
|
|
170
|
+
? {
|
|
171
|
+
photoCodec: 'jpeg' as const,
|
|
172
|
+
// Barcode stills are decoded off the live path, so preserve the
|
|
173
|
+
// fine PDF417 modules instead of favoring capture speed.
|
|
174
|
+
qualityPrioritization: isScanningBarcodeRef.current ? 'quality' as const : 'balanced' as const,
|
|
175
|
+
}
|
|
176
|
+
: {})
|
|
153
177
|
});
|
|
154
178
|
|
|
155
179
|
// 3. CROSS-PLATFORM PATH NORMALIZATION
|
|
@@ -172,7 +196,7 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
172
196
|
onSilentCaptureRef.current?.({
|
|
173
197
|
success: captureSuccess,
|
|
174
198
|
path: finalPath,
|
|
175
|
-
barcode: scannedBarcodeRef.current
|
|
199
|
+
barcode: scannedBarcodeRef.current.value
|
|
176
200
|
});
|
|
177
201
|
|
|
178
202
|
} catch (error: any) {
|
|
@@ -185,45 +209,26 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
185
209
|
|
|
186
210
|
// 5. THE UNBREAKABLE INTERVAL
|
|
187
211
|
useEffect(() => {
|
|
188
|
-
//
|
|
189
|
-
//
|
|
190
|
-
|
|
191
|
-
if (!showCamera || isProcessing || Platform.OS === 'web') return;
|
|
212
|
+
// Give autofocus/exposure and the user time to settle before the first
|
|
213
|
+
// automatic capture. A remount creates a fresh grace period for each side.
|
|
214
|
+
if (!showCamera || !isInitialized || isProcessing || Platform.OS === 'web') return;
|
|
192
215
|
|
|
193
216
|
let active = true;
|
|
194
217
|
let id: ReturnType<typeof setInterval>;
|
|
195
218
|
|
|
196
219
|
const timer = setTimeout(() => {
|
|
197
220
|
if (!active) return;
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}, 1500);
|
|
201
|
-
|
|
202
|
-
return () => {
|
|
203
|
-
active = false;
|
|
204
|
-
clearTimeout(timer);
|
|
205
|
-
if (id) clearInterval(id);
|
|
206
|
-
};
|
|
207
|
-
}, [showCamera, isProcessing, isScanningBarcode, captureSilentPhoto]);
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
useEffect(() => {
|
|
211
|
-
if (!showCamera || !isInitialized || isProcessing) return;
|
|
212
|
-
let active = true;
|
|
213
|
-
let id: ReturnType<typeof setInterval>;
|
|
214
|
-
|
|
215
|
-
const timer = setTimeout(() => {
|
|
216
|
-
if (!active) return;
|
|
217
|
-
const intervalDelay = isScanningBarcode ? 3000 : 1500;
|
|
221
|
+
captureSilentPhoto();
|
|
222
|
+
const intervalDelay = isScanningBarcode ? 4500 : 3000;
|
|
218
223
|
id = setInterval(captureSilentPhoto, intervalDelay);
|
|
219
|
-
},
|
|
224
|
+
}, Math.max(0, captureStabilizationDelayMs));
|
|
220
225
|
|
|
221
226
|
return () => {
|
|
222
227
|
active = false;
|
|
223
228
|
clearTimeout(timer);
|
|
224
229
|
if (id) clearInterval(id);
|
|
225
230
|
};
|
|
226
|
-
}, [showCamera, isInitialized, isProcessing,
|
|
231
|
+
}, [showCamera, isInitialized, isProcessing, isScanningBarcode, captureStabilizationDelayMs, captureSilentPhoto]);
|
|
227
232
|
|
|
228
233
|
useEffect(() => {
|
|
229
234
|
if (Platform.OS !== 'web' || !showCamera) return;
|
|
@@ -252,8 +257,8 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
252
257
|
}, [showCamera]);
|
|
253
258
|
|
|
254
259
|
const handleWebBarcodeScanned = useCallback((value: string) => {
|
|
255
|
-
if (!isProcessingRef.current && value !== scannedBarcodeRef.current) {
|
|
256
|
-
scannedBarcodeRef.current = value;
|
|
260
|
+
if (!isProcessingRef.current && value !== scannedBarcodeRef.current.value) {
|
|
261
|
+
scannedBarcodeRef.current = { value, emittedAt: Date.now() };
|
|
257
262
|
onBarcodeScanned?.(value);
|
|
258
263
|
}
|
|
259
264
|
}, [onBarcodeScanned]);
|
|
@@ -291,16 +296,22 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
291
296
|
resizeMode="cover"
|
|
292
297
|
isActive={showCamera && !isProcessing && appState === 'active'}
|
|
293
298
|
photo={true}
|
|
299
|
+
photoQualityBalance={isScanningBarcode ? 'quality' : 'balanced'}
|
|
294
300
|
video={false}
|
|
295
301
|
audio={false}
|
|
296
302
|
onInitialized={onInitialized}
|
|
297
303
|
onError={onCameraError}
|
|
298
|
-
|
|
304
|
+
// Some Android camera levels cannot configure Preview + ImageCapture +
|
|
305
|
+
// ImageAnalysis together and fail with invalid-output-configuration.
|
|
306
|
+
// Android barcodes use the bundled full-resolution ML Kit/ZXing still
|
|
307
|
+
// decoder; iOS can retain Vision Camera's low-latency live scanner.
|
|
308
|
+
codeScanner={Platform.OS === 'ios' && isScanningBarcode ? codeScanner : undefined}
|
|
299
309
|
/>
|
|
300
310
|
{Platform.OS === 'web' && isScanningBarcode && isVideoFound && (
|
|
301
311
|
<WebBarcodeScanner
|
|
302
312
|
videoRef={webVideoRef as React.RefObject<HTMLVideoElement>}
|
|
303
313
|
onBarcodeScanned={handleWebBarcodeScanned}
|
|
314
|
+
formats={barcodeTypes}
|
|
304
315
|
active={!isProcessingRef.current}
|
|
305
316
|
/>
|
|
306
317
|
)}
|
|
@@ -312,4 +323,4 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
312
323
|
const styles = StyleSheet.create({
|
|
313
324
|
container: { flex: 1, backgroundColor: 'black' },
|
|
314
325
|
permissionMessage: { color: 'white', textAlign: 'center', margin: 20, fontSize: 16 },
|
|
315
|
-
});
|
|
326
|
+
});
|
|
@@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
|
2
2
|
import { View, StyleSheet, TouchableOpacity, Text, Platform } from 'react-native';
|
|
3
3
|
import { EnhancedCameraViewProps } from './OverLay/type';
|
|
4
4
|
import { useI18n } from '../hooks/useI18n';
|
|
5
|
+
import type { CodeType } from 'react-native-vision-camera';
|
|
5
6
|
// 🚨 Import the WebBarcodeScanner we built earlier
|
|
6
7
|
import { WebBarcodeScanner } from './WebBarcodeScanner';
|
|
7
8
|
|
|
@@ -9,6 +10,7 @@ import { WebBarcodeScanner } from './WebBarcodeScanner';
|
|
|
9
10
|
export interface ExtendedCameraProps extends EnhancedCameraViewProps {
|
|
10
11
|
isScanningBarcode?: boolean;
|
|
11
12
|
onBarcodeScanned?: (data: string) => void;
|
|
13
|
+
barcodeTypes?: CodeType[];
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
@@ -34,10 +36,11 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
34
36
|
videoDuration = 10,
|
|
35
37
|
onSilentCapture,
|
|
36
38
|
silentCaptureResult,
|
|
37
|
-
captureStabilizationDelayMs =
|
|
39
|
+
captureStabilizationDelayMs = 4000,
|
|
38
40
|
// 🚨 New props for barcode support
|
|
39
41
|
isScanningBarcode = false,
|
|
40
42
|
onBarcodeScanned,
|
|
43
|
+
barcodeTypes,
|
|
41
44
|
}) => {
|
|
42
45
|
const { t } = useI18n();
|
|
43
46
|
|
|
@@ -61,12 +64,16 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
61
64
|
|
|
62
65
|
// 🚨 New Refs for Barcode Logic
|
|
63
66
|
const isProcessingRef = useRef(silentCaptureResult?.isAnalyzing || false);
|
|
64
|
-
const scannedBarcodeRef = useRef<string | null>(null);
|
|
67
|
+
const scannedBarcodeRef = useRef<{ value: string | null; emittedAt: number }>({ value: null, emittedAt: 0 });
|
|
65
68
|
|
|
66
69
|
useEffect(() => {
|
|
67
70
|
isProcessingRef.current = silentCaptureResult?.isAnalyzing || false;
|
|
68
71
|
}, [silentCaptureResult?.isAnalyzing]);
|
|
69
72
|
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
scannedBarcodeRef.current = { value: null, emittedAt: 0 };
|
|
75
|
+
}, [isScanningBarcode]);
|
|
76
|
+
|
|
70
77
|
useEffect(() => {
|
|
71
78
|
if (showCamera) {
|
|
72
79
|
checkPermissions();
|
|
@@ -223,8 +230,10 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
223
230
|
// 🚨 Memoized Callback for Barcode Decoding
|
|
224
231
|
const handleWebBarcodeScanned = useCallback((value: string) => {
|
|
225
232
|
console.log(`🎉 [WEB SCANNER] SUCCESS! Decoded value:`, value);
|
|
226
|
-
|
|
227
|
-
|
|
233
|
+
const now = Date.now();
|
|
234
|
+
const previous = scannedBarcodeRef.current;
|
|
235
|
+
if (!isProcessingRef.current && (value !== previous.value || now - previous.emittedAt > 1500)) {
|
|
236
|
+
scannedBarcodeRef.current = { value, emittedAt: now };
|
|
228
237
|
onBarcodeScanned?.(value);
|
|
229
238
|
}
|
|
230
239
|
}, [onBarcodeScanned]);
|
|
@@ -289,6 +298,7 @@ export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
|
289
298
|
<WebBarcodeScanner
|
|
290
299
|
videoRef={videoRef}
|
|
291
300
|
onBarcodeScanned={handleWebBarcodeScanned}
|
|
301
|
+
formats={barcodeTypes}
|
|
292
302
|
// Use silentCaptureResult.isAnalyzing (state) not the ref so
|
|
293
303
|
// React re-renders with the correct active value
|
|
294
304
|
active={isScanningBarcode && isInitialized && !(silentCaptureResult?.isAnalyzing ?? false)}
|
|
@@ -354,4 +364,4 @@ const styles = StyleSheet.create({
|
|
|
354
364
|
bbox: { position: 'absolute', borderStyle: 'solid', backgroundColor: 'transparent' },
|
|
355
365
|
analyzingContainer: { position: 'absolute', bottom: 100, alignSelf: 'center', backgroundColor: 'rgba(0, 0, 0, 0.7)', padding: 10, borderRadius: 10, zIndex: 1000 },
|
|
356
366
|
analyzingText: { color: 'white', fontSize: 16, fontWeight: 'bold' },
|
|
357
|
-
});
|
|
367
|
+
});
|