@sanctum-key/react-native-sdk 1.0.13 → 1.0.15
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/build/package.json +1 -1
- package/build/src/components/EnhancedCameraView.d.ts.map +1 -1
- package/build/src/components/EnhancedCameraView.js +148 -8
- package/build/src/components/EnhancedCameraView.js.map +1 -1
- package/build/src/components/KYCElements/IDCardCapture.d.ts.map +1 -1
- package/build/src/components/KYCElements/IDCardCapture.js +168 -115
- package/build/src/components/KYCElements/IDCardCapture.js.map +1 -1
- package/build/src/utils/cropByObb.d.ts +0 -12
- package/build/src/utils/cropByObb.d.ts.map +1 -1
- package/build/src/utils/cropByObb.js +73 -98
- package/build/src/utils/cropByObb.js.map +1 -1
- package/package.json +1 -1
- package/src/components/EnhancedCameraView.tsx +190 -33
- package/src/components/KYCElements/IDCardCapture.tsx +253 -182
- package/src/utils/cropByObb.ts +90 -127
package/build/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnhancedCameraView.d.ts","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EnhancedCameraView.d.ts","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"AAuKA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAGzD,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA2IhE,CAAC"}
|
|
@@ -1,3 +1,146 @@
|
|
|
1
|
+
// import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
// import { View, StyleSheet, Text, AppState } from 'react-native';
|
|
3
|
+
// import { Camera, useCameraDevice, useCameraFormat } from 'react-native-vision-camera';
|
|
4
|
+
// import VisionCameraModule from '../modules/camera/VisionCameraModule';
|
|
5
|
+
// import { useI18n } from '../hooks/useI18n';
|
|
6
|
+
// import { EnhancedCameraViewProps } from './OverLay/type';
|
|
7
|
+
// import { Button } from './ui/Button';
|
|
8
|
+
// export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
|
|
9
|
+
// showCamera,
|
|
10
|
+
// cameraType: initialCameraType = 'front',
|
|
11
|
+
// style,
|
|
12
|
+
// onError,
|
|
13
|
+
// onSilentCapture,
|
|
14
|
+
// silentCaptureResult,
|
|
15
|
+
// isProcessing = false,
|
|
16
|
+
// overlayComponent,
|
|
17
|
+
// }) => {
|
|
18
|
+
// const { t } = useI18n();
|
|
19
|
+
// const camera = useRef<Camera>(null);
|
|
20
|
+
// const isCapturingRef = useRef(false);
|
|
21
|
+
// const isProcessingRef = useRef(isProcessing);
|
|
22
|
+
// const [cameraType] = useState<'front' | 'back'>(initialCameraType);
|
|
23
|
+
// const [hasPermission, setHasPermission] = useState<boolean | null>(null);
|
|
24
|
+
// const [isInitialized, setIsInitialized] = useState(false);
|
|
25
|
+
// const [refreshCamera, setRefreshCamera] = useState(false);
|
|
26
|
+
// const [layout, setLayout] = useState({ width: 0, height: 0 });
|
|
27
|
+
// const device = useCameraDevice(cameraType, {
|
|
28
|
+
// physicalDevices: [
|
|
29
|
+
// 'wide-angle-camera' // Explicitly request standard 1x lens
|
|
30
|
+
// ]
|
|
31
|
+
// });
|
|
32
|
+
// const targetRatio = layout.width > 0 ? layout.height / layout.width : 16 / 9;
|
|
33
|
+
// const format = useCameraFormat(device, [
|
|
34
|
+
// { photoAspectRatio: targetRatio },
|
|
35
|
+
// { photoResolution: 'max' }
|
|
36
|
+
// ]);
|
|
37
|
+
// useEffect(() => {
|
|
38
|
+
// isProcessingRef.current = isProcessing;
|
|
39
|
+
// }, [isProcessing]);
|
|
40
|
+
// const checkPermissions = async () => {
|
|
41
|
+
// try {
|
|
42
|
+
// const hasAllPermissions = await VisionCameraModule.hasAllPermissions();
|
|
43
|
+
// if (!hasAllPermissions) {
|
|
44
|
+
// const granted = await VisionCameraModule.requestAllPermissions();
|
|
45
|
+
// if (!granted) {
|
|
46
|
+
// setHasPermission(false);
|
|
47
|
+
// onError?.({ message: t('camera.permissionRequired') });
|
|
48
|
+
// return;
|
|
49
|
+
// }
|
|
50
|
+
// }
|
|
51
|
+
// setHasPermission(true);
|
|
52
|
+
// } catch (error) {
|
|
53
|
+
// setHasPermission(false);
|
|
54
|
+
// onError?.({ message: t('camera.errorOccurred') });
|
|
55
|
+
// }
|
|
56
|
+
// };
|
|
57
|
+
// useEffect(() => {
|
|
58
|
+
// if (showCamera) checkPermissions();
|
|
59
|
+
// }, [showCamera, refreshCamera]);
|
|
60
|
+
// useEffect(() => {
|
|
61
|
+
// const subscription = AppState.addEventListener('change', nextAppState => {
|
|
62
|
+
// if (nextAppState === 'active' && showCamera && hasPermission === false) {
|
|
63
|
+
// checkPermissions();
|
|
64
|
+
// }
|
|
65
|
+
// });
|
|
66
|
+
// return () => subscription.remove();
|
|
67
|
+
// }, [showCamera, hasPermission]);
|
|
68
|
+
// const onInitialized = useCallback(() => setIsInitialized(true), []);
|
|
69
|
+
// const onCameraError = useCallback((error: any) => {
|
|
70
|
+
// onError?.({ message: error.message || t('camera.errorOccurred') });
|
|
71
|
+
// }, [onError, t]);
|
|
72
|
+
// const captureSilentPhoto = useCallback(async () => {
|
|
73
|
+
// if (!camera.current || !isInitialized || isProcessingRef.current || isCapturingRef.current) return;
|
|
74
|
+
// if (silentCaptureResult?.isAnalyzing) return;
|
|
75
|
+
// try {
|
|
76
|
+
// isCapturingRef.current = true;
|
|
77
|
+
// const photo = await camera.current.takePhoto({
|
|
78
|
+
// enableShutterSound: false,
|
|
79
|
+
// flash: 'off',
|
|
80
|
+
// });
|
|
81
|
+
// const result = await VisionCameraModule.processPhotoResult(photo);
|
|
82
|
+
// onSilentCapture?.({
|
|
83
|
+
// ...result,
|
|
84
|
+
// path: result.path || photo.path,
|
|
85
|
+
// });
|
|
86
|
+
// } catch (error) {
|
|
87
|
+
// // Silent background fail
|
|
88
|
+
// } finally {
|
|
89
|
+
// isCapturingRef.current = false;
|
|
90
|
+
// }
|
|
91
|
+
// }, [isInitialized, onSilentCapture, silentCaptureResult]);
|
|
92
|
+
// useEffect(() => {
|
|
93
|
+
// if (!showCamera || !isInitialized || isProcessing) return;
|
|
94
|
+
// let isActive = true;
|
|
95
|
+
// let intervalId: ReturnType<typeof setInterval>;
|
|
96
|
+
// const warmupTimer = setTimeout(() => {
|
|
97
|
+
// if (!isActive) return;
|
|
98
|
+
// intervalId = setInterval(() => {
|
|
99
|
+
// captureSilentPhoto();
|
|
100
|
+
// }, 1500);
|
|
101
|
+
// }, 1000);
|
|
102
|
+
// return () => {
|
|
103
|
+
// isActive = false;
|
|
104
|
+
// clearTimeout(warmupTimer);
|
|
105
|
+
// if (intervalId) clearInterval(intervalId);
|
|
106
|
+
// };
|
|
107
|
+
// }, [showCamera, isInitialized, isProcessing, captureSilentPhoto]);
|
|
108
|
+
// if (hasPermission === null) return <View style={[styles.container, style]} />;
|
|
109
|
+
// if (hasPermission === false) {
|
|
110
|
+
// return (
|
|
111
|
+
// <View style={[styles.container, style, { justifyContent: 'center', alignItems: 'center' }]}>
|
|
112
|
+
// <Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>
|
|
113
|
+
// <Button title="Refresh Camera" onPress={() => setRefreshCamera(prev => !prev)} variant="primary" />
|
|
114
|
+
// </View>
|
|
115
|
+
// );
|
|
116
|
+
// }
|
|
117
|
+
// if (!device || !showCamera) return <View style={[styles.container, style]} />;
|
|
118
|
+
// return (
|
|
119
|
+
// <View
|
|
120
|
+
// style={[styles.container, style]}
|
|
121
|
+
// onLayout={(e) => setLayout({ width: e.nativeEvent.layout.width, height: e.nativeEvent.layout.height })}
|
|
122
|
+
// >
|
|
123
|
+
// <Camera
|
|
124
|
+
// ref={camera}
|
|
125
|
+
// style={StyleSheet.absoluteFill}
|
|
126
|
+
// device={device}
|
|
127
|
+
// format={format}
|
|
128
|
+
// resizeMode="cover"
|
|
129
|
+
// isActive={showCamera && !isProcessing}
|
|
130
|
+
// photo={true}
|
|
131
|
+
// video={false}
|
|
132
|
+
// audio={false}
|
|
133
|
+
// onInitialized={onInitialized}
|
|
134
|
+
// onError={onCameraError}
|
|
135
|
+
// />
|
|
136
|
+
// {overlayComponent}
|
|
137
|
+
// </View>
|
|
138
|
+
// );
|
|
139
|
+
// };
|
|
140
|
+
// const styles = StyleSheet.create({
|
|
141
|
+
// container: { flex: 1, backgroundColor: 'black' },
|
|
142
|
+
// permissionMessage: { color: 'white', textAlign: 'center', margin: 20, fontSize: 16 },
|
|
143
|
+
// });
|
|
1
144
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
145
|
import { View, StyleSheet, Text, AppState } from 'react-native';
|
|
3
146
|
import { Camera, useCameraDevice } from 'react-native-vision-camera';
|
|
@@ -10,10 +153,11 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
|
|
|
10
153
|
const isCapturingRef = useRef(false);
|
|
11
154
|
const isProcessingRef = useRef(isProcessing);
|
|
12
155
|
const [cameraType] = useState(initialCameraType);
|
|
13
|
-
// 🚨 BUG FIX: Initialize to null to prevent the "Flicker" on retake
|
|
14
156
|
const [hasPermission, setHasPermission] = useState(null);
|
|
15
157
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
16
158
|
const [refreshCamera, setRefreshCamera] = useState(false);
|
|
159
|
+
// 🚨 THE FIX: Removed the strict physical device filtering and custom format.
|
|
160
|
+
// This allows Android to select its own supported, stable hardware stream, preventing crashes.
|
|
17
161
|
const device = useCameraDevice(cameraType);
|
|
18
162
|
useEffect(() => {
|
|
19
163
|
isProcessingRef.current = isProcessing;
|
|
@@ -76,7 +220,6 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
|
|
|
76
220
|
isCapturingRef.current = false;
|
|
77
221
|
}
|
|
78
222
|
}, [isInitialized, onSilentCapture, silentCaptureResult]);
|
|
79
|
-
// 🚨 BUG FIX: The Warm-up Timer (Fixes Blurry Images)
|
|
80
223
|
useEffect(() => {
|
|
81
224
|
if (!showCamera || !isInitialized || isProcessing)
|
|
82
225
|
return;
|
|
@@ -87,7 +230,7 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
|
|
|
87
230
|
return;
|
|
88
231
|
intervalId = setInterval(() => {
|
|
89
232
|
captureSilentPhoto();
|
|
90
|
-
}, 1500);
|
|
233
|
+
}, 1500);
|
|
91
234
|
}, 1000);
|
|
92
235
|
return () => {
|
|
93
236
|
isActive = false;
|
|
@@ -96,11 +239,8 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
|
|
|
96
239
|
clearInterval(intervalId);
|
|
97
240
|
};
|
|
98
241
|
}, [showCamera, isInitialized, isProcessing, captureSilentPhoto]);
|
|
99
|
-
|
|
100
|
-
// 🚨 BUG FIX: Show nothing while checking permissions (Stops flicker)
|
|
101
|
-
if (hasPermission === null) {
|
|
242
|
+
if (hasPermission === null)
|
|
102
243
|
return <View style={[styles.container, style]}/>;
|
|
103
|
-
}
|
|
104
244
|
if (hasPermission === false) {
|
|
105
245
|
return (<View style={[styles.container, style, { justifyContent: 'center', alignItems: 'center' }]}>
|
|
106
246
|
<Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>
|
|
@@ -110,7 +250,7 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
|
|
|
110
250
|
if (!device || !showCamera)
|
|
111
251
|
return <View style={[styles.container, style]}/>;
|
|
112
252
|
return (<View style={[styles.container, style]}>
|
|
113
|
-
<Camera ref={camera} style={StyleSheet.absoluteFill} device={device} isActive={showCamera && !isProcessing} photo={true} video={false} audio={false} onInitialized={onInitialized} onError={onCameraError}/>
|
|
253
|
+
<Camera ref={camera} style={StyleSheet.absoluteFill} device={device} resizeMode="cover" isActive={showCamera && !isProcessing} photo={true} video={false} audio={false} onInitialized={onInitialized} onError={onCameraError}/>
|
|
114
254
|
{overlayComponent}
|
|
115
255
|
</View>);
|
|
116
256
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnhancedCameraView.js","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,kBAAkB,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,CAAC,MAAM,kBAAkB,GAAsC,CAAC,EACpE,UAAU,EACV,UAAU,EAAE,iBAAiB,GAAG,OAAO,EACvC,KAAK,EACL,OAAO,EACP,eAAe,EACf,mBAAmB,EACnB,YAAY,GAAG,KAAK,EACpB,gBAAgB,GACjB,EAAE,EAAE;IACH,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,MAAM,CAAS,IAAI,CAAC,CAAC;IAEpC,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,eAAe,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IAE7C,MAAM,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAmB,iBAAiB,CAAC,CAAC;IAEnE,oEAAoE;IACpE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAiB,IAAI,CAAC,CAAC;IACzE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1D,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE1D,MAAM,MAAM,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAE3C,SAAS,CAAC,GAAG,EAAE;QACb,eAAe,CAAC,OAAO,GAAG,YAAY,CAAC;IACzC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;QAClC,IAAI,CAAC;YACH,MAAM,iBAAiB,GAAG,MAAM,kBAAkB,CAAC,iBAAiB,EAAE,CAAC;YACvE,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACvB,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,qBAAqB,EAAE,CAAC;gBACjE,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,gBAAgB,CAAC,KAAK,CAAC,CAAC;oBACxB,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,2BAA2B,CAAC,EAAE,CAAC,CAAC;oBACvD,OAAO;gBACT,CAAC;YACH,CAAC;YACD,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gBAAgB,CAAC,KAAK,CAAC,CAAC;YACxB,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,UAAU;YAAE,gBAAgB,EAAE,CAAC;IACrC,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;IAEhC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,YAAY,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE;YACtE,IAAI,YAAY,KAAK,QAAQ,IAAI,UAAU,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;gBACvE,gBAAgB,EAAE,CAAC;YACrB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;IACrC,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;IAEhC,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,KAAU,EAAE,EAAE;QAC/C,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IAEjB,MAAM,kBAAkB,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAChD,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,aAAa,IAAI,eAAe,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO;YAAE,OAAO;QACnG,IAAI,mBAAmB,EAAE,WAAW;YAAE,OAAO;QAE7C,IAAI,CAAC;YACH,cAAc,CAAC,OAAO,GAAG,IAAI,CAAC;YAC9B,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;gBAC3C,kBAAkB,EAAE,KAAK;gBACzB,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAElE,eAAe,EAAE,CAAC;gBACd,GAAG,MAAM;gBACT,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;aAClC,CAAC,CAAC;QAEL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,yBAAyB;QAC3B,CAAC;gBAAS,CAAC;YACT,cAAc,CAAC,OAAO,GAAG,KAAK,CAAC;QACjC,CAAC;IACH,CAAC,EAAE,CAAC,aAAa,EAAE,eAAe,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAE1D,sDAAsD;IACtD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,UAAU,IAAI,CAAC,aAAa,IAAI,YAAY;YAAE,OAAO;QAE1D,IAAI,QAAQ,GAAG,IAAI,CAAC;QACpB,IAAI,UAA0C,CAAC;QAE/C,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,EAAE;YAClC,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACtB,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;gBAC5B,kBAAkB,EAAE,CAAC;YACvB,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,+DAA+D;QAC3E,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,OAAO,GAAG,EAAE;YACV,QAAQ,GAAG,KAAK,CAAC;YACjB,YAAY,CAAC,WAAW,CAAC,CAAC;YAC1B,IAAI,UAAU;gBAAE,aAAa,CAAC,UAAU,CAAC,CAAC;QAC5C,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAElE,oBAAoB;IAEpB,sEAAsE;IACtE,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,EAAG,CAAC;IACpD,CAAC;IAED,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;QAC5B,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,CACzF;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,EAAE,IAAI,CAC7E;QAAA,CAAC,MAAM,CACJ,KAAK,CAAC,gBAAgB,CACtB,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAC/C,OAAO,CAAC,SAAS,EAEtB;MAAA,EAAE,IAAI,CAAC,CACR,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,MAAM,IAAI,CAAC,UAAU;QAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,EAAG,CAAC;IAE9E,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CACrC;MAAA,CAAC,MAAM,CACL,GAAG,CAAC,CAAC,MAAM,CAAC,CACZ,KAAK,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAC/B,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,QAAQ,CAAC,CAAC,UAAU,IAAI,CAAC,YAAY,CAAC,CACtC,KAAK,CAAC,CAAC,IAAI,CAAC,CACZ,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,aAAa,CAAC,CAAC,aAAa,CAAC,CAC7B,OAAO,CAAC,CAAC,aAAa,CAAC,EAEzB;MAAA,CAAC,gBAAgB,CACnB;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/B,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,eAAe,EAAE,OAAO,EAAE;IAChD,iBAAiB,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;CACrF,CAAC,CAAC","sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { View, StyleSheet, Text, AppState } from 'react-native';\nimport { Camera, useCameraDevice } from 'react-native-vision-camera';\nimport VisionCameraModule from '../modules/camera/VisionCameraModule';\nimport { useI18n } from '../hooks/useI18n';\nimport { EnhancedCameraViewProps } from './OverLay/type';\nimport { Button } from './ui/Button';\n\nexport const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({ \n showCamera,\n cameraType: initialCameraType = 'front',\n style,\n onError,\n onSilentCapture, \n silentCaptureResult,\n isProcessing = false, \n overlayComponent,\n}) => {\n const { t } = useI18n();\n const camera = useRef<Camera>(null);\n \n const isCapturingRef = useRef(false);\n const isProcessingRef = useRef(isProcessing);\n\n const [cameraType] = useState<'front' | 'back'>(initialCameraType);\n \n // 🚨 BUG FIX: Initialize to null to prevent the \"Flicker\" on retake\n const [hasPermission, setHasPermission] = useState<boolean | null>(null);\n const [isInitialized, setIsInitialized] = useState(false);\n const [refreshCamera, setRefreshCamera] = useState(false);\n\n const device = useCameraDevice(cameraType);\n\n useEffect(() => {\n isProcessingRef.current = isProcessing;\n }, [isProcessing]);\n\n const checkPermissions = async () => {\n try {\n const hasAllPermissions = await VisionCameraModule.hasAllPermissions();\n if (!hasAllPermissions) {\n const granted = await VisionCameraModule.requestAllPermissions();\n if (!granted) {\n setHasPermission(false);\n onError?.({ message: t('camera.permissionRequired') });\n return;\n }\n }\n setHasPermission(true);\n } catch (error) {\n setHasPermission(false);\n onError?.({ message: t('camera.errorOccurred') });\n }\n };\n\n useEffect(() => {\n if (showCamera) checkPermissions();\n }, [showCamera, refreshCamera]);\n\n useEffect(() => {\n const subscription = AppState.addEventListener('change', nextAppState => {\n if (nextAppState === 'active' && showCamera && hasPermission === false) {\n checkPermissions();\n }\n });\n return () => subscription.remove();\n }, [showCamera, hasPermission]);\n\n const onInitialized = useCallback(() => setIsInitialized(true), []);\n const onCameraError = useCallback((error: any) => {\n onError?.({ message: error.message || t('camera.errorOccurred') });\n }, [onError, t]);\n\n const captureSilentPhoto = useCallback(async () => {\n if (!camera.current || !isInitialized || isProcessingRef.current || isCapturingRef.current) return;\n if (silentCaptureResult?.isAnalyzing) return;\n\n try {\n isCapturingRef.current = true; \n const photo = await camera.current.takePhoto({\n enableShutterSound: false, \n flash: 'off', \n });\n\n const result = await VisionCameraModule.processPhotoResult(photo);\n \n onSilentCapture?.({\n ...result,\n path: result.path || photo.path, \n });\n\n } catch (error) {\n // Silent background fail\n } finally {\n isCapturingRef.current = false; \n }\n }, [isInitialized, onSilentCapture, silentCaptureResult]);\n\n // 🚨 BUG FIX: The Warm-up Timer (Fixes Blurry Images)\n useEffect(() => {\n if (!showCamera || !isInitialized || isProcessing) return;\n \n let isActive = true;\n let intervalId: ReturnType<typeof setInterval>;\n\n const warmupTimer = setTimeout(() => {\n if (!isActive) return;\n intervalId = setInterval(() => {\n captureSilentPhoto();\n }, 1500); // 1.5s gives the hardware more time to stabilize between shots\n }, 1000); \n \n return () => {\n isActive = false;\n clearTimeout(warmupTimer);\n if (intervalId) clearInterval(intervalId);\n };\n }, [showCamera, isInitialized, isProcessing, captureSilentPhoto]);\n\n // --- RENDERERS ---\n \n // 🚨 BUG FIX: Show nothing while checking permissions (Stops flicker)\n if (hasPermission === null) {\n return <View style={[styles.container, style]} />;\n }\n\n if (hasPermission === false) {\n return (\n <View style={[styles.container, style, { justifyContent: 'center', alignItems: 'center' }]}>\n <Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>\n <Button \n title=\"Refresh Camera\" \n onPress={() => setRefreshCamera(prev => !prev)} \n variant=\"primary\"\n />\n </View>\n );\n }\n\n if (!device || !showCamera) return <View style={[styles.container, style]} />;\n\n return (\n <View style={[styles.container, style]}>\n <Camera\n ref={camera}\n style={StyleSheet.absoluteFill}\n device={device}\n isActive={showCamera && !isProcessing}\n photo={true}\n video={false} \n audio={false} \n onInitialized={onInitialized}\n onError={onCameraError}\n />\n {overlayComponent}\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: { flex: 1, backgroundColor: 'black' },\n permissionMessage: { color: 'white', textAlign: 'center', margin: 20, fontSize: 16 },\n});"]}
|
|
1
|
+
{"version":3,"file":"EnhancedCameraView.js","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,mEAAmE;AACnE,0FAA0F;AAC1F,yEAAyE;AACzE,8CAA8C;AAC9C,4DAA4D;AAC5D,wCAAwC;AAExC,0EAA0E;AAC1E,gBAAgB;AAChB,6CAA6C;AAC7C,WAAW;AACX,aAAa;AACb,qBAAqB;AACrB,yBAAyB;AACzB,0BAA0B;AAC1B,sBAAsB;AACtB,UAAU;AACV,6BAA6B;AAC7B,yCAAyC;AAEzC,0CAA0C;AAC1C,kDAAkD;AAElD,wEAAwE;AACxE,8EAA8E;AAC9E,+DAA+D;AAC/D,+DAA+D;AAC/D,mEAAmE;AAGnE,iDAAiD;AACjD,yBAAyB;AACzB,mEAAmE;AACnE,QAAQ;AACR,QAAQ;AAER,kFAAkF;AAElF,6CAA6C;AAC7C,yCAAyC;AACzC,kCAAkC;AAClC,QAAQ;AAER,sBAAsB;AACtB,8CAA8C;AAC9C,wBAAwB;AAExB,2CAA2C;AAC3C,YAAY;AACZ,gFAAgF;AAChF,kCAAkC;AAClC,4EAA4E;AAC5E,0BAA0B;AAC1B,qCAAqC;AACrC,oEAAoE;AACpE,oBAAoB;AACpB,YAAY;AACZ,UAAU;AACV,gCAAgC;AAChC,wBAAwB;AACxB,iCAAiC;AACjC,2DAA2D;AAC3D,QAAQ;AACR,OAAO;AAEP,sBAAsB;AACtB,0CAA0C;AAC1C,qCAAqC;AAErC,sBAAsB;AACtB,iFAAiF;AACjF,kFAAkF;AAClF,8BAA8B;AAC9B,UAAU;AACV,UAAU;AACV,0CAA0C;AAC1C,qCAAqC;AAErC,yEAAyE;AACzE,wDAAwD;AACxD,0EAA0E;AAC1E,sBAAsB;AAEtB,yDAAyD;AACzD,0GAA0G;AAC1G,oDAAoD;AAEpD,YAAY;AACZ,uCAAuC;AACvC,uDAAuD;AACvD,qCAAqC;AACrC,wBAAwB;AACxB,YAAY;AACZ,2EAA2E;AAE3E,4BAA4B;AAC5B,qBAAqB;AACrB,2CAA2C;AAC3C,YAAY;AACZ,wBAAwB;AACxB,kCAAkC;AAClC,kBAAkB;AAClB,wCAAwC;AACxC,QAAQ;AACR,+DAA+D;AAE/D,sBAAsB;AACtB,iEAAiE;AACjE,2BAA2B;AAC3B,sDAAsD;AAEtD,6CAA6C;AAC7C,+BAA+B;AAC/B,yCAAyC;AACzC,gCAAgC;AAChC,kBAAkB;AAClB,gBAAgB;AAEhB,qBAAqB;AACrB,0BAA0B;AAC1B,mCAAmC;AACnC,mDAAmD;AACnD,SAAS;AACT,uEAAuE;AAEvE,mFAAmF;AAEnF,mCAAmC;AACnC,eAAe;AACf,qGAAqG;AACrG,yFAAyF;AACzF,8GAA8G;AAC9G,gBAAgB;AAChB,SAAS;AACT,MAAM;AAEN,mFAAmF;AAEnF,aAAa;AACb,aAAa;AACb,0CAA0C;AAC1C,gHAAgH;AAChH,QAAQ;AACR,gBAAgB;AAChB,uBAAuB;AACvB,0CAA0C;AAC1C,0BAA0B;AAC1B,qCAAqC;AACrC,qCAAqC;AACrC,iDAAiD;AACjD,uBAAuB;AACvB,wBAAwB;AACxB,wBAAwB;AACxB,wCAAwC;AACxC,kCAAkC;AAClC,WAAW;AACX,2BAA2B;AAC3B,cAAc;AACd,OAAO;AACP,KAAK;AAEL,qCAAqC;AACrC,sDAAsD;AACtD,0FAA0F;AAC1F,MAAM;AAEN,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,kBAAkB,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,CAAC,MAAM,kBAAkB,GAAsC,CAAC,EACpE,UAAU,EACV,UAAU,EAAE,iBAAiB,GAAG,OAAO,EACvC,KAAK,EACL,OAAO,EACP,eAAe,EACf,mBAAmB,EACnB,YAAY,GAAG,KAAK,EACpB,gBAAgB,GACjB,EAAE,EAAE;IACH,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,MAAM,CAAS,IAAI,CAAC,CAAC;IAEpC,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,eAAe,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IAE7C,MAAM,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAmB,iBAAiB,CAAC,CAAC;IACnE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAiB,IAAI,CAAC,CAAC;IACzE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1D,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE1D,8EAA8E;IAC9E,+FAA+F;IAC/F,MAAM,MAAM,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAE3C,SAAS,CAAC,GAAG,EAAE;QACb,eAAe,CAAC,OAAO,GAAG,YAAY,CAAC;IACzC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;QAClC,IAAI,CAAC;YACH,MAAM,iBAAiB,GAAG,MAAM,kBAAkB,CAAC,iBAAiB,EAAE,CAAC;YACvE,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACvB,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,qBAAqB,EAAE,CAAC;gBACjE,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,gBAAgB,CAAC,KAAK,CAAC,CAAC;oBACxB,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,2BAA2B,CAAC,EAAE,CAAC,CAAC;oBACvD,OAAO;gBACT,CAAC;YACH,CAAC;YACD,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gBAAgB,CAAC,KAAK,CAAC,CAAC;YACxB,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,UAAU;YAAE,gBAAgB,EAAE,CAAC;IACrC,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;IAEhC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,YAAY,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE;YACtE,IAAI,YAAY,KAAK,QAAQ,IAAI,UAAU,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;gBACvE,gBAAgB,EAAE,CAAC;YACrB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;IACrC,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;IAEhC,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,KAAU,EAAE,EAAE;QAC/C,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IAEjB,MAAM,kBAAkB,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAChD,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,aAAa,IAAI,eAAe,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO;YAAE,OAAO;QACnG,IAAI,mBAAmB,EAAE,WAAW;YAAE,OAAO;QAE7C,IAAI,CAAC;YACH,cAAc,CAAC,OAAO,GAAG,IAAI,CAAC;YAC9B,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;gBAC3C,kBAAkB,EAAE,KAAK;gBACzB,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAElE,eAAe,EAAE,CAAC;gBAChB,GAAG,MAAM;gBACT,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;aAChC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,yBAAyB;QAC3B,CAAC;gBAAS,CAAC;YACT,cAAc,CAAC,OAAO,GAAG,KAAK,CAAC;QACjC,CAAC;IACH,CAAC,EAAE,CAAC,aAAa,EAAE,eAAe,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAE1D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,UAAU,IAAI,CAAC,aAAa,IAAI,YAAY;YAAE,OAAO;QAE1D,IAAI,QAAQ,GAAG,IAAI,CAAC;QACpB,IAAI,UAA0C,CAAC;QAE/C,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,EAAE;YAClC,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACtB,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;gBAC5B,kBAAkB,EAAE,CAAC;YACvB,CAAC,EAAE,IAAI,CAAC,CAAC;QACX,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,OAAO,GAAG,EAAE;YACV,QAAQ,GAAG,KAAK,CAAC;YACjB,YAAY,CAAC,WAAW,CAAC,CAAC;YAC1B,IAAI,UAAU;gBAAE,aAAa,CAAC,UAAU,CAAC,CAAC;QAC5C,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAElE,IAAI,aAAa,KAAK,IAAI;QAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,EAAG,CAAC;IAE9E,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;QAC5B,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,CACzF;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,EAAE,IAAI,CAC7E;QAAA,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAClG;MAAA,EAAE,IAAI,CAAC,CACR,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,MAAM,IAAI,CAAC,UAAU;QAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,EAAG,CAAC;IAE9E,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CACrC;MAAA,CAAC,MAAM,CACL,GAAG,CAAC,CAAC,MAAM,CAAC,CACZ,KAAK,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAC/B,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,UAAU,CAAC,OAAO,CAClB,QAAQ,CAAC,CAAC,UAAU,IAAI,CAAC,YAAY,CAAC,CACtC,KAAK,CAAC,CAAC,IAAI,CAAC,CACZ,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,aAAa,CAAC,CAAC,aAAa,CAAC,CAC7B,OAAO,CAAC,CAAC,aAAa,CAAC,EAEzB;MAAA,CAAC,gBAAgB,CACnB;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/B,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,eAAe,EAAE,OAAO,EAAE;IAChD,iBAAiB,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;CACrF,CAAC,CAAC","sourcesContent":["// import React, { useCallback, useEffect, useRef, useState } from 'react';\n// import { View, StyleSheet, Text, AppState } from 'react-native';\n// import { Camera, useCameraDevice, useCameraFormat } from 'react-native-vision-camera'; \n// import VisionCameraModule from '../modules/camera/VisionCameraModule';\n// import { useI18n } from '../hooks/useI18n';\n// import { EnhancedCameraViewProps } from './OverLay/type';\n// import { Button } from './ui/Button';\n\n// export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({\n// showCamera,\n// cameraType: initialCameraType = 'front',\n// style,\n// onError,\n// onSilentCapture,\n// silentCaptureResult,\n// isProcessing = false,\n// overlayComponent,\n// }) => {\n// const { t } = useI18n();\n// const camera = useRef<Camera>(null);\n\n// const isCapturingRef = useRef(false);\n// const isProcessingRef = useRef(isProcessing);\n\n// const [cameraType] = useState<'front' | 'back'>(initialCameraType);\n// const [hasPermission, setHasPermission] = useState<boolean | null>(null);\n// const [isInitialized, setIsInitialized] = useState(false);\n// const [refreshCamera, setRefreshCamera] = useState(false);\n// const [layout, setLayout] = useState({ width: 0, height: 0 });\n\n\n// const device = useCameraDevice(cameraType, {\n// physicalDevices: [\n// 'wide-angle-camera' // Explicitly request standard 1x lens\n// ]\n// });\n\n// const targetRatio = layout.width > 0 ? layout.height / layout.width : 16 / 9;\n\n// const format = useCameraFormat(device, [\n// { photoAspectRatio: targetRatio },\n// { photoResolution: 'max' } \n// ]);\n\n// useEffect(() => {\n// isProcessingRef.current = isProcessing;\n// }, [isProcessing]);\n\n// const checkPermissions = async () => {\n// try {\n// const hasAllPermissions = await VisionCameraModule.hasAllPermissions();\n// if (!hasAllPermissions) {\n// const granted = await VisionCameraModule.requestAllPermissions();\n// if (!granted) {\n// setHasPermission(false);\n// onError?.({ message: t('camera.permissionRequired') });\n// return;\n// }\n// }\n// setHasPermission(true);\n// } catch (error) {\n// setHasPermission(false);\n// onError?.({ message: t('camera.errorOccurred') });\n// }\n// };\n\n// useEffect(() => {\n// if (showCamera) checkPermissions();\n// }, [showCamera, refreshCamera]);\n\n// useEffect(() => {\n// const subscription = AppState.addEventListener('change', nextAppState => {\n// if (nextAppState === 'active' && showCamera && hasPermission === false) {\n// checkPermissions();\n// }\n// });\n// return () => subscription.remove();\n// }, [showCamera, hasPermission]);\n\n// const onInitialized = useCallback(() => setIsInitialized(true), []);\n// const onCameraError = useCallback((error: any) => {\n// onError?.({ message: error.message || t('camera.errorOccurred') });\n// }, [onError, t]);\n\n// const captureSilentPhoto = useCallback(async () => {\n// if (!camera.current || !isInitialized || isProcessingRef.current || isCapturingRef.current) return;\n// if (silentCaptureResult?.isAnalyzing) return;\n\n// try {\n// isCapturingRef.current = true;\n// const photo = await camera.current.takePhoto({\n// enableShutterSound: false,\n// flash: 'off',\n// });\n// const result = await VisionCameraModule.processPhotoResult(photo);\n\n// onSilentCapture?.({\n// ...result,\n// path: result.path || photo.path,\n// });\n// } catch (error) {\n// // Silent background fail\n// } finally {\n// isCapturingRef.current = false;\n// }\n// }, [isInitialized, onSilentCapture, silentCaptureResult]);\n\n// useEffect(() => {\n// if (!showCamera || !isInitialized || isProcessing) return;\n// let isActive = true;\n// let intervalId: ReturnType<typeof setInterval>;\n\n// const warmupTimer = setTimeout(() => {\n// if (!isActive) return;\n// intervalId = setInterval(() => {\n// captureSilentPhoto();\n// }, 1500);\n// }, 1000);\n\n// return () => {\n// isActive = false;\n// clearTimeout(warmupTimer);\n// if (intervalId) clearInterval(intervalId);\n// };\n// }, [showCamera, isInitialized, isProcessing, captureSilentPhoto]);\n\n// if (hasPermission === null) return <View style={[styles.container, style]} />;\n\n// if (hasPermission === false) {\n// return (\n// <View style={[styles.container, style, { justifyContent: 'center', alignItems: 'center' }]}>\n// <Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>\n// <Button title=\"Refresh Camera\" onPress={() => setRefreshCamera(prev => !prev)} variant=\"primary\" />\n// </View>\n// );\n// }\n\n// if (!device || !showCamera) return <View style={[styles.container, style]} />;\n\n// return (\n// <View \n// style={[styles.container, style]}\n// onLayout={(e) => setLayout({ width: e.nativeEvent.layout.width, height: e.nativeEvent.layout.height })}\n// >\n// <Camera\n// ref={camera}\n// style={StyleSheet.absoluteFill}\n// device={device}\n// format={format} \n// resizeMode=\"cover\" \n// isActive={showCamera && !isProcessing}\n// photo={true}\n// video={false}\n// audio={false}\n// onInitialized={onInitialized}\n// onError={onCameraError}\n// />\n// {overlayComponent}\n// </View>\n// );\n// };\n\n// const styles = StyleSheet.create({\n// container: { flex: 1, backgroundColor: 'black' },\n// permissionMessage: { color: 'white', textAlign: 'center', margin: 20, fontSize: 16 },\n// });\n\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { View, StyleSheet, Text, AppState } from 'react-native';\nimport { Camera, useCameraDevice } from 'react-native-vision-camera'; \nimport VisionCameraModule from '../modules/camera/VisionCameraModule';\nimport { useI18n } from '../hooks/useI18n';\nimport { EnhancedCameraViewProps } from './OverLay/type';\nimport { Button } from './ui/Button';\n\nexport const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({\n showCamera,\n cameraType: initialCameraType = 'front',\n style,\n onError,\n onSilentCapture,\n silentCaptureResult,\n isProcessing = false,\n overlayComponent,\n}) => {\n const { t } = useI18n();\n const camera = useRef<Camera>(null);\n\n const isCapturingRef = useRef(false);\n const isProcessingRef = useRef(isProcessing);\n\n const [cameraType] = useState<'front' | 'back'>(initialCameraType);\n const [hasPermission, setHasPermission] = useState<boolean | null>(null);\n const [isInitialized, setIsInitialized] = useState(false);\n const [refreshCamera, setRefreshCamera] = useState(false);\n\n // 🚨 THE FIX: Removed the strict physical device filtering and custom format.\n // This allows Android to select its own supported, stable hardware stream, preventing crashes.\n const device = useCameraDevice(cameraType);\n\n useEffect(() => {\n isProcessingRef.current = isProcessing;\n }, [isProcessing]);\n\n const checkPermissions = async () => {\n try {\n const hasAllPermissions = await VisionCameraModule.hasAllPermissions();\n if (!hasAllPermissions) {\n const granted = await VisionCameraModule.requestAllPermissions();\n if (!granted) {\n setHasPermission(false);\n onError?.({ message: t('camera.permissionRequired') });\n return;\n }\n }\n setHasPermission(true);\n } catch (error) {\n setHasPermission(false);\n onError?.({ message: t('camera.errorOccurred') });\n }\n };\n\n useEffect(() => {\n if (showCamera) checkPermissions();\n }, [showCamera, refreshCamera]);\n\n useEffect(() => {\n const subscription = AppState.addEventListener('change', nextAppState => {\n if (nextAppState === 'active' && showCamera && hasPermission === false) {\n checkPermissions();\n }\n });\n return () => subscription.remove();\n }, [showCamera, hasPermission]);\n\n const onInitialized = useCallback(() => setIsInitialized(true), []);\n const onCameraError = useCallback((error: any) => {\n onError?.({ message: error.message || t('camera.errorOccurred') });\n }, [onError, t]);\n\n const captureSilentPhoto = useCallback(async () => {\n if (!camera.current || !isInitialized || isProcessingRef.current || isCapturingRef.current) return;\n if (silentCaptureResult?.isAnalyzing) return;\n\n try {\n isCapturingRef.current = true;\n const photo = await camera.current.takePhoto({\n enableShutterSound: false,\n flash: 'off',\n });\n \n const result = await VisionCameraModule.processPhotoResult(photo);\n\n onSilentCapture?.({\n ...result,\n path: result.path || photo.path,\n });\n } catch (error) {\n // Silent background fail\n } finally {\n isCapturingRef.current = false;\n }\n }, [isInitialized, onSilentCapture, silentCaptureResult]);\n\n useEffect(() => {\n if (!showCamera || !isInitialized || isProcessing) return;\n \n let isActive = true;\n let intervalId: ReturnType<typeof setInterval>;\n\n const warmupTimer = setTimeout(() => {\n if (!isActive) return;\n intervalId = setInterval(() => {\n captureSilentPhoto();\n }, 1500);\n }, 1000);\n\n return () => {\n isActive = false;\n clearTimeout(warmupTimer);\n if (intervalId) clearInterval(intervalId);\n };\n }, [showCamera, isInitialized, isProcessing, captureSilentPhoto]);\n\n if (hasPermission === null) return <View style={[styles.container, style]} />;\n\n if (hasPermission === false) {\n return (\n <View style={[styles.container, style, { justifyContent: 'center', alignItems: 'center' }]}>\n <Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>\n <Button title=\"Refresh Camera\" onPress={() => setRefreshCamera(prev => !prev)} variant=\"primary\" />\n </View>\n );\n }\n\n if (!device || !showCamera) return <View style={[styles.container, style]} />;\n\n return (\n <View style={[styles.container, style]}>\n <Camera\n ref={camera}\n style={StyleSheet.absoluteFill}\n device={device}\n resizeMode=\"cover\" \n isActive={showCamera && !isProcessing}\n photo={true}\n video={false}\n audio={false}\n onInitialized={onInitialized}\n onError={onCameraError}\n />\n {overlayComponent}\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: { flex: 1, backgroundColor: 'black' },\n permissionMessage: { color: 'white', textAlign: 'center', margin: 20, fontSize: 16 },\n});"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IDCardCapture.d.ts","sourceRoot":"","sources":["../../../../src/components/KYCElements/IDCardCapture.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAI5D,OAAO,EAAE,iBAAiB,EAAoI,MAAM,uBAAuB,CAAC;AAc5L,UAAU,cAAc;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAAE;AAC3F,UAAU,kBAAkB;IAAG,SAAS,EAAE,iBAAiB,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAAE;AAExO,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"IDCardCapture.d.ts","sourceRoot":"","sources":["../../../../src/components/KYCElements/IDCardCapture.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAI5D,OAAO,EAAE,iBAAiB,EAAoI,MAAM,uBAAuB,CAAC;AAc5L,UAAU,cAAc;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAAE;AAC3F,UAAU,kBAAkB;IAAG,SAAS,EAAE,iBAAiB,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAAE;AAExO,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAyftD,CAAC"}
|