@umituz/react-native-location 1.0.0 → 1.0.3
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 +3 -7
- package/src/domain/entities/Location.ts +16 -168
- package/src/index.ts +3 -107
- package/src/infrastructure/services/LocationService.ts +76 -286
- package/src/presentation/hooks/useLocation.ts +38 -221
- package/LICENSE +0 -22
- package/README.md +0 -127
- package/lib/domain/entities/Location.d.ts +0 -144
- package/lib/domain/entities/Location.d.ts.map +0 -1
- package/lib/domain/entities/Location.js +0 -52
- package/lib/domain/entities/Location.js.map +0 -1
- package/lib/index.d.ts +0 -95
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -95
- package/lib/index.js.map +0 -1
- package/lib/infrastructure/services/LocationService.d.ts +0 -93
- package/lib/infrastructure/services/LocationService.d.ts.map +0 -1
- package/lib/infrastructure/services/LocationService.js +0 -250
- package/lib/infrastructure/services/LocationService.js.map +0 -1
- package/lib/presentation/hooks/useLocation.d.ts +0 -95
- package/lib/presentation/hooks/useLocation.d.ts.map +0 -1
- package/lib/presentation/hooks/useLocation.js +0 -156
- package/lib/presentation/hooks/useLocation.js.map +0 -1
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Location Service Implementation
|
|
3
|
-
*
|
|
4
|
-
* Handles device location retrieval, permissions, caching, and reverse geocoding
|
|
5
|
-
* with intelligent fallback strategies
|
|
6
|
-
*
|
|
7
|
-
* Features:
|
|
8
|
-
* - Multi-tier accuracy fallback (High → Balanced → Cached)
|
|
9
|
-
* - 15-minute location caching for performance
|
|
10
|
-
* - Reverse geocoding with coordinate fallback
|
|
11
|
-
* - Platform detection (iOS/Android only, no web)
|
|
12
|
-
* - Silent failures (no console logging)
|
|
13
|
-
* - AsyncStorage persistence
|
|
14
|
-
*
|
|
15
|
-
* Dependencies:
|
|
16
|
-
* - expo-location (GPS and permissions API)
|
|
17
|
-
* - AsyncStorage (cache persistence)
|
|
18
|
-
*
|
|
19
|
-
* USAGE:
|
|
20
|
-
* ```typescript
|
|
21
|
-
* import { locationService } from '@umituz/react-native-location';
|
|
22
|
-
*
|
|
23
|
-
* // Check permission
|
|
24
|
-
* const hasPermission = await locationService.hasPermissions();
|
|
25
|
-
*
|
|
26
|
-
* // Request permission if needed
|
|
27
|
-
* if (!hasPermission) {
|
|
28
|
-
* const granted = await locationService.requestPermissions();
|
|
29
|
-
* }
|
|
30
|
-
*
|
|
31
|
-
* // Get current location
|
|
32
|
-
* const location = await locationService.getCurrentLocation();
|
|
33
|
-
* if (location) {
|
|
34
|
-
* console.log(location.latitude, location.longitude);
|
|
35
|
-
* console.log(locationService.formatLocation(location));
|
|
36
|
-
* }
|
|
37
|
-
* ```
|
|
38
|
-
*/
|
|
39
|
-
import { Platform } from 'react-native';
|
|
40
|
-
import * as Location from 'expo-location';
|
|
41
|
-
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
42
|
-
import { LOCATION_CONSTANTS } from '../../domain/entities/Location';
|
|
43
|
-
class LocationService {
|
|
44
|
-
constructor() {
|
|
45
|
-
this.cachedLocation = null;
|
|
46
|
-
this.cachedAt = 0;
|
|
47
|
-
this.permissionStatus = 'unknown';
|
|
48
|
-
this.loadCachedLocation();
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Check if location services are available on this platform
|
|
52
|
-
*/
|
|
53
|
-
isLocationAvailable() {
|
|
54
|
-
// Location services not available on web
|
|
55
|
-
if (Platform.OS === 'web') {
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Load cached location from AsyncStorage
|
|
62
|
-
*/
|
|
63
|
-
async loadCachedLocation() {
|
|
64
|
-
try {
|
|
65
|
-
const cached = await AsyncStorage.getItem(LOCATION_CONSTANTS.CACHE_KEY);
|
|
66
|
-
if (cached) {
|
|
67
|
-
const parsed = JSON.parse(cached);
|
|
68
|
-
if (Date.now() - parsed.cachedAt < LOCATION_CONSTANTS.CACHE_DURATION) {
|
|
69
|
-
this.cachedLocation = parsed.data;
|
|
70
|
-
this.cachedAt = parsed.cachedAt;
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
// Expired cache, remove it
|
|
74
|
-
await AsyncStorage.removeItem(LOCATION_CONSTANTS.CACHE_KEY);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
catch (error) {
|
|
79
|
-
// Silent failure on cache load
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Save location to cache (AsyncStorage + memory)
|
|
84
|
-
*/
|
|
85
|
-
async saveCachedLocation(location) {
|
|
86
|
-
try {
|
|
87
|
-
const cached = {
|
|
88
|
-
data: location,
|
|
89
|
-
cachedAt: Date.now(),
|
|
90
|
-
};
|
|
91
|
-
this.cachedLocation = location;
|
|
92
|
-
this.cachedAt = cached.cachedAt;
|
|
93
|
-
await AsyncStorage.setItem(LOCATION_CONSTANTS.CACHE_KEY, JSON.stringify(cached));
|
|
94
|
-
}
|
|
95
|
-
catch (error) {
|
|
96
|
-
// Silent failure on cache save
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Get cached location if available and not expired
|
|
101
|
-
*/
|
|
102
|
-
getCachedLocation() {
|
|
103
|
-
if (!this.cachedLocation) {
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
const age = Date.now() - this.cachedAt;
|
|
107
|
-
if (age < LOCATION_CONSTANTS.CACHE_DURATION) {
|
|
108
|
-
return { ...this.cachedLocation, isCached: true };
|
|
109
|
-
}
|
|
110
|
-
return null;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Request location permissions from user
|
|
114
|
-
*/
|
|
115
|
-
async requestPermissions() {
|
|
116
|
-
if (!this.isLocationAvailable()) {
|
|
117
|
-
this.permissionStatus = 'denied';
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
try {
|
|
121
|
-
const { status } = await Location.requestForegroundPermissionsAsync();
|
|
122
|
-
this.permissionStatus = status === 'granted' ? 'granted' : 'denied';
|
|
123
|
-
return status === 'granted';
|
|
124
|
-
}
|
|
125
|
-
catch (error) {
|
|
126
|
-
this.permissionStatus = 'denied';
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Check if location permissions are granted
|
|
132
|
-
*/
|
|
133
|
-
async hasPermissions() {
|
|
134
|
-
if (!this.isLocationAvailable()) {
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
// Use cached permission status if available
|
|
138
|
-
if (this.permissionStatus !== 'unknown') {
|
|
139
|
-
return this.permissionStatus === 'granted';
|
|
140
|
-
}
|
|
141
|
-
try {
|
|
142
|
-
const { status } = await Location.getForegroundPermissionsAsync();
|
|
143
|
-
this.permissionStatus = status === 'granted' ? 'granted' : 'denied';
|
|
144
|
-
return status === 'granted';
|
|
145
|
-
}
|
|
146
|
-
catch (error) {
|
|
147
|
-
this.permissionStatus = 'denied';
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Get permission status without requesting
|
|
153
|
-
*/
|
|
154
|
-
getPermissionStatus() {
|
|
155
|
-
return this.permissionStatus;
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Get current location with fallback strategies
|
|
159
|
-
* Priority: High accuracy → Balanced accuracy → Cached location → null
|
|
160
|
-
*/
|
|
161
|
-
async getCurrentLocation() {
|
|
162
|
-
if (!this.isLocationAvailable()) {
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
try {
|
|
166
|
-
const hasPermission = await this.hasPermissions();
|
|
167
|
-
if (!hasPermission) {
|
|
168
|
-
const granted = await this.requestPermissions();
|
|
169
|
-
if (!granted) {
|
|
170
|
-
// Return cached location if available
|
|
171
|
-
return this.getCachedLocation();
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
// Try high accuracy first
|
|
175
|
-
let locationData = await this.getLocationWithAccuracy(Location.Accuracy.High, LOCATION_CONSTANTS.HIGH_ACCURACY_TIMEOUT);
|
|
176
|
-
// Fallback to balanced accuracy if high accuracy fails
|
|
177
|
-
if (!locationData) {
|
|
178
|
-
locationData = await this.getLocationWithAccuracy(Location.Accuracy.Balanced, LOCATION_CONSTANTS.BALANCED_ACCURACY_TIMEOUT);
|
|
179
|
-
}
|
|
180
|
-
// Fallback to cached location
|
|
181
|
-
if (!locationData) {
|
|
182
|
-
return this.getCachedLocation();
|
|
183
|
-
}
|
|
184
|
-
// Cache the new location
|
|
185
|
-
await this.saveCachedLocation(locationData);
|
|
186
|
-
return locationData;
|
|
187
|
-
}
|
|
188
|
-
catch (error) {
|
|
189
|
-
// Return cached location as last resort
|
|
190
|
-
return this.getCachedLocation();
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
/**
|
|
194
|
-
* Get location with specific accuracy and timeout
|
|
195
|
-
*/
|
|
196
|
-
async getLocationWithAccuracy(accuracy, timeout) {
|
|
197
|
-
try {
|
|
198
|
-
const location = (await Promise.race([
|
|
199
|
-
Location.getCurrentPositionAsync({ accuracy }),
|
|
200
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), timeout)),
|
|
201
|
-
]));
|
|
202
|
-
if (!location) {
|
|
203
|
-
return null;
|
|
204
|
-
}
|
|
205
|
-
const locationData = {
|
|
206
|
-
latitude: location.coords.latitude,
|
|
207
|
-
longitude: location.coords.longitude,
|
|
208
|
-
timestamp: Date.now(),
|
|
209
|
-
accuracy: location.coords.accuracy ?? undefined,
|
|
210
|
-
isCached: false,
|
|
211
|
-
};
|
|
212
|
-
// Try to get address (reverse geocoding)
|
|
213
|
-
try {
|
|
214
|
-
const addresses = await Location.reverseGeocodeAsync({
|
|
215
|
-
latitude: location.coords.latitude,
|
|
216
|
-
longitude: location.coords.longitude,
|
|
217
|
-
});
|
|
218
|
-
if (addresses && addresses.length > 0) {
|
|
219
|
-
const address = addresses[0];
|
|
220
|
-
const addressParts = [address.street, address.city, address.region].filter(Boolean);
|
|
221
|
-
locationData.address =
|
|
222
|
-
addressParts.join(', ') || 'Unknown location';
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
catch (error) {
|
|
226
|
-
// Fallback to coordinates if geocoding fails
|
|
227
|
-
locationData.address = `${location.coords.latitude.toFixed(LOCATION_CONSTANTS.COORDINATE_PRECISION)}, ${location.coords.longitude.toFixed(LOCATION_CONSTANTS.COORDINATE_PRECISION)}`;
|
|
228
|
-
}
|
|
229
|
-
return locationData;
|
|
230
|
-
}
|
|
231
|
-
catch (error) {
|
|
232
|
-
return null;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Format location for display (address or coordinates)
|
|
237
|
-
*/
|
|
238
|
-
formatLocation(location) {
|
|
239
|
-
if (location.address) {
|
|
240
|
-
return location.address;
|
|
241
|
-
}
|
|
242
|
-
return `${location.latitude.toFixed(LOCATION_CONSTANTS.COORDINATE_PRECISION)}, ${location.longitude.toFixed(LOCATION_CONSTANTS.COORDINATE_PRECISION)}`;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Singleton instance
|
|
247
|
-
* Use this for all location operations
|
|
248
|
-
*/
|
|
249
|
-
export const locationService = new LocationService();
|
|
250
|
-
//# sourceMappingURL=LocationService.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LocationService.js","sourceRoot":"","sources":["../../../src/infrastructure/services/LocationService.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useLocation Hook
|
|
3
|
-
*
|
|
4
|
-
* React hook for device location services
|
|
5
|
-
* Wraps locationService with React-friendly state management
|
|
6
|
-
*
|
|
7
|
-
* Features:
|
|
8
|
-
* - Get current location with loading state
|
|
9
|
-
* - Permission management
|
|
10
|
-
* - Cached location access
|
|
11
|
-
* - Error handling
|
|
12
|
-
* - Format locations for display
|
|
13
|
-
*
|
|
14
|
-
* USAGE:
|
|
15
|
-
* ```typescript
|
|
16
|
-
* import { useLocation } from '@umituz/react-native-location';
|
|
17
|
-
*
|
|
18
|
-
* const MyComponent = () => {
|
|
19
|
-
* const {
|
|
20
|
-
* location,
|
|
21
|
-
* loading,
|
|
22
|
-
* error,
|
|
23
|
-
* hasPermission,
|
|
24
|
-
* requestPermission,
|
|
25
|
-
* getCurrentLocation,
|
|
26
|
-
* getCached,
|
|
27
|
-
* formatLocation,
|
|
28
|
-
* } = useLocation();
|
|
29
|
-
*
|
|
30
|
-
* useEffect(() => {
|
|
31
|
-
* // Auto-fetch location on mount
|
|
32
|
-
* getCurrentLocation();
|
|
33
|
-
* }, []);
|
|
34
|
-
*
|
|
35
|
-
* if (loading) return <LoadingIndicator />;
|
|
36
|
-
* if (error) return <ErrorMessage message={error} />;
|
|
37
|
-
*
|
|
38
|
-
* return (
|
|
39
|
-
* <View>
|
|
40
|
-
* {location && (
|
|
41
|
-
* <Text>Location: {formatLocation(location)}</Text>
|
|
42
|
-
* )}
|
|
43
|
-
* <AtomicButton onPress={getCurrentLocation}>
|
|
44
|
-
* Refresh Location
|
|
45
|
-
* </AtomicButton>
|
|
46
|
-
* </View>
|
|
47
|
-
* );
|
|
48
|
-
* };
|
|
49
|
-
* ```
|
|
50
|
-
*/
|
|
51
|
-
import type { LocationData, LocationPermissionStatus } from '../../domain/entities/Location';
|
|
52
|
-
export interface UseLocationReturn {
|
|
53
|
-
/** Current location data (null if not retrieved) */
|
|
54
|
-
location: LocationData | null;
|
|
55
|
-
/** Loading state during location retrieval */
|
|
56
|
-
loading: boolean;
|
|
57
|
-
/** Error message if location retrieval failed */
|
|
58
|
-
error: string | null;
|
|
59
|
-
/** Current permission status */
|
|
60
|
-
permissionStatus: LocationPermissionStatus;
|
|
61
|
-
/** Whether location permissions are granted */
|
|
62
|
-
hasPermission: boolean;
|
|
63
|
-
/** Whether location services are available on this platform */
|
|
64
|
-
isAvailable: boolean;
|
|
65
|
-
/**
|
|
66
|
-
* Request location permissions from user
|
|
67
|
-
* @returns Promise resolving to true if granted
|
|
68
|
-
*/
|
|
69
|
-
requestPermission: () => Promise<boolean>;
|
|
70
|
-
/**
|
|
71
|
-
* Get current location with fallback strategies
|
|
72
|
-
* Updates location state and handles errors
|
|
73
|
-
*/
|
|
74
|
-
getCurrentLocation: () => Promise<void>;
|
|
75
|
-
/**
|
|
76
|
-
* Get cached location if available
|
|
77
|
-
* @returns Cached location or null
|
|
78
|
-
*/
|
|
79
|
-
getCached: () => LocationData | null;
|
|
80
|
-
/**
|
|
81
|
-
* Format location for display
|
|
82
|
-
* @param loc - LocationData to format
|
|
83
|
-
* @returns Formatted string (address or coordinates)
|
|
84
|
-
*/
|
|
85
|
-
formatLocation: (loc: LocationData) => string;
|
|
86
|
-
/**
|
|
87
|
-
* Clear current location state
|
|
88
|
-
*/
|
|
89
|
-
clearLocation: () => void;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Hook for device location services
|
|
93
|
-
*/
|
|
94
|
-
export declare const useLocation: () => UseLocationReturn;
|
|
95
|
-
//# sourceMappingURL=useLocation.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useLocation.d.ts","sourceRoot":"","sources":["../../../src/presentation/hooks/useLocation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAIH,OAAO,KAAK,EACV,YAAY,EACZ,wBAAwB,EACzB,MAAM,gCAAgC,CAAC;AAExC,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAE9B,8CAA8C;IAC9C,OAAO,EAAE,OAAO,CAAC;IAEjB,iDAAiD;IACjD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAErB,gCAAgC;IAChC,gBAAgB,EAAE,wBAAwB,CAAC;IAE3C,+CAA+C;IAC/C,aAAa,EAAE,OAAO,CAAC;IAEvB,+DAA+D;IAC/D,WAAW,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAE1C;;;OAGG;IACH,kBAAkB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;;OAGG;IACH,SAAS,EAAE,MAAM,YAAY,GAAG,IAAI,CAAC;IAErC;;;;OAIG;IACH,cAAc,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,MAAM,CAAC;IAE9C;;OAEG;IACH,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,QAAO,iBAiH9B,CAAC"}
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useLocation Hook
|
|
3
|
-
*
|
|
4
|
-
* React hook for device location services
|
|
5
|
-
* Wraps locationService with React-friendly state management
|
|
6
|
-
*
|
|
7
|
-
* Features:
|
|
8
|
-
* - Get current location with loading state
|
|
9
|
-
* - Permission management
|
|
10
|
-
* - Cached location access
|
|
11
|
-
* - Error handling
|
|
12
|
-
* - Format locations for display
|
|
13
|
-
*
|
|
14
|
-
* USAGE:
|
|
15
|
-
* ```typescript
|
|
16
|
-
* import { useLocation } from '@umituz/react-native-location';
|
|
17
|
-
*
|
|
18
|
-
* const MyComponent = () => {
|
|
19
|
-
* const {
|
|
20
|
-
* location,
|
|
21
|
-
* loading,
|
|
22
|
-
* error,
|
|
23
|
-
* hasPermission,
|
|
24
|
-
* requestPermission,
|
|
25
|
-
* getCurrentLocation,
|
|
26
|
-
* getCached,
|
|
27
|
-
* formatLocation,
|
|
28
|
-
* } = useLocation();
|
|
29
|
-
*
|
|
30
|
-
* useEffect(() => {
|
|
31
|
-
* // Auto-fetch location on mount
|
|
32
|
-
* getCurrentLocation();
|
|
33
|
-
* }, []);
|
|
34
|
-
*
|
|
35
|
-
* if (loading) return <LoadingIndicator />;
|
|
36
|
-
* if (error) return <ErrorMessage message={error} />;
|
|
37
|
-
*
|
|
38
|
-
* return (
|
|
39
|
-
* <View>
|
|
40
|
-
* {location && (
|
|
41
|
-
* <Text>Location: {formatLocation(location)}</Text>
|
|
42
|
-
* )}
|
|
43
|
-
* <AtomicButton onPress={getCurrentLocation}>
|
|
44
|
-
* Refresh Location
|
|
45
|
-
* </AtomicButton>
|
|
46
|
-
* </View>
|
|
47
|
-
* );
|
|
48
|
-
* };
|
|
49
|
-
* ```
|
|
50
|
-
*/
|
|
51
|
-
import { useState, useCallback, useEffect } from 'react';
|
|
52
|
-
import { locationService } from '../../infrastructure/services/LocationService';
|
|
53
|
-
/**
|
|
54
|
-
* Hook for device location services
|
|
55
|
-
*/
|
|
56
|
-
export const useLocation = () => {
|
|
57
|
-
const [location, setLocation] = useState(null);
|
|
58
|
-
const [loading, setLoading] = useState(false);
|
|
59
|
-
const [error, setError] = useState(null);
|
|
60
|
-
const [permissionStatus, setPermissionStatus] = useState('unknown');
|
|
61
|
-
// Check if location services are available
|
|
62
|
-
const isAvailable = locationService.isLocationAvailable();
|
|
63
|
-
// Check initial permission status
|
|
64
|
-
useEffect(() => {
|
|
65
|
-
const checkPermission = async () => {
|
|
66
|
-
const hasPermission = await locationService.hasPermissions();
|
|
67
|
-
setPermissionStatus(hasPermission ? 'granted' : locationService.getPermissionStatus());
|
|
68
|
-
};
|
|
69
|
-
if (isAvailable) {
|
|
70
|
-
checkPermission();
|
|
71
|
-
}
|
|
72
|
-
}, [isAvailable]);
|
|
73
|
-
/**
|
|
74
|
-
* Request location permissions
|
|
75
|
-
*/
|
|
76
|
-
const requestPermission = useCallback(async () => {
|
|
77
|
-
if (!isAvailable) {
|
|
78
|
-
setError('Location services not available on this platform');
|
|
79
|
-
setPermissionStatus('denied');
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
try {
|
|
83
|
-
const granted = await locationService.requestPermissions();
|
|
84
|
-
setPermissionStatus(granted ? 'granted' : 'denied');
|
|
85
|
-
if (!granted) {
|
|
86
|
-
setError('Location permission denied');
|
|
87
|
-
}
|
|
88
|
-
return granted;
|
|
89
|
-
}
|
|
90
|
-
catch (err) {
|
|
91
|
-
setError('Failed to request location permission');
|
|
92
|
-
setPermissionStatus('denied');
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
|
-
}, [isAvailable]);
|
|
96
|
-
/**
|
|
97
|
-
* Get current location with fallback strategies
|
|
98
|
-
*/
|
|
99
|
-
const getCurrentLocation = useCallback(async () => {
|
|
100
|
-
if (!isAvailable) {
|
|
101
|
-
setError('Location services not available on this platform');
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
setLoading(true);
|
|
105
|
-
setError(null);
|
|
106
|
-
try {
|
|
107
|
-
const currentLocation = await locationService.getCurrentLocation();
|
|
108
|
-
if (currentLocation) {
|
|
109
|
-
setLocation(currentLocation);
|
|
110
|
-
setError(null);
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
setError('Unable to retrieve location');
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
catch (err) {
|
|
117
|
-
setError('Failed to get location');
|
|
118
|
-
}
|
|
119
|
-
finally {
|
|
120
|
-
setLoading(false);
|
|
121
|
-
}
|
|
122
|
-
}, [isAvailable]);
|
|
123
|
-
/**
|
|
124
|
-
* Get cached location
|
|
125
|
-
*/
|
|
126
|
-
const getCached = useCallback(() => {
|
|
127
|
-
return locationService.getCachedLocation();
|
|
128
|
-
}, []);
|
|
129
|
-
/**
|
|
130
|
-
* Format location for display
|
|
131
|
-
*/
|
|
132
|
-
const formatLocation = useCallback((loc) => {
|
|
133
|
-
return locationService.formatLocation(loc);
|
|
134
|
-
}, []);
|
|
135
|
-
/**
|
|
136
|
-
* Clear location state
|
|
137
|
-
*/
|
|
138
|
-
const clearLocation = useCallback(() => {
|
|
139
|
-
setLocation(null);
|
|
140
|
-
setError(null);
|
|
141
|
-
}, []);
|
|
142
|
-
return {
|
|
143
|
-
location,
|
|
144
|
-
loading,
|
|
145
|
-
error,
|
|
146
|
-
permissionStatus,
|
|
147
|
-
hasPermission: permissionStatus === 'granted',
|
|
148
|
-
isAvailable,
|
|
149
|
-
requestPermission,
|
|
150
|
-
getCurrentLocation,
|
|
151
|
-
getCached,
|
|
152
|
-
formatLocation,
|
|
153
|
-
clearLocation,
|
|
154
|
-
};
|
|
155
|
-
};
|
|
156
|
-
//# sourceMappingURL=useLocation.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useLocation.js","sourceRoot":"","sources":["../../../src/presentation/hooks/useLocation.ts"],"names":[],"mappings":"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"}
|