react-native-biometric-verifier 0.0.20 â 0.0.22
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/package.json +1 -1
- package/src/components/Card.js +31 -18
- package/src/components/Loader.js +1 -1
- package/src/index.js +24 -24
- package/src/utils/getLoaderGif.js +3 -3
package/package.json
CHANGED
package/src/components/Card.js
CHANGED
|
@@ -4,7 +4,7 @@ import Icon from 'react-native-vector-icons/MaterialIcons';
|
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import { Global } from '../utils/Global';
|
|
6
6
|
|
|
7
|
-
export const Card = ({ employeeData, apiurl }) => {
|
|
7
|
+
export const Card = ({ employeeData, apiurl, fileurl = 'file/filedownload/photo/' }) => {
|
|
8
8
|
const [imageError, setImageError] = useState(false);
|
|
9
9
|
|
|
10
10
|
if (!employeeData || typeof employeeData !== 'object') {
|
|
@@ -12,28 +12,34 @@ export const Card = ({ employeeData, apiurl }) => {
|
|
|
12
12
|
return null;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const { facename, faceid,
|
|
15
|
+
const { facename, faceid, img } = employeeData;
|
|
16
16
|
|
|
17
17
|
const employeeName = facename || 'Unknown Employee';
|
|
18
18
|
const employeeId = faceid || 'N/A';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
|
|
20
|
+
const imageSource = !imageError && img
|
|
21
|
+
? { uri: `${apiurl}${fileurl}${img}` }
|
|
22
|
+
: null;
|
|
23
23
|
|
|
24
24
|
return (
|
|
25
25
|
<View style={styles.card}>
|
|
26
|
-
{/* Employee Image */}
|
|
26
|
+
{/* Employee Image or Fallback Icon */}
|
|
27
27
|
<View style={styles.imageWrapper}>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
{!imageError && img ? (
|
|
29
|
+
<Image
|
|
30
|
+
source={imageSource}
|
|
31
|
+
style={styles.image}
|
|
32
|
+
resizeMode="cover"
|
|
33
|
+
onError={() => {
|
|
34
|
+
console.error(`Error loading image for employee: ${employeeName}`);
|
|
35
|
+
setImageError(true);
|
|
36
|
+
}}
|
|
37
|
+
/>
|
|
38
|
+
) : (
|
|
39
|
+
<View style={styles.iconContainer}>
|
|
40
|
+
<Icon name="person-outline" size={60} color={Global.AppTheme.primary} />
|
|
41
|
+
</View>
|
|
42
|
+
)}
|
|
37
43
|
<View style={styles.imageOverlay} />
|
|
38
44
|
</View>
|
|
39
45
|
|
|
@@ -56,8 +62,10 @@ Card.propTypes = {
|
|
|
56
62
|
employeeData: PropTypes.shape({
|
|
57
63
|
facename: PropTypes.string,
|
|
58
64
|
faceid: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
59
|
-
|
|
65
|
+
img: PropTypes.string,
|
|
60
66
|
}),
|
|
67
|
+
apiurl: PropTypes.string,
|
|
68
|
+
fileurl: PropTypes.string,
|
|
61
69
|
};
|
|
62
70
|
|
|
63
71
|
const styles = StyleSheet.create({
|
|
@@ -75,7 +83,6 @@ const styles = StyleSheet.create({
|
|
|
75
83
|
elevation: 4,
|
|
76
84
|
borderWidth: 1,
|
|
77
85
|
borderColor: 'rgba(255,255,255,0.2)',
|
|
78
|
-
backdropFilter: 'blur(10px)', // works only in web, safe to keep
|
|
79
86
|
},
|
|
80
87
|
imageWrapper: {
|
|
81
88
|
width: 110,
|
|
@@ -92,6 +99,12 @@ const styles = StyleSheet.create({
|
|
|
92
99
|
width: '100%',
|
|
93
100
|
height: '100%',
|
|
94
101
|
},
|
|
102
|
+
iconContainer: {
|
|
103
|
+
justifyContent: 'center',
|
|
104
|
+
alignItems: 'center',
|
|
105
|
+
width: '100%',
|
|
106
|
+
height: '100%',
|
|
107
|
+
},
|
|
95
108
|
imageOverlay: {
|
|
96
109
|
...StyleSheet.absoluteFillObject,
|
|
97
110
|
backgroundColor: 'rgba(108, 99, 255, 0.12)',
|
package/src/components/Loader.js
CHANGED
|
@@ -16,7 +16,7 @@ export default function Loader({
|
|
|
16
16
|
overlayColor = 'rgba(0,0,0,0.4)',
|
|
17
17
|
loaderColor = 'lightblue',
|
|
18
18
|
size = 50,
|
|
19
|
-
gifSource
|
|
19
|
+
gifSource,
|
|
20
20
|
message = '',
|
|
21
21
|
messageStyle = {},
|
|
22
22
|
animationType = 'fade',
|
package/src/index.js
CHANGED
|
@@ -40,9 +40,9 @@ import CaptureImageWithoutEdit from "./components/CaptureImageWithoutEdit";
|
|
|
40
40
|
import StepIndicator from "./components/StepIndicator";
|
|
41
41
|
|
|
42
42
|
const BiometricModal = React.memo(
|
|
43
|
-
({ data, qrscan = false, callback, apiurl, onclose, frameProcessorFps, livenessLevel }) => {
|
|
43
|
+
({ data, qrscan = false, callback, apiurl, onclose, frameProcessorFps, livenessLevel, fileurl, imageurl }) => {
|
|
44
44
|
const navigation = useNavigation();
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
// Custom hooks
|
|
47
47
|
const { countdown, startCountdown, resetCountdown, pauseCountdown, resumeCountdown } = useCountdown();
|
|
48
48
|
const { requestLocationPermission, getCurrentLocation } = useGeolocation();
|
|
@@ -67,7 +67,7 @@ const BiometricModal = React.memo(
|
|
|
67
67
|
const responseRef = useRef(null);
|
|
68
68
|
const processedRef = useRef(false);
|
|
69
69
|
const resetTimeoutRef = useRef(null);
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
// Animation values
|
|
72
72
|
const iconScaleAnim = useRef(new Animated.Value(1)).current;
|
|
73
73
|
const iconOpacityAnim = useRef(new Animated.Value(0)).current;
|
|
@@ -79,12 +79,12 @@ const BiometricModal = React.memo(
|
|
|
79
79
|
return () => {
|
|
80
80
|
console.log("đ§š BiometricModal unmounting - cleaning up");
|
|
81
81
|
mountedRef.current = false;
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
if (resetTimeoutRef.current) {
|
|
84
84
|
clearTimeout(resetTimeoutRef.current);
|
|
85
85
|
console.log("âšī¸ Cleared reset timeout");
|
|
86
86
|
}
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
clearNotification();
|
|
89
89
|
};
|
|
90
90
|
}, []);
|
|
@@ -131,7 +131,7 @@ const BiometricModal = React.memo(
|
|
|
131
131
|
if (mountedRef.current) {
|
|
132
132
|
setState((prev) => {
|
|
133
133
|
const merged = { ...prev, ...newState };
|
|
134
|
-
|
|
134
|
+
|
|
135
135
|
if (JSON.stringify(prev) !== JSON.stringify(merged)) {
|
|
136
136
|
console.log("đ State updated:", merged);
|
|
137
137
|
|
|
@@ -153,7 +153,7 @@ const BiometricModal = React.memo(
|
|
|
153
153
|
|
|
154
154
|
return merged;
|
|
155
155
|
}
|
|
156
|
-
|
|
156
|
+
|
|
157
157
|
return prev;
|
|
158
158
|
});
|
|
159
159
|
} else {
|
|
@@ -165,7 +165,7 @@ const BiometricModal = React.memo(
|
|
|
165
165
|
const resetState = useCallback(() => {
|
|
166
166
|
console.log("đ Resetting biometric modal state");
|
|
167
167
|
onclose(false);
|
|
168
|
-
|
|
168
|
+
|
|
169
169
|
setState({
|
|
170
170
|
isLoading: false,
|
|
171
171
|
loadingType: Global.LoadingTypes.none,
|
|
@@ -173,7 +173,7 @@ const BiometricModal = React.memo(
|
|
|
173
173
|
employeeData: null,
|
|
174
174
|
animationState: Global.AnimationStates.faceScan,
|
|
175
175
|
});
|
|
176
|
-
|
|
176
|
+
|
|
177
177
|
setModalVisible(false);
|
|
178
178
|
processedRef.current = false;
|
|
179
179
|
resetCountdown();
|
|
@@ -202,7 +202,7 @@ const BiometricModal = React.memo(
|
|
|
202
202
|
if (resetTimeoutRef.current) {
|
|
203
203
|
clearTimeout(resetTimeoutRef.current);
|
|
204
204
|
}
|
|
205
|
-
|
|
205
|
+
|
|
206
206
|
resetTimeoutRef.current = setTimeout(() => {
|
|
207
207
|
console.log("â° Error timeout completed - resetting state");
|
|
208
208
|
resetState();
|
|
@@ -215,7 +215,7 @@ const BiometricModal = React.memo(
|
|
|
215
215
|
const handleCountdownFinish = useCallback(() => {
|
|
216
216
|
console.log("â° Countdown finished");
|
|
217
217
|
handleProcessError("Time is up! Please try again.");
|
|
218
|
-
|
|
218
|
+
|
|
219
219
|
if (navigation.canGoBack()) {
|
|
220
220
|
console.log("âŠī¸ Navigating back due to timeout");
|
|
221
221
|
navigation.goBack();
|
|
@@ -229,7 +229,7 @@ const BiometricModal = React.memo(
|
|
|
229
229
|
handleProcessError("Invalid API URL configuration.");
|
|
230
230
|
return false;
|
|
231
231
|
}
|
|
232
|
-
|
|
232
|
+
|
|
233
233
|
console.log("â
API URL validated:", apiurl);
|
|
234
234
|
return true;
|
|
235
235
|
}, [apiurl, handleProcessError]);
|
|
@@ -256,7 +256,7 @@ const BiometricModal = React.memo(
|
|
|
256
256
|
|
|
257
257
|
InteractionManager.runAfterInteractions(async () => {
|
|
258
258
|
let base64;
|
|
259
|
-
|
|
259
|
+
|
|
260
260
|
try {
|
|
261
261
|
console.log("đŧī¸ Converting image to base64");
|
|
262
262
|
updateState({
|
|
@@ -299,7 +299,7 @@ const BiometricModal = React.memo(
|
|
|
299
299
|
if (response?.httpstatus === 200) {
|
|
300
300
|
console.log("â
Face recognition successful");
|
|
301
301
|
responseRef.current = response;
|
|
302
|
-
|
|
302
|
+
|
|
303
303
|
updateState({
|
|
304
304
|
employeeData: response.data?.data || null,
|
|
305
305
|
animationState: Global.AnimationStates.success,
|
|
@@ -315,11 +315,11 @@ const BiometricModal = React.memo(
|
|
|
315
315
|
} else {
|
|
316
316
|
console.log("â
Verification complete - calling callback");
|
|
317
317
|
safeCallback(responseRef.current);
|
|
318
|
-
|
|
318
|
+
|
|
319
319
|
if (resetTimeoutRef.current) {
|
|
320
320
|
clearTimeout(resetTimeoutRef.current);
|
|
321
321
|
}
|
|
322
|
-
|
|
322
|
+
|
|
323
323
|
resetTimeoutRef.current = setTimeout(() => {
|
|
324
324
|
console.log("â° Success timeout completed - resetting");
|
|
325
325
|
resetState();
|
|
@@ -436,7 +436,7 @@ const BiometricModal = React.memo(
|
|
|
436
436
|
console.log("â
Location verified successfully");
|
|
437
437
|
safeCallback(responseRef.current);
|
|
438
438
|
notifyMessage("Location verified successfully!", "success");
|
|
439
|
-
|
|
439
|
+
|
|
440
440
|
updateState({
|
|
441
441
|
animationState: Global.AnimationStates.success,
|
|
442
442
|
isLoading: false,
|
|
@@ -446,7 +446,7 @@ const BiometricModal = React.memo(
|
|
|
446
446
|
if (resetTimeoutRef.current) {
|
|
447
447
|
clearTimeout(resetTimeoutRef.current);
|
|
448
448
|
}
|
|
449
|
-
|
|
449
|
+
|
|
450
450
|
resetTimeoutRef.current = setTimeout(() => {
|
|
451
451
|
console.log("â° Location success timeout - resetting");
|
|
452
452
|
resetState();
|
|
@@ -547,8 +547,8 @@ const BiometricModal = React.memo(
|
|
|
547
547
|
const loaderSource = useMemo(
|
|
548
548
|
() =>
|
|
549
549
|
state.isLoading &&
|
|
550
|
-
getLoaderGif(state.animationState, state.currentStep, apiurl),
|
|
551
|
-
[state.isLoading, state.animationState, state.currentStep, apiurl]
|
|
550
|
+
getLoaderGif(state.animationState, state.currentStep, apiurl, imageurl),
|
|
551
|
+
[state.isLoading, state.animationState, state.currentStep, apiurl, imageurl]
|
|
552
552
|
);
|
|
553
553
|
|
|
554
554
|
// Determine if camera should be shown
|
|
@@ -580,7 +580,7 @@ const BiometricModal = React.memo(
|
|
|
580
580
|
/>
|
|
581
581
|
</View>
|
|
582
582
|
)}
|
|
583
|
-
|
|
583
|
+
|
|
584
584
|
{/* UI elements positioned absolutely on top of camera */}
|
|
585
585
|
<TouchableOpacity
|
|
586
586
|
style={styles.closeButton}
|
|
@@ -590,7 +590,7 @@ const BiometricModal = React.memo(
|
|
|
590
590
|
>
|
|
591
591
|
<Icon name="close" size={24} color={Global.AppTheme.light} />
|
|
592
592
|
</TouchableOpacity>
|
|
593
|
-
|
|
593
|
+
|
|
594
594
|
<View style={styles.topContainer}>
|
|
595
595
|
{!shouldShowCamera && (
|
|
596
596
|
<View style={styles.headerContainer}>
|
|
@@ -601,14 +601,14 @@ const BiometricModal = React.memo(
|
|
|
601
601
|
</View>
|
|
602
602
|
)}
|
|
603
603
|
</View>
|
|
604
|
-
|
|
604
|
+
|
|
605
605
|
<View style={styles.topContainerstep}>
|
|
606
606
|
<StepIndicator currentStep={state.currentStep} qrscan={qrscan} />
|
|
607
607
|
</View>
|
|
608
608
|
|
|
609
609
|
{state.employeeData && (
|
|
610
610
|
<View style={styles.cardContainer}>
|
|
611
|
-
<Card employeeData={state.employeeData} apiurl={apiurl} />
|
|
611
|
+
<Card employeeData={state.employeeData} apiurl={apiurl} fileurl={fileurl} />
|
|
612
612
|
</View>
|
|
613
613
|
)}
|
|
614
614
|
|
|
@@ -6,11 +6,11 @@ import { Global } from "./Global";
|
|
|
6
6
|
* @param {string} currentStep - Current step of verification
|
|
7
7
|
* @returns {any} - Gif image source or null
|
|
8
8
|
*/
|
|
9
|
-
export const getLoaderGif = (animationState, currentStep,APIURL) => {
|
|
9
|
+
export const getLoaderGif = (animationState, currentStep,APIURL,imageurl ='file/getCommonFile/image/') => {
|
|
10
10
|
const FaceGifUrl =
|
|
11
|
-
`${APIURL}
|
|
11
|
+
`${APIURL}${imageurl}Face.gif`;
|
|
12
12
|
const LocationGifUrl =
|
|
13
|
-
`${APIURL}
|
|
13
|
+
`${APIURL}${imageurl}Location.gif`;
|
|
14
14
|
|
|
15
15
|
if (
|
|
16
16
|
animationState === Global.AnimationStates.faceScan ||
|