react-native-nitro-geolocation 0.3.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 +5 -7
- 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 -140
- package/src/hooks/useRequestPermission.ts +0 -98
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
|
/**
|
|
@@ -51,8 +51,6 @@ export interface UseWatchPositionOptions extends LocationRequestOptions {
|
|
|
51
51
|
* ```
|
|
52
52
|
*/
|
|
53
53
|
export function useWatchPosition(options?: UseWatchPositionOptions) {
|
|
54
|
-
const client = useGeolocationClient();
|
|
55
|
-
|
|
56
54
|
const [position, setPosition] = useState<GeolocationResponse | null>(null);
|
|
57
55
|
const [isWatching, setIsWatching] = useState(false);
|
|
58
56
|
const [error, setError] = useState<LocationError | null>(null);
|
|
@@ -78,7 +76,7 @@ export function useWatchPosition(options?: UseWatchPositionOptions) {
|
|
|
78
76
|
if (!enabled) {
|
|
79
77
|
// Not enabled, ensure cleanup
|
|
80
78
|
if (tokenRef.current) {
|
|
81
|
-
|
|
79
|
+
NitroGeolocationHybridObject.unwatch(tokenRef.current);
|
|
82
80
|
tokenRef.current = null;
|
|
83
81
|
}
|
|
84
82
|
setIsWatching(false);
|
|
@@ -89,7 +87,7 @@ export function useWatchPosition(options?: UseWatchPositionOptions) {
|
|
|
89
87
|
setIsWatching(true);
|
|
90
88
|
setError(null);
|
|
91
89
|
|
|
92
|
-
const token =
|
|
90
|
+
const token = NitroGeolocationHybridObject.watchPosition(
|
|
93
91
|
(result: GeolocationResponse) => {
|
|
94
92
|
// Success callback
|
|
95
93
|
if (!isMountedRef.current) return;
|
|
@@ -109,10 +107,10 @@ export function useWatchPosition(options?: UseWatchPositionOptions) {
|
|
|
109
107
|
// Cleanup function
|
|
110
108
|
return () => {
|
|
111
109
|
if (token) {
|
|
112
|
-
|
|
110
|
+
NitroGeolocationHybridObject.unwatch(token);
|
|
113
111
|
}
|
|
114
112
|
};
|
|
115
|
-
}, [enabled
|
|
113
|
+
}, [enabled]); // Only re-subscribe when enabled changes
|
|
116
114
|
|
|
117
115
|
// Track mount status
|
|
118
116
|
useEffect(() => {
|
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,140 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
-
import type {
|
|
3
|
-
LocationError,
|
|
4
|
-
LocationRequestOptions
|
|
5
|
-
} from "../NitroGeolocation.nitro";
|
|
6
|
-
import { useGeolocationClient } from "../components/GeolocationProvider";
|
|
7
|
-
import type { GeolocationResponse } from "../types";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Options for useGetCurrentPosition hook (Query style).
|
|
11
|
-
*/
|
|
12
|
-
export interface UseGetCurrentPositionOptions extends LocationRequestOptions {
|
|
13
|
-
/**
|
|
14
|
-
* Whether to automatically fetch the current position.
|
|
15
|
-
* When false, only manual refetch() will trigger the request.
|
|
16
|
-
* @default true
|
|
17
|
-
*/
|
|
18
|
-
enabled?: boolean;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Hook for getting current location (one-time request) in Query style.
|
|
23
|
-
* Provides loading, error states, and data similar to TanStack Query.
|
|
24
|
-
*
|
|
25
|
-
* @param options - Location request options and enabled flag
|
|
26
|
-
* @returns Object containing position, loading/error states, and refetch function
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* ```tsx
|
|
30
|
-
* // Auto-fetch on mount
|
|
31
|
-
* function MyComponent() {
|
|
32
|
-
* const {
|
|
33
|
-
* position,
|
|
34
|
-
* isLoading,
|
|
35
|
-
* isError,
|
|
36
|
-
* error,
|
|
37
|
-
* refetch
|
|
38
|
-
* } = useGetCurrentPosition({
|
|
39
|
-
* enabled: true,
|
|
40
|
-
* enableHighAccuracy: true,
|
|
41
|
-
* });
|
|
42
|
-
*
|
|
43
|
-
* if (isLoading) return <Text>Loading...</Text>;
|
|
44
|
-
* if (isError) return <Text>Error: {error?.message}</Text>;
|
|
45
|
-
* if (!position) return null;
|
|
46
|
-
*
|
|
47
|
-
* return (
|
|
48
|
-
* <View>
|
|
49
|
-
* <Text>Lat: {position.coords.latitude}</Text>
|
|
50
|
-
* <Text>Lng: {position.coords.longitude}</Text>
|
|
51
|
-
* <Button title="Refresh" onPress={() => refetch()} />
|
|
52
|
-
* </View>
|
|
53
|
-
* );
|
|
54
|
-
* }
|
|
55
|
-
*
|
|
56
|
-
* // Manual trigger only
|
|
57
|
-
* function ManualComponent() {
|
|
58
|
-
* const { position, isLoading, refetch } = useGetCurrentPosition({
|
|
59
|
-
* enabled: false
|
|
60
|
-
* });
|
|
61
|
-
*
|
|
62
|
-
* return (
|
|
63
|
-
* <View>
|
|
64
|
-
* <Button
|
|
65
|
-
* title="Get Location"
|
|
66
|
-
* onPress={() => refetch()}
|
|
67
|
-
* disabled={isLoading}
|
|
68
|
-
* />
|
|
69
|
-
* {position && <Text>Lat: {position.coords.latitude}</Text>}
|
|
70
|
-
* </View>
|
|
71
|
-
* );
|
|
72
|
-
* }
|
|
73
|
-
* ```
|
|
74
|
-
*/
|
|
75
|
-
export function useGetCurrentPosition(options?: UseGetCurrentPositionOptions) {
|
|
76
|
-
const client = useGeolocationClient();
|
|
77
|
-
|
|
78
|
-
const [position, setPosition] = useState<GeolocationResponse | null>(null);
|
|
79
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
80
|
-
const [isError, setIsError] = useState(false);
|
|
81
|
-
const [error, setError] = useState<LocationError | null>(null);
|
|
82
|
-
|
|
83
|
-
const isMountedRef = useRef(true);
|
|
84
|
-
const optionsRef = useRef(options);
|
|
85
|
-
|
|
86
|
-
// Update options ref when they change
|
|
87
|
-
useEffect(() => {
|
|
88
|
-
optionsRef.current = options;
|
|
89
|
-
}, [options]);
|
|
90
|
-
|
|
91
|
-
const fetchPosition = useCallback(async () => {
|
|
92
|
-
if (!isMountedRef.current) return;
|
|
93
|
-
|
|
94
|
-
setIsLoading(true);
|
|
95
|
-
setIsError(false);
|
|
96
|
-
setError(null);
|
|
97
|
-
|
|
98
|
-
try {
|
|
99
|
-
const result = await client.getCurrentPosition(optionsRef.current);
|
|
100
|
-
if (!isMountedRef.current) return;
|
|
101
|
-
|
|
102
|
-
setPosition(result);
|
|
103
|
-
setIsLoading(false);
|
|
104
|
-
} catch (err) {
|
|
105
|
-
if (!isMountedRef.current) return;
|
|
106
|
-
|
|
107
|
-
setIsError(true);
|
|
108
|
-
setError(err as LocationError);
|
|
109
|
-
setIsLoading(false);
|
|
110
|
-
}
|
|
111
|
-
}, [client]);
|
|
112
|
-
|
|
113
|
-
// Extract enabled flag for reactive dependency
|
|
114
|
-
const enabled = options?.enabled ?? true;
|
|
115
|
-
|
|
116
|
-
// Auto-fetch on mount if enabled
|
|
117
|
-
useEffect(() => {
|
|
118
|
-
if (enabled) {
|
|
119
|
-
fetchPosition();
|
|
120
|
-
}
|
|
121
|
-
// Only run when enabled changes, not when fetchPosition changes
|
|
122
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
123
|
-
}, [enabled]);
|
|
124
|
-
|
|
125
|
-
// Track mount status
|
|
126
|
-
useEffect(() => {
|
|
127
|
-
isMountedRef.current = true;
|
|
128
|
-
return () => {
|
|
129
|
-
isMountedRef.current = false;
|
|
130
|
-
};
|
|
131
|
-
}, []);
|
|
132
|
-
|
|
133
|
-
return {
|
|
134
|
-
position,
|
|
135
|
-
isLoading,
|
|
136
|
-
isError,
|
|
137
|
-
error,
|
|
138
|
-
refetch: fetchPosition
|
|
139
|
-
};
|
|
140
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
-
import type {
|
|
3
|
-
LocationError,
|
|
4
|
-
PermissionStatus
|
|
5
|
-
} from "../NitroGeolocation.nitro";
|
|
6
|
-
import { useGeolocationClient } from "../components/GeolocationProvider";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Hook for requesting location permission in Mutation style.
|
|
10
|
-
* Provides pending, error states, and status similar to TanStack Query mutations.
|
|
11
|
-
*
|
|
12
|
-
* @returns Object containing requestPermission function, status, and state flags
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```tsx
|
|
16
|
-
* function MyComponent() {
|
|
17
|
-
* const {
|
|
18
|
-
* requestPermission,
|
|
19
|
-
* status,
|
|
20
|
-
* isPending,
|
|
21
|
-
* isError,
|
|
22
|
-
* error
|
|
23
|
-
* } = useRequestPermission();
|
|
24
|
-
*
|
|
25
|
-
* const handleRequest = async () => {
|
|
26
|
-
* const result = await requestPermission();
|
|
27
|
-
* if (result === 'granted') {
|
|
28
|
-
* console.log('Permission granted!');
|
|
29
|
-
* }
|
|
30
|
-
* };
|
|
31
|
-
*
|
|
32
|
-
* return (
|
|
33
|
-
* <View>
|
|
34
|
-
* <Button
|
|
35
|
-
* onPress={handleRequest}
|
|
36
|
-
* disabled={isPending}
|
|
37
|
-
* >
|
|
38
|
-
* {isPending ? 'Requesting...' : 'Request Permission'}
|
|
39
|
-
* </Button>
|
|
40
|
-
* {isError && <Text>Error: {error?.message}</Text>}
|
|
41
|
-
* {status && <Text>Status: {status}</Text>}
|
|
42
|
-
* </View>
|
|
43
|
-
* );
|
|
44
|
-
* }
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
export function useRequestPermission() {
|
|
48
|
-
const client = useGeolocationClient();
|
|
49
|
-
|
|
50
|
-
const [status, setStatus] = useState<PermissionStatus | null>(null);
|
|
51
|
-
const [isPending, setIsPending] = useState(false);
|
|
52
|
-
const [isError, setIsError] = useState(false);
|
|
53
|
-
const [error, setError] = useState<LocationError | null>(null);
|
|
54
|
-
|
|
55
|
-
const isMountedRef = useRef(true);
|
|
56
|
-
|
|
57
|
-
const requestPermission = useCallback(async (): Promise<PermissionStatus> => {
|
|
58
|
-
if (!isMountedRef.current) {
|
|
59
|
-
throw new Error("Component unmounted");
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
setIsPending(true);
|
|
63
|
-
setIsError(false);
|
|
64
|
-
setError(null);
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
const result = await client.requestPermission();
|
|
68
|
-
if (!isMountedRef.current) return result;
|
|
69
|
-
|
|
70
|
-
setStatus(result);
|
|
71
|
-
setIsPending(false);
|
|
72
|
-
return result;
|
|
73
|
-
} catch (err) {
|
|
74
|
-
if (!isMountedRef.current) throw err;
|
|
75
|
-
|
|
76
|
-
setIsError(true);
|
|
77
|
-
setError(err as LocationError);
|
|
78
|
-
setIsPending(false);
|
|
79
|
-
throw err;
|
|
80
|
-
}
|
|
81
|
-
}, [client]);
|
|
82
|
-
|
|
83
|
-
// Track mount status
|
|
84
|
-
useEffect(() => {
|
|
85
|
-
isMountedRef.current = true;
|
|
86
|
-
return () => {
|
|
87
|
-
isMountedRef.current = false;
|
|
88
|
-
};
|
|
89
|
-
}, []);
|
|
90
|
-
|
|
91
|
-
return {
|
|
92
|
-
requestPermission,
|
|
93
|
-
status,
|
|
94
|
-
isPending,
|
|
95
|
-
isError,
|
|
96
|
-
error
|
|
97
|
-
};
|
|
98
|
-
}
|