react-native-nitro-geolocation 0.2.0 → 0.4.0
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/api/checkPermission.ts +21 -0
- package/src/api/getCurrentPosition.ts +35 -0
- package/src/api/index.ts +7 -0
- package/src/api/requestPermission.ts +21 -0
- package/src/api/setConfiguration.ts +31 -0
- package/src/api/stopObserving.ts +22 -0
- package/src/api/unwatch.ts +18 -0
- package/src/api/watchPosition.ts +38 -0
- package/src/hooks/index.ts +4 -6
- package/src/hooks/useWatchPosition.ts +32 -31
- package/src/index.tsx +34 -34
- package/src/GeolocationClient.ts +0 -116
- package/src/components/GeolocationProvider.tsx +0 -91
- package/src/components/index.ts +0 -13
- package/src/hooks/useCheckPermission.ts +0 -46
- package/src/hooks/useGetCurrentPosition.ts +0 -44
- package/src/hooks/useRequestPermission.ts +0 -38
package/package.json
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PermissionStatus } from "../NitroGeolocation.nitro";
|
|
2
|
+
import { NitroGeolocationHybridObject } from "../NitroGeolocationModule";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Check current location permission status.
|
|
6
|
+
* Does NOT request permission, only checks current state.
|
|
7
|
+
*
|
|
8
|
+
* @returns Promise resolving to current permission status
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import { checkPermission } from 'react-native-nitro-geolocation';
|
|
12
|
+
*
|
|
13
|
+
* const status = await checkPermission();
|
|
14
|
+
* if (status === 'granted') {
|
|
15
|
+
* // Get location
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export function checkPermission(): Promise<PermissionStatus> {
|
|
20
|
+
return NitroGeolocationHybridObject.checkPermission();
|
|
21
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { LocationRequestOptions } from "../NitroGeolocation.nitro";
|
|
2
|
+
import { NitroGeolocationHybridObject } from "../NitroGeolocationModule";
|
|
3
|
+
import type { GeolocationResponse } from "../types";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Get current location (one-time request).
|
|
7
|
+
*
|
|
8
|
+
* Strategy:
|
|
9
|
+
* 1. Check cached location (if maximumAge allows)
|
|
10
|
+
* 2. Request fresh location from GPS/Network
|
|
11
|
+
* 3. Timeout after specified duration
|
|
12
|
+
*
|
|
13
|
+
* @param options - Location request options
|
|
14
|
+
* @returns Promise resolving to current position
|
|
15
|
+
* @throws LocationError if permission denied, timeout, or unavailable
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* import { getCurrentPosition } from 'react-native-nitro-geolocation';
|
|
19
|
+
*
|
|
20
|
+
* try {
|
|
21
|
+
* const position = await getCurrentPosition({
|
|
22
|
+
* enableHighAccuracy: true,
|
|
23
|
+
* timeout: 15000
|
|
24
|
+
* });
|
|
25
|
+
* console.log(position.coords.latitude, position.coords.longitude);
|
|
26
|
+
* } catch (error) {
|
|
27
|
+
* console.error(error.message);
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export function getCurrentPosition(
|
|
32
|
+
options?: LocationRequestOptions
|
|
33
|
+
): Promise<GeolocationResponse> {
|
|
34
|
+
return NitroGeolocationHybridObject.getCurrentPosition(options);
|
|
35
|
+
}
|
package/src/api/index.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { setConfiguration } from "./setConfiguration";
|
|
2
|
+
export { checkPermission } from "./checkPermission";
|
|
3
|
+
export { requestPermission } from "./requestPermission";
|
|
4
|
+
export { getCurrentPosition } from "./getCurrentPosition";
|
|
5
|
+
export { watchPosition } from "./watchPosition";
|
|
6
|
+
export { unwatch } from "./unwatch";
|
|
7
|
+
export { stopObserving } from "./stopObserving";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PermissionStatus } from "../NitroGeolocation.nitro";
|
|
2
|
+
import { NitroGeolocationHybridObject } from "../NitroGeolocationModule";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Request location permission from the user.
|
|
6
|
+
* Shows system permission dialog if not yet determined.
|
|
7
|
+
*
|
|
8
|
+
* @returns Promise resolving to new permission status
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import { requestPermission } from 'react-native-nitro-geolocation';
|
|
12
|
+
*
|
|
13
|
+
* const status = await requestPermission();
|
|
14
|
+
* if (status === 'granted') {
|
|
15
|
+
* // Get location
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export function requestPermission(): Promise<PermissionStatus> {
|
|
20
|
+
return NitroGeolocationHybridObject.requestPermission();
|
|
21
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ModernGeolocationConfiguration as NitroModernGeolocationConfiguration } from "../NitroGeolocation.nitro";
|
|
2
|
+
import { NitroGeolocationHybridObject } from "../NitroGeolocationModule";
|
|
3
|
+
import type { ModernGeolocationConfiguration } from "../types";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Set global geolocation configuration.
|
|
7
|
+
* Should be called once at app startup.
|
|
8
|
+
*
|
|
9
|
+
* @param config - Platform-specific configuration
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import { setConfiguration } from 'react-native-nitro-geolocation';
|
|
13
|
+
*
|
|
14
|
+
* setConfiguration({
|
|
15
|
+
* authorizationLevel: 'whenInUse',
|
|
16
|
+
* enableBackgroundLocationUpdates: false,
|
|
17
|
+
* locationProvider: 'auto'
|
|
18
|
+
* });
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function setConfiguration(config: ModernGeolocationConfiguration): void {
|
|
22
|
+
const nativeConfig: NitroModernGeolocationConfiguration = {
|
|
23
|
+
...config,
|
|
24
|
+
locationProvider:
|
|
25
|
+
config.locationProvider === "android"
|
|
26
|
+
? "android_platform"
|
|
27
|
+
: config.locationProvider
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
NitroGeolocationHybridObject.setConfiguration(nativeConfig);
|
|
31
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { NitroGeolocationHybridObject } from "../NitroGeolocationModule";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Stop ALL watch subscriptions immediately.
|
|
5
|
+
*
|
|
6
|
+
* Use cases:
|
|
7
|
+
* - Emergency cleanup
|
|
8
|
+
* - App termination
|
|
9
|
+
* - User logout
|
|
10
|
+
*
|
|
11
|
+
* Note: Individual subscriptions should use unwatch() instead.
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* import { stopObserving } from 'react-native-nitro-geolocation';
|
|
15
|
+
*
|
|
16
|
+
* // Stop all location tracking
|
|
17
|
+
* stopObserving();
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export function stopObserving(): void {
|
|
21
|
+
NitroGeolocationHybridObject.stopObserving();
|
|
22
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { NitroGeolocationHybridObject } from "../NitroGeolocationModule";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Stop a specific watch subscription.
|
|
5
|
+
*
|
|
6
|
+
* @param token - Subscription token from watchPosition()
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { watchPosition, unwatch } from 'react-native-nitro-geolocation';
|
|
10
|
+
*
|
|
11
|
+
* const token = watchPosition((position) => console.log(position));
|
|
12
|
+
* // Later...
|
|
13
|
+
* unwatch(token);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export function unwatch(token: string): void {
|
|
17
|
+
NitroGeolocationHybridObject.unwatch(token);
|
|
18
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
LocationError,
|
|
3
|
+
LocationRequestOptions
|
|
4
|
+
} from "../NitroGeolocation.nitro";
|
|
5
|
+
import { NitroGeolocationHybridObject } from "../NitroGeolocationModule";
|
|
6
|
+
import type { GeolocationResponse } from "../types";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Start watching for continuous location updates.
|
|
10
|
+
*
|
|
11
|
+
* IMPORTANT: This is a LOW-LEVEL API.
|
|
12
|
+
* For React components, use useWatchPosition() hook instead.
|
|
13
|
+
*
|
|
14
|
+
* @param success - Called on each successful location update
|
|
15
|
+
* @param error - Called when an error occurs
|
|
16
|
+
* @param options - Location request options
|
|
17
|
+
* @returns Subscription token (UUID string) for cleanup
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* import { watchPosition, unwatch } from 'react-native-nitro-geolocation';
|
|
21
|
+
*
|
|
22
|
+
* const token = watchPosition(
|
|
23
|
+
* (position) => console.log(position.coords),
|
|
24
|
+
* (error) => console.error(error.message),
|
|
25
|
+
* { enableHighAccuracy: true, distanceFilter: 10 }
|
|
26
|
+
* );
|
|
27
|
+
*
|
|
28
|
+
* // Later: cleanup
|
|
29
|
+
* unwatch(token);
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function watchPosition(
|
|
33
|
+
success: (position: GeolocationResponse) => void,
|
|
34
|
+
error?: (error: LocationError) => void,
|
|
35
|
+
options?: LocationRequestOptions
|
|
36
|
+
): string {
|
|
37
|
+
return NitroGeolocationHybridObject.watchPosition(success, error, options);
|
|
38
|
+
}
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* React hook for geolocation.
|
|
3
|
+
* Provides a declarative API for continuous location tracking.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export * from "./useGetCurrentPosition";
|
|
9
|
-
export * from "./useWatchPosition";
|
|
6
|
+
export { useWatchPosition } from "./useWatchPosition";
|
|
7
|
+
export type { UseWatchPositionOptions } from "./useWatchPosition";
|
|
@@ -3,7 +3,7 @@ import type {
|
|
|
3
3
|
LocationError,
|
|
4
4
|
LocationRequestOptions
|
|
5
5
|
} from "../NitroGeolocation.nitro";
|
|
6
|
-
import {
|
|
6
|
+
import { NitroGeolocationHybridObject } from "../NitroGeolocationModule";
|
|
7
7
|
import type { GeolocationResponse } from "../types";
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -26,12 +26,12 @@ export interface UseWatchPositionOptions extends LocationRequestOptions {
|
|
|
26
26
|
* Cleanup is automatic via useEffect.
|
|
27
27
|
*
|
|
28
28
|
* @param options - Location request options
|
|
29
|
-
* @returns Object containing current position
|
|
29
|
+
* @returns Object containing current position, error, and watching status
|
|
30
30
|
*
|
|
31
31
|
* @example
|
|
32
32
|
* ```tsx
|
|
33
33
|
* function LiveTracking() {
|
|
34
|
-
* const {
|
|
34
|
+
* const { position, error, isWatching } = useWatchPosition({
|
|
35
35
|
* enabled: true,
|
|
36
36
|
* enableHighAccuracy: true,
|
|
37
37
|
* distanceFilter: 10 // Update every 10 meters
|
|
@@ -39,22 +39,21 @@ export interface UseWatchPositionOptions extends LocationRequestOptions {
|
|
|
39
39
|
*
|
|
40
40
|
* if (!isWatching) return <Text>Not watching</Text>;
|
|
41
41
|
* if (error) return <Text>Error: {error.message}</Text>;
|
|
42
|
-
* if (!
|
|
42
|
+
* if (!position) return <Text>Waiting for location...</Text>;
|
|
43
43
|
*
|
|
44
44
|
* return (
|
|
45
45
|
* <Text>
|
|
46
|
-
* Current: {
|
|
47
|
-
* Accuracy: {
|
|
46
|
+
* Current: {position.coords.latitude}, {position.coords.longitude}
|
|
47
|
+
* Accuracy: {position.coords.accuracy}m
|
|
48
48
|
* </Text>
|
|
49
49
|
* );
|
|
50
50
|
* }
|
|
51
51
|
* ```
|
|
52
52
|
*/
|
|
53
53
|
export function useWatchPosition(options?: UseWatchPositionOptions) {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
const [data, setData] = useState<GeolocationResponse | null>(null);
|
|
54
|
+
const [position, setPosition] = useState<GeolocationResponse | null>(null);
|
|
57
55
|
const [isWatching, setIsWatching] = useState(false);
|
|
56
|
+
const [error, setError] = useState<LocationError | null>(null);
|
|
58
57
|
|
|
59
58
|
// Store subscription token (hidden from user!)
|
|
60
59
|
const tokenRef = useRef<string | null>(null);
|
|
@@ -62,34 +61,45 @@ export function useWatchPosition(options?: UseWatchPositionOptions) {
|
|
|
62
61
|
// Track if component is mounted to prevent state updates after unmount
|
|
63
62
|
const isMountedRef = useRef(true);
|
|
64
63
|
|
|
64
|
+
// Store latest options in ref to avoid unnecessary re-subscriptions
|
|
65
|
+
const optionsRef = useRef(options);
|
|
66
|
+
|
|
67
|
+
// Update options ref whenever options change
|
|
65
68
|
useEffect(() => {
|
|
66
|
-
|
|
69
|
+
optionsRef.current = options;
|
|
70
|
+
}, [options]);
|
|
67
71
|
|
|
72
|
+
// Extract enabled flag for reactive dependency
|
|
73
|
+
const enabled = options?.enabled ?? false;
|
|
74
|
+
|
|
75
|
+
useEffect(() => {
|
|
68
76
|
if (!enabled) {
|
|
69
77
|
// Not enabled, ensure cleanup
|
|
70
78
|
if (tokenRef.current) {
|
|
71
|
-
|
|
79
|
+
NitroGeolocationHybridObject.unwatch(tokenRef.current);
|
|
72
80
|
tokenRef.current = null;
|
|
73
81
|
}
|
|
74
82
|
setIsWatching(false);
|
|
75
83
|
return;
|
|
76
84
|
}
|
|
77
85
|
|
|
78
|
-
// Start watching
|
|
86
|
+
// Start watching with latest options
|
|
79
87
|
setIsWatching(true);
|
|
88
|
+
setError(null);
|
|
80
89
|
|
|
81
|
-
const token =
|
|
82
|
-
(
|
|
90
|
+
const token = NitroGeolocationHybridObject.watchPosition(
|
|
91
|
+
(result: GeolocationResponse) => {
|
|
83
92
|
// Success callback
|
|
84
93
|
if (!isMountedRef.current) return;
|
|
85
|
-
|
|
94
|
+
setPosition(result);
|
|
95
|
+
setError(null);
|
|
86
96
|
},
|
|
87
97
|
(err: LocationError) => {
|
|
88
|
-
// Error callback
|
|
98
|
+
// Error callback
|
|
89
99
|
if (!isMountedRef.current) return;
|
|
90
|
-
|
|
100
|
+
setError(err);
|
|
91
101
|
},
|
|
92
|
-
|
|
102
|
+
optionsRef.current
|
|
93
103
|
);
|
|
94
104
|
|
|
95
105
|
tokenRef.current = token;
|
|
@@ -97,20 +107,10 @@ export function useWatchPosition(options?: UseWatchPositionOptions) {
|
|
|
97
107
|
// Cleanup function
|
|
98
108
|
return () => {
|
|
99
109
|
if (token) {
|
|
100
|
-
|
|
110
|
+
NitroGeolocationHybridObject.unwatch(token);
|
|
101
111
|
}
|
|
102
112
|
};
|
|
103
|
-
}, [
|
|
104
|
-
client,
|
|
105
|
-
options?.enabled,
|
|
106
|
-
options?.enableHighAccuracy,
|
|
107
|
-
options?.distanceFilter,
|
|
108
|
-
options?.interval,
|
|
109
|
-
options?.fastestInterval,
|
|
110
|
-
options?.timeout,
|
|
111
|
-
options?.maximumAge,
|
|
112
|
-
options?.useSignificantChanges
|
|
113
|
-
]);
|
|
113
|
+
}, [enabled]); // Only re-subscribe when enabled changes
|
|
114
114
|
|
|
115
115
|
// Track mount status
|
|
116
116
|
useEffect(() => {
|
|
@@ -121,7 +121,8 @@ export function useWatchPosition(options?: UseWatchPositionOptions) {
|
|
|
121
121
|
}, []);
|
|
122
122
|
|
|
123
123
|
return {
|
|
124
|
-
|
|
124
|
+
position,
|
|
125
|
+
error,
|
|
125
126
|
isWatching
|
|
126
127
|
};
|
|
127
128
|
}
|
package/src/index.tsx
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Modern Geolocation API for React Native.
|
|
3
3
|
*
|
|
4
|
-
* This is the main entry point for the modern,
|
|
4
|
+
* This is the main entry point for the modern, functional API.
|
|
5
5
|
* For legacy compatibility, use: import Geolocation from 'react-native-nitro-geolocation/compat'
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
8
|
* ```tsx
|
|
9
9
|
* import {
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* useGetCurrentPosition,
|
|
10
|
+
* setConfiguration,
|
|
11
|
+
* getCurrentPosition,
|
|
12
|
+
* requestPermission,
|
|
14
13
|
* useWatchPosition
|
|
15
14
|
* } from 'react-native-nitro-geolocation';
|
|
16
15
|
*
|
|
17
|
-
* //
|
|
18
|
-
*
|
|
16
|
+
* // Set configuration at app startup
|
|
17
|
+
* setConfiguration({
|
|
19
18
|
* authorizationLevel: 'whenInUse',
|
|
20
19
|
* enableBackgroundLocationUpdates: false,
|
|
21
20
|
* locationProvider: 'auto'
|
|
22
21
|
* });
|
|
23
22
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
23
|
+
* // Request permission
|
|
24
|
+
* async function setup() {
|
|
25
|
+
* const status = await requestPermission();
|
|
26
|
+
* if (status === 'granted') {
|
|
27
|
+
* const position = await getCurrentPosition({ enableHighAccuracy: true });
|
|
28
|
+
* console.log('Position:', position);
|
|
29
|
+
* }
|
|
30
30
|
* }
|
|
31
31
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* const
|
|
32
|
+
* // Continuous tracking in React component
|
|
33
|
+
* function LiveTracking() {
|
|
34
|
+
* const { position, error, isWatching } = useWatchPosition({
|
|
35
|
+
* enabled: true,
|
|
36
|
+
* enableHighAccuracy: true,
|
|
37
|
+
* distanceFilter: 10
|
|
38
|
+
* });
|
|
35
39
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* const pos = await getCurrentPosition({ enableHighAccuracy: true });
|
|
40
|
-
* console.log('Position:', pos);
|
|
41
|
-
* } catch (error) {
|
|
42
|
-
* console.error('Error:', error);
|
|
43
|
-
* } finally {
|
|
44
|
-
* setLoading(false);
|
|
45
|
-
* }
|
|
46
|
-
* };
|
|
40
|
+
* if (!isWatching) return <Text>Not watching</Text>;
|
|
41
|
+
* if (error) return <Text>Error: {error.message}</Text>;
|
|
42
|
+
* if (!position) return <Text>Waiting...</Text>;
|
|
47
43
|
*
|
|
48
|
-
* return <
|
|
44
|
+
* return <Text>Lat: {position.coords.latitude}</Text>;
|
|
49
45
|
* }
|
|
50
46
|
* ```
|
|
51
47
|
*/
|
|
52
48
|
|
|
53
|
-
// Core
|
|
54
|
-
export {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
49
|
+
// Core API functions
|
|
50
|
+
export {
|
|
51
|
+
setConfiguration,
|
|
52
|
+
checkPermission,
|
|
53
|
+
requestPermission,
|
|
54
|
+
getCurrentPosition,
|
|
55
|
+
watchPosition,
|
|
56
|
+
unwatch,
|
|
57
|
+
stopObserving
|
|
58
|
+
} from "./api";
|
|
59
59
|
|
|
60
60
|
// Hooks
|
|
61
61
|
export * from "./hooks";
|
package/src/GeolocationClient.ts
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
LocationError,
|
|
3
|
-
LocationRequestOptions,
|
|
4
|
-
ModernGeolocationConfiguration as NitroModernGeolocationConfiguration,
|
|
5
|
-
PermissionStatus
|
|
6
|
-
} from "./NitroGeolocation.nitro";
|
|
7
|
-
import { NitroGeolocationHybridObject } from "./NitroGeolocationModule";
|
|
8
|
-
import type { ModernGeolocationConfiguration } from "./types";
|
|
9
|
-
import type { GeolocationResponse } from "./types";
|
|
10
|
-
|
|
11
|
-
export interface GeolocationClientConfig
|
|
12
|
-
extends ModernGeolocationConfiguration {}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* GeolocationClient provides direct access to geolocation methods.
|
|
16
|
-
*
|
|
17
|
-
* Usage:
|
|
18
|
-
* ```tsx
|
|
19
|
-
* // With provider
|
|
20
|
-
* const client = new GeolocationClient({ locationProvider: 'auto' });
|
|
21
|
-
* <GeolocationClientProvider client={client}>
|
|
22
|
-
* <App />
|
|
23
|
-
* </GeolocationClientProvider>
|
|
24
|
-
*
|
|
25
|
-
* // Without provider
|
|
26
|
-
* const standaloneClient = new GeolocationClient();
|
|
27
|
-
* await standaloneClient.getCurrentPosition();
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
export class GeolocationClient {
|
|
31
|
-
private config: GeolocationClientConfig;
|
|
32
|
-
|
|
33
|
-
constructor(config: GeolocationClientConfig = {}) {
|
|
34
|
-
this.config = config;
|
|
35
|
-
|
|
36
|
-
// Set configuration on Nitro module
|
|
37
|
-
if (Object.keys(config).length > 0) {
|
|
38
|
-
const nativeConfig: NitroModernGeolocationConfiguration = {
|
|
39
|
-
...config,
|
|
40
|
-
locationProvider:
|
|
41
|
-
config.locationProvider === "android"
|
|
42
|
-
? "android_platform"
|
|
43
|
-
: config.locationProvider
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
NitroGeolocationHybridObject.setConfiguration(nativeConfig);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Check current location permission status.
|
|
52
|
-
* Does NOT request permission, only checks current state.
|
|
53
|
-
*/
|
|
54
|
-
checkPermission = (): Promise<PermissionStatus> => {
|
|
55
|
-
return NitroGeolocationHybridObject.checkPermission();
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Request location permission from the user.
|
|
60
|
-
* Shows system permission dialog if not yet determined.
|
|
61
|
-
*/
|
|
62
|
-
requestPermission = (): Promise<PermissionStatus> => {
|
|
63
|
-
return NitroGeolocationHybridObject.requestPermission();
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Get current location (one-time request).
|
|
68
|
-
*
|
|
69
|
-
* @param options - Location request options
|
|
70
|
-
* @returns Promise resolving to current position
|
|
71
|
-
*/
|
|
72
|
-
getCurrentPosition = (
|
|
73
|
-
options?: LocationRequestOptions
|
|
74
|
-
): Promise<GeolocationResponse> => {
|
|
75
|
-
return NitroGeolocationHybridObject.getCurrentPosition(options);
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Start watching for continuous location updates.
|
|
80
|
-
*
|
|
81
|
-
* @param success - Called on each successful location update
|
|
82
|
-
* @param error - Called when an error occurs
|
|
83
|
-
* @param options - Location request options
|
|
84
|
-
* @returns Subscription token (UUID string) for cleanup
|
|
85
|
-
*/
|
|
86
|
-
watchPosition = (
|
|
87
|
-
success: (position: GeolocationResponse) => void,
|
|
88
|
-
error?: (error: LocationError) => void,
|
|
89
|
-
options?: LocationRequestOptions
|
|
90
|
-
): string => {
|
|
91
|
-
return NitroGeolocationHybridObject.watchPosition(success, error, options);
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Stop a specific watch subscription.
|
|
96
|
-
*
|
|
97
|
-
* @param token - Subscription token from watchPosition()
|
|
98
|
-
*/
|
|
99
|
-
unwatch = (token: string): void => {
|
|
100
|
-
NitroGeolocationHybridObject.unwatch(token);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Stop ALL watch subscriptions immediately.
|
|
105
|
-
*/
|
|
106
|
-
stopObserving = (): void => {
|
|
107
|
-
NitroGeolocationHybridObject.stopObserving();
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Get the current client configuration.
|
|
112
|
-
*/
|
|
113
|
-
getConfig = (): Readonly<GeolocationClientConfig> => {
|
|
114
|
-
return { ...this.config };
|
|
115
|
-
};
|
|
116
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import React, { createContext, useContext } from "react";
|
|
2
|
-
import type { GeolocationClient } from "../GeolocationClient";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Geolocation context value.
|
|
6
|
-
*/
|
|
7
|
-
export interface GeolocationContextValue {
|
|
8
|
-
client: GeolocationClient;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Geolocation context.
|
|
13
|
-
*/
|
|
14
|
-
const GeolocationContext = createContext<GeolocationContextValue | null>(null);
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Hook to access GeolocationClient from context.
|
|
18
|
-
* Throws error if used outside GeolocationClientProvider.
|
|
19
|
-
*/
|
|
20
|
-
export function useGeolocationClient(): GeolocationClient {
|
|
21
|
-
const context = useContext(GeolocationContext);
|
|
22
|
-
|
|
23
|
-
if (!context) {
|
|
24
|
-
throw new Error(
|
|
25
|
-
"useGeolocationClient must be used within GeolocationClientProvider. " +
|
|
26
|
-
"Wrap your component with <GeolocationClientProvider client={...}> at the root level."
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return context.client;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Props for GeolocationProvider component.
|
|
35
|
-
*/
|
|
36
|
-
export interface GeolocationProviderProps {
|
|
37
|
-
/**
|
|
38
|
-
* GeolocationClient instance (required).
|
|
39
|
-
* Create with: new GeolocationClient({...config})
|
|
40
|
-
*/
|
|
41
|
-
client: GeolocationClient;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Child components that can use geolocation hooks.
|
|
45
|
-
*/
|
|
46
|
-
children: React.ReactNode;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Provider component for GeolocationClient.
|
|
51
|
-
*
|
|
52
|
-
* This component should wrap your app at the root level.
|
|
53
|
-
* It provides a GeolocationClient instance to all child components via context.
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* ```tsx
|
|
57
|
-
* // Create client instance
|
|
58
|
-
* const geolocationClient = new GeolocationClient({
|
|
59
|
-
* authorizationLevel: 'whenInUse',
|
|
60
|
-
* enableBackgroundLocationUpdates: false,
|
|
61
|
-
* locationProvider: 'auto'
|
|
62
|
-
* });
|
|
63
|
-
*
|
|
64
|
-
* function App() {
|
|
65
|
-
* return (
|
|
66
|
-
* <GeolocationClientProvider client={geolocationClient}>
|
|
67
|
-
* <NavigationContainer>
|
|
68
|
-
* <YourApp />
|
|
69
|
-
* </NavigationContainer>
|
|
70
|
-
* </GeolocationClientProvider>
|
|
71
|
-
* );
|
|
72
|
-
* }
|
|
73
|
-
* ```
|
|
74
|
-
*/
|
|
75
|
-
export function GeolocationProvider({
|
|
76
|
-
client,
|
|
77
|
-
children
|
|
78
|
-
}: GeolocationProviderProps) {
|
|
79
|
-
const value: GeolocationContextValue = {
|
|
80
|
-
client
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
return (
|
|
84
|
-
<GeolocationContext.Provider value={value}>
|
|
85
|
-
{children}
|
|
86
|
-
</GeolocationContext.Provider>
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Modern alias (preferred)
|
|
91
|
-
export const GeolocationClientProvider = GeolocationProvider;
|
package/src/components/index.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* React components for geolocation.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export {
|
|
6
|
-
GeolocationProvider,
|
|
7
|
-
GeolocationClientProvider,
|
|
8
|
-
useGeolocationClient
|
|
9
|
-
} from "./GeolocationProvider";
|
|
10
|
-
export type {
|
|
11
|
-
GeolocationProviderProps,
|
|
12
|
-
GeolocationContextValue
|
|
13
|
-
} from "./GeolocationProvider";
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import type { PermissionStatus } from "../NitroGeolocation.nitro";
|
|
2
|
-
import { useGeolocationClient } from "../components/GeolocationProvider";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Hook that returns a function to check current location permission status.
|
|
6
|
-
* Does NOT request permission, only checks current state.
|
|
7
|
-
*
|
|
8
|
-
* Must be used within GeolocationClientProvider.
|
|
9
|
-
*
|
|
10
|
-
* @returns Object containing checkPermission function
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```tsx
|
|
14
|
-
* const geolocationClient = new GeolocationClient({...config});
|
|
15
|
-
*
|
|
16
|
-
* function App() {
|
|
17
|
-
* return (
|
|
18
|
-
* <GeolocationClientProvider client={geolocationClient}>
|
|
19
|
-
* <MyComponent />
|
|
20
|
-
* </GeolocationClientProvider>
|
|
21
|
-
* );
|
|
22
|
-
* }
|
|
23
|
-
*
|
|
24
|
-
* function MyComponent() {
|
|
25
|
-
* const { checkPermission } = useCheckPermission();
|
|
26
|
-
*
|
|
27
|
-
* const handleCheck = async () => {
|
|
28
|
-
* const status = await checkPermission();
|
|
29
|
-
* if (status === 'granted') {
|
|
30
|
-
* // Can use location
|
|
31
|
-
* }
|
|
32
|
-
* };
|
|
33
|
-
*
|
|
34
|
-
* return <Button onPress={handleCheck} />;
|
|
35
|
-
* }
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
export function useCheckPermission() {
|
|
39
|
-
const client = useGeolocationClient();
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
checkPermission: (): Promise<PermissionStatus> => {
|
|
43
|
-
return client.checkPermission();
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type { LocationRequestOptions } from "../NitroGeolocation.nitro";
|
|
2
|
-
import { useGeolocationClient } from "../components/GeolocationProvider";
|
|
3
|
-
import type { GeolocationResponse } from "../types";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Hook that returns a function to get current location (one-time request).
|
|
7
|
-
* The returned function throws error if permission denied, timeout, or unavailable.
|
|
8
|
-
*
|
|
9
|
-
* @returns Object containing getCurrentPosition function
|
|
10
|
-
* @throws LocationError with code and message
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```tsx
|
|
14
|
-
* function MyComponent() {
|
|
15
|
-
* const { getCurrentPosition } = useGetCurrentPosition();
|
|
16
|
-
*
|
|
17
|
-
* const handleGetLocation = async () => {
|
|
18
|
-
* try {
|
|
19
|
-
* const position = await getCurrentPosition({
|
|
20
|
-
* enableHighAccuracy: true,
|
|
21
|
-
* timeout: 15000,
|
|
22
|
-
* });
|
|
23
|
-
* console.log('Lat:', position.coords.latitude);
|
|
24
|
-
* console.log('Lng:', position.coords.longitude);
|
|
25
|
-
* } catch (error) {
|
|
26
|
-
* console.error('Location error:', error.message);
|
|
27
|
-
* }
|
|
28
|
-
* };
|
|
29
|
-
*
|
|
30
|
-
* return <Button onPress={handleGetLocation} />;
|
|
31
|
-
* }
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
34
|
-
export function useGetCurrentPosition() {
|
|
35
|
-
const client = useGeolocationClient();
|
|
36
|
-
|
|
37
|
-
return {
|
|
38
|
-
getCurrentPosition: (
|
|
39
|
-
options?: LocationRequestOptions
|
|
40
|
-
): Promise<GeolocationResponse> => {
|
|
41
|
-
return client.getCurrentPosition(options);
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { PermissionStatus } from "../NitroGeolocation.nitro";
|
|
2
|
-
import { useGeolocationClient } from "../components/GeolocationProvider";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Hook that returns a function to request location permission from the user.
|
|
6
|
-
* Shows system permission dialog if not yet determined.
|
|
7
|
-
*
|
|
8
|
-
* @returns Object containing requestPermission function
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```tsx
|
|
12
|
-
* function MyComponent() {
|
|
13
|
-
* const { requestPermission } = useRequestPermission();
|
|
14
|
-
*
|
|
15
|
-
* const handleRequest = async () => {
|
|
16
|
-
* try {
|
|
17
|
-
* const status = await requestPermission();
|
|
18
|
-
* if (status === 'granted') {
|
|
19
|
-
* console.log('Permission granted!');
|
|
20
|
-
* }
|
|
21
|
-
* } catch (error) {
|
|
22
|
-
* console.error('Permission error:', error);
|
|
23
|
-
* }
|
|
24
|
-
* };
|
|
25
|
-
*
|
|
26
|
-
* return <Button onPress={handleRequest} />;
|
|
27
|
-
* }
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
export function useRequestPermission() {
|
|
31
|
-
const client = useGeolocationClient();
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
requestPermission: (): Promise<PermissionStatus> => {
|
|
35
|
-
return client.requestPermission();
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
}
|