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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-biometric-verifier",
3
- "version": "0.0.20",
3
+ "version": "0.0.22",
4
4
  "description": "A React Native module for biometric verification with face recognition and QR code scanning",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -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, imageurl } = employeeData;
15
+ const { facename, faceid, img } = employeeData;
16
16
 
17
17
  const employeeName = facename || 'Unknown Employee';
18
18
  const employeeId = faceid || 'N/A';
19
- const imageSource =
20
- !imageError && imageurl
21
- ? { uri: `${apiurl}file/filedownload/photo/${imageurl}` }
22
- : { uri: `${apiurl}file/getCommonFile/image/camera.png` };
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
- <Image
29
- source={imageSource}
30
- style={styles.image}
31
- resizeMode="cover"
32
- onError={() => {
33
- console.error(`Error loading image for employee: ${employeeName}`);
34
- setImageError(true);
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
- imageurl: PropTypes.string,
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)',
@@ -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 = {uri: `http://emr.amalaims.org:9393/file/getCommonFile/image/heartpulse.gif`},
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}file/getCommonFile/image/Face.gif`;
11
+ `${APIURL}${imageurl}Face.gif`;
12
12
  const LocationGifUrl =
13
- `${APIURL}file/getCommonFile/image/Location.gif`;
13
+ `${APIURL}${imageurl}Location.gif`;
14
14
 
15
15
  if (
16
16
  animationState === Global.AnimationStates.faceScan ||