react-native-biometric-verifier 0.0.55 → 0.0.57

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.
@@ -1,249 +1,71 @@
1
- import { useCallback, useRef } from 'react';
1
+ import { useCallback } from 'react';
2
2
  import { Platform, PermissionsAndroid } from 'react-native';
3
3
  import Geolocation from 'react-native-geolocation-service';
4
4
 
5
5
  /**
6
- * FAST + ACCURATE Geolocation Hook (Optimized for Verification)
6
+ * Custom hook for requesting location permission and fetching current location.
7
+ *
8
+ * @param {Function} notifyMessage - Callback to show notifications (message, type).
9
+ * @returns {Object} { requestLocationPermission, getCurrentLocation }
7
10
  */
8
11
  export const useGeolocation = (notifyMessage) => {
9
- const locationWatchId = useRef(null);
10
-
11
- /* -------------------------------------------------------------------------- */
12
- /* PERMISSIONS */
13
- /* -------------------------------------------------------------------------- */
12
+ /**
13
+ * Requests location permission (Android only).
14
+ * @returns {Promise<boolean>} - True if permission granted, else false.
15
+ */
14
16
  const requestLocationPermission = useCallback(async () => {
15
- try {
16
- if (Platform.OS !== 'android') return true;
17
+ if (Platform.OS !== 'android') return true;
17
18
 
18
- const permissions = [
19
+ try {
20
+ const granted = await PermissionsAndroid.request(
19
21
  PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
20
- PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
21
- ];
22
-
23
- const result = await PermissionsAndroid.requestMultiple(permissions);
24
-
25
- const granted = Object.values(result).every(
26
- status => status === PermissionsAndroid.RESULTS.GRANTED
22
+ {
23
+ title: 'Location Permission Required',
24
+ message: 'This app needs your location to verify QR code scans.',
25
+ buttonPositive: 'OK',
26
+ buttonNegative: 'Cancel',
27
+ }
27
28
  );
28
29
 
29
- if (!granted) {
30
- notifyMessage?.('Location permissions missing', 'warning');
30
+ const hasPermission = granted === PermissionsAndroid.RESULTS.GRANTED;
31
+
32
+ if (!hasPermission) {
33
+ notifyMessage?.('Cannot get location without permission.', 'error');
31
34
  }
32
35
 
33
- return granted;
34
- } catch (err) {
35
- console.error('[Geo Permissions]', err);
36
+ return hasPermission;
37
+ } catch (error) {
38
+ console.error('Location permission error:', error);
39
+ notifyMessage?.('Location permission error.', 'error');
36
40
  return false;
37
41
  }
38
42
  }, [notifyMessage]);
39
43
 
40
- /* -------------------------------------------------------------------------- */
41
- /* STOP LOCATION WATCH */
42
- /* -------------------------------------------------------------------------- */
43
- const stopLocationWatching = useCallback(() => {
44
- if (locationWatchId.current !== null) {
45
- Geolocation.clearWatch(locationWatchId.current);
46
- locationWatchId.current = null;
47
- }
48
- }, []);
49
-
50
- /* -------------------------------------------------------------------------- */
51
- /* FAST + ACCURATE LOCATION FETCH */
52
- /* -------------------------------------------------------------------------- */
53
- const getCurrentLocation = useCallback((options = {}) => {
54
- return new Promise((resolve, reject) => {
55
- let samples = [];
56
- let resolved = false;
57
-
58
- const defaultOptions = {
59
- enableHighAccuracy: true,
60
- timeout: 8000, // ⏱ fast
61
- maximumAge: 2000, // allow cached fix
62
- forceRequestLocation: true,
63
- showLocationDialog: true,
64
- interval: 800,
65
- fastestInterval: 500,
66
- distanceFilter: 0,
67
- ...options,
68
- };
69
-
70
- try {
71
- /* ---------------- FAST FIRST FIX ---------------- */
44
+ /**
45
+ * Fetches the current location of the device.
46
+ * @returns {Promise<GeolocationCoordinates>}
47
+ */
48
+ const getCurrentLocation = useCallback(
49
+ () =>
50
+ new Promise((resolve, reject) => {
72
51
  Geolocation.getCurrentPosition(
73
- (pos) => {
74
- if (!pos?.coords || resolved) return;
75
-
76
- const {
77
- latitude,
78
- longitude,
79
- accuracy,
80
- altitude = 0,
81
- speed = 0,
82
- heading = 0,
83
- } = pos.coords;
84
-
85
- // Accept immediately if good enough for verification
86
- if (accuracy <= 15) {
87
- resolved = true;
88
- resolve({
89
- latitude,
90
- longitude,
91
- altitude,
92
- accuracy,
93
- speed,
94
- heading,
95
- timestamp: pos.timestamp,
96
- });
97
- }
98
-
99
- samples.push({
100
- latitude,
101
- longitude,
102
- altitude,
103
- accuracy,
104
- speed,
105
- heading,
106
- timestamp: pos.timestamp,
107
- });
108
- },
109
- (err) => {
110
- console.warn('[Geo Fast Fix Failed]', err);
111
- },
112
- defaultOptions
113
- );
114
-
115
- /* ---------------- BACKGROUND IMPROVEMENT ---------------- */
116
- locationWatchId.current = Geolocation.watchPosition(
117
- (p) => {
118
- if (!p?.coords) return;
119
-
120
- const {
121
- latitude,
122
- longitude,
123
- accuracy,
124
- altitude = 0,
125
- speed = 0,
126
- heading = 0,
127
- } = p.coords;
128
-
129
- /* -------- LIGHT NOISE FILTERS -------- */
130
- if (accuracy > 40) return;
131
- if (speed > 50) return;
132
-
133
- samples.push({
134
- latitude,
135
- longitude,
136
- altitude,
137
- accuracy,
138
- speed,
139
- heading,
140
- timestamp: p.timestamp,
141
- });
142
-
143
- if (samples.length > 8) samples.shift();
144
-
145
- samples.sort((a, b) => a.accuracy - b.accuracy);
146
- const best = samples[0];
147
-
148
- // Upgrade accuracy silently
149
- if (best.accuracy <= 6 && !resolved) {
150
- resolved = true;
151
- stopLocationWatching();
152
- resolve(best);
153
- }
52
+ (position) => {
53
+ resolve(position.coords);
154
54
  },
155
- (err) => {
156
- console.error('[Geo Watch Error]', err);
157
- stopLocationWatching();
55
+ (error) => {
56
+ notifyMessage?.('Unable to fetch current location.', 'error');
57
+ reject(error);
158
58
  },
159
- defaultOptions
160
- );
161
-
162
- /* ---------------- HARD STOP ---------------- */
163
- setTimeout(() => {
164
- if (!resolved && samples.length) {
165
- resolved = true;
166
- stopLocationWatching();
167
- samples.sort((a, b) => a.accuracy - b.accuracy);
168
- resolve(samples[0]);
59
+ {
60
+ enableHighAccuracy: true,
61
+ timeout: 15000,
62
+ maximumAge: 10000,
63
+ distanceFilter: 1,
169
64
  }
170
- }, 5000);
171
- } catch (err) {
172
- stopLocationWatching();
173
- notifyMessage?.('Failed to get location', 'error');
174
- reject(err);
175
- }
176
- });
177
- }, [notifyMessage, stopLocationWatching]);
178
-
179
- /* -------------------------------------------------------------------------- */
180
- /* DISTANCE CALCULATION */
181
- /* -------------------------------------------------------------------------- */
182
- const calculateEnhancedDistance = useCallback(
183
- (lat1, lon1, lat2, lon2, alt1 = 0, alt2 = 0) => {
184
- try {
185
- if (
186
- typeof lat1 !== 'number' ||
187
- typeof lon1 !== 'number' ||
188
- typeof lat2 !== 'number' ||
189
- typeof lon2 !== 'number'
190
- ) return Infinity;
191
-
192
- const toRad = deg => deg * Math.PI / 180;
193
- const R = 6371e3;
194
-
195
- const φ1 = toRad(lat1);
196
- const φ2 = toRad(lat2);
197
- const Δφ = toRad(lat2 - lat1);
198
- const Δλ = toRad(lon2 - lon1);
199
-
200
- const a =
201
- Math.sin(Δφ / 2) ** 2 +
202
- Math.cos(φ1) * Math.cos(φ2) *
203
- Math.sin(Δλ / 2) ** 2;
204
-
205
- const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
206
- const surfaceDistance = R * c;
207
-
208
- const heightDiff = Math.abs(alt1 - alt2);
209
- return Math.sqrt(surfaceDistance ** 2 + heightDiff ** 2);
210
- } catch {
211
- return Infinity;
212
- }
213
- },
214
- []
215
- );
216
-
217
- const calculateSafeDistance = useCallback(
218
- (p1, p2) => {
219
- try {
220
- const lat1 = p1.latitude ?? p1.lat;
221
- const lon1 = p1.longitude ?? p1.lng ?? p1.lon;
222
- const alt1 = p1.altitude ?? p1.alt ?? 0;
223
-
224
- const lat2 = p2.latitude ?? p2.lat;
225
- const lon2 = p2.longitude ?? p2.lng ?? p2.lon;
226
- const alt2 = p2.altitude ?? p2.alt ?? 0;
227
-
228
- return calculateEnhancedDistance(
229
- lat1, lon1, lat2, lon2, alt1, alt2
230
65
  );
231
- } catch {
232
- return Infinity;
233
- }
234
- },
235
- [calculateEnhancedDistance]
66
+ }),
67
+ [notifyMessage]
236
68
  );
237
69
 
238
- /* -------------------------------------------------------------------------- */
239
- /* API */
240
- /* -------------------------------------------------------------------------- */
241
- return {
242
- requestLocationPermission,
243
- getCurrentLocation,
244
- stopLocationWatching,
245
- getCurrentWatchId: () => locationWatchId.current,
246
- calculateEnhancedDistance,
247
- calculateSafeDistance,
248
- };
70
+ return { requestLocationPermission, getCurrentLocation };
249
71
  };