react-native-nitro-geolocation 0.1.1 → 0.2.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/android/src/main/java/com/margelo/nitro/nitrogeolocation/GetCurrentPosition.kt +4 -4
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/NitroGeolocation.kt +642 -50
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/NitroGeolocationCompat.kt +81 -0
- package/android/src/main/java/com/margelo/nitro/nitrogeolocation/WatchPosition.kt +4 -4
- package/ios/LocationManager.swift +113 -128
- package/ios/NitroGeolocation.swift +546 -61
- package/ios/NitroGeolocationCompat.swift +109 -0
- package/nitrogen/generated/android/c++/JAuthorizationLevel.hpp +61 -0
- package/nitrogen/generated/android/c++/JAuthorizationLevelInternal.hpp +3 -4
- package/nitrogen/generated/android/c++/JFunc_void.hpp +2 -1
- package/nitrogen/generated/android/c++/JFunc_void_GeolocationError.hpp +2 -1
- package/nitrogen/generated/android/c++/JFunc_void_GeolocationResponse.hpp +6 -1
- package/nitrogen/generated/android/c++/JFunc_void_LocationError.hpp +78 -0
- package/nitrogen/generated/android/c++/JGeolocationCoordinates.hpp +25 -17
- package/nitrogen/generated/android/c++/JGeolocationError.hpp +5 -1
- package/nitrogen/generated/android/c++/JGeolocationOptions.hpp +5 -1
- package/nitrogen/generated/android/c++/JGeolocationResponse.hpp +9 -1
- package/nitrogen/generated/android/c++/JHybridNitroGeolocationCompatSpec.cpp +109 -0
- package/nitrogen/generated/android/c++/JHybridNitroGeolocationCompatSpec.hpp +70 -0
- package/nitrogen/generated/android/c++/JHybridNitroGeolocationSpec.cpp +98 -42
- package/nitrogen/generated/android/c++/JHybridNitroGeolocationSpec.hpp +7 -5
- package/nitrogen/generated/android/c++/JLocationError.hpp +61 -0
- package/nitrogen/generated/android/c++/JLocationProvider.hpp +61 -0
- package/nitrogen/generated/android/c++/JLocationProviderInternal.hpp +3 -4
- package/nitrogen/generated/android/c++/JLocationRequestOptions.hpp +81 -0
- package/nitrogen/generated/android/c++/JModernGeolocationConfiguration.hpp +73 -0
- package/nitrogen/generated/android/c++/JNullableDouble.cpp +26 -0
- package/nitrogen/generated/android/c++/JNullableDouble.hpp +69 -0
- package/nitrogen/generated/android/c++/JPermissionStatus.hpp +64 -0
- package/nitrogen/generated/android/c++/JRNConfigurationInternal.hpp +5 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AuthorizationLevel.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/AuthorizationLevelInternal.kt +2 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void.kt +0 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_GeolocationError.kt +0 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_GeolocationResponse.kt +0 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/Func_void_LocationError.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeolocationCoordinates.kt +34 -25
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeolocationError.kt +27 -18
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeolocationOptions.kt +33 -24
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/GeolocationResponse.kt +18 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/HybridNitroGeolocationCompatSpec.kt +92 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/HybridNitroGeolocationSpec.kt +17 -17
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationError.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationProvider.kt +24 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationProviderInternal.kt +2 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/LocationRequestOptions.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/ModernGeolocationConfiguration.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/NullableDouble.kt +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/PermissionStatus.kt +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrogeolocation/RNConfigurationInternal.kt +24 -15
- package/nitrogen/generated/android/nitrogeolocation+autolinking.cmake +3 -0
- package/nitrogen/generated/android/nitrogeolocationOnLoad.cpp +14 -2
- package/nitrogen/generated/ios/NitroGeolocation+autolinking.rb +1 -1
- package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Bridge.cpp +55 -13
- package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Bridge.hpp +325 -68
- package/nitrogen/generated/ios/NitroGeolocation-Swift-Cxx-Umbrella.hpp +26 -0
- package/nitrogen/generated/ios/NitroGeolocationAutolinking.mm +8 -0
- package/nitrogen/generated/ios/NitroGeolocationAutolinking.swift +15 -0
- package/nitrogen/generated/ios/c++/HybridNitroGeolocationCompatSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridNitroGeolocationCompatSpecSwift.hpp +130 -0
- package/nitrogen/generated/ios/c++/HybridNitroGeolocationSpecSwift.hpp +47 -26
- package/nitrogen/generated/ios/swift/AuthorizationLevel.swift +44 -0
- package/nitrogen/generated/ios/swift/Func_void.swift +1 -1
- package/nitrogen/generated/ios/swift/Func_void_GeolocationError.swift +1 -1
- package/nitrogen/generated/ios/swift/Func_void_GeolocationResponse.swift +1 -1
- package/nitrogen/generated/ios/swift/Func_void_LocationError.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_PermissionStatus.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
- package/nitrogen/generated/ios/swift/GeolocationCoordinates.swift +132 -93
- package/nitrogen/generated/ios/swift/GeolocationError.swift +11 -40
- package/nitrogen/generated/ios/swift/GeolocationOptions.swift +29 -98
- package/nitrogen/generated/ios/swift/GeolocationResponse.swift +5 -16
- package/nitrogen/generated/ios/swift/HybridNitroGeolocationCompatSpec.swift +61 -0
- package/nitrogen/generated/ios/swift/HybridNitroGeolocationCompatSpec_cxx.swift +244 -0
- package/nitrogen/generated/ios/swift/HybridNitroGeolocationSpec.swift +13 -5
- package/nitrogen/generated/ios/swift/HybridNitroGeolocationSpec_cxx.swift +66 -64
- package/nitrogen/generated/ios/swift/LocationError.swift +35 -0
- package/nitrogen/generated/ios/swift/LocationProvider.swift +44 -0
- package/nitrogen/generated/ios/swift/LocationRequestOptions.swift +116 -0
- package/nitrogen/generated/ios/swift/ModernGeolocationConfiguration.swift +83 -0
- package/nitrogen/generated/ios/swift/NullableDouble.swift +18 -0
- package/nitrogen/generated/ios/swift/PermissionStatus.swift +48 -0
- package/nitrogen/generated/ios/swift/RNConfigurationInternal.swift +16 -50
- package/nitrogen/generated/shared/c++/AuthorizationLevel.hpp +80 -0
- package/nitrogen/generated/shared/c++/GeolocationCoordinates.hpp +45 -27
- package/nitrogen/generated/shared/c++/GeolocationError.hpp +32 -16
- package/nitrogen/generated/shared/c++/GeolocationOptions.hpp +38 -22
- package/nitrogen/generated/shared/c++/GeolocationResponse.hpp +23 -7
- package/nitrogen/generated/shared/c++/HybridNitroGeolocationCompatSpec.cpp +26 -0
- package/nitrogen/generated/shared/c++/HybridNitroGeolocationCompatSpec.hpp +79 -0
- package/nitrogen/generated/shared/c++/HybridNitroGeolocationSpec.cpp +4 -3
- package/nitrogen/generated/shared/c++/HybridNitroGeolocationSpec.hpp +22 -16
- package/nitrogen/generated/shared/c++/LocationError.hpp +87 -0
- package/nitrogen/generated/shared/c++/LocationProvider.hpp +80 -0
- package/nitrogen/generated/shared/c++/LocationRequestOptions.hpp +107 -0
- package/nitrogen/generated/shared/c++/ModernGeolocationConfiguration.hpp +100 -0
- package/nitrogen/generated/shared/c++/PermissionStatus.hpp +84 -0
- package/nitrogen/generated/shared/c++/RNConfigurationInternal.hpp +29 -13
- package/package.json +16 -7
- package/src/GeolocationClient.ts +116 -0
- package/src/NitroGeolocation.nitro.ts +177 -30
- package/src/NitroGeolocationCompat.nitro.ts +41 -0
- package/src/NitroGeolocationModule.ts +6 -0
- package/src/compat/clearWatch.ts +9 -0
- package/src/{getCurrentPosition.ts → compat/getCurrentPosition.ts} +7 -3
- package/src/compat/index.tsx +34 -0
- package/src/compat/requestAuthorization.ts +9 -0
- package/src/{setRNConfiguration.ts → compat/setRNConfiguration.ts} +6 -4
- package/src/{stopObserving.ts → compat/stopObserving.ts} +4 -2
- package/src/{watchPosition.ts → compat/watchPosition.ts} +7 -6
- package/src/components/GeolocationProvider.tsx +91 -0
- package/src/components/index.ts +13 -0
- package/src/hooks/index.ts +9 -0
- package/src/hooks/useCheckPermission.ts +46 -0
- package/src/hooks/useGetCurrentPosition.ts +44 -0
- package/src/hooks/useRequestPermission.ts +38 -0
- package/src/hooks/useWatchPosition.ts +127 -0
- package/src/index.tsx +72 -27
- package/src/types.ts +32 -4
- package/src/utils/cache.ts +25 -0
- package/src/utils/config.ts +93 -0
- package/src/utils/errors.ts +82 -0
- package/src/utils/index.ts +27 -0
- package/src/utils/provider.ts +61 -0
- package/src/utils/quality.ts +98 -0
- package/README.md +0 -318
- package/src/clearWatch.ts +0 -13
- package/src/requestAuthorization.ts +0 -9
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { NitroGeolocationHybridCompatObject } from "../NitroGeolocationModule";
|
|
2
|
+
import type { GeolocationError } from "../types";
|
|
3
|
+
|
|
4
|
+
export function requestAuthorization(
|
|
5
|
+
success?: () => void,
|
|
6
|
+
error?: (error: GeolocationError) => void
|
|
7
|
+
): void {
|
|
8
|
+
NitroGeolocationHybridCompatObject.requestAuthorization(success, error);
|
|
9
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { RNConfigurationInternal } from "
|
|
2
|
-
import {
|
|
3
|
-
import type { GeolocationConfiguration } from "
|
|
1
|
+
import type { RNConfigurationInternal } from "../NitroGeolocationCompat.nitro";
|
|
2
|
+
import { NitroGeolocationHybridCompatObject } from "../NitroGeolocationModule";
|
|
3
|
+
import type { GeolocationConfiguration } from "../types";
|
|
4
4
|
|
|
5
5
|
// Mapping layer: convert "android" to "android_platform" for C++
|
|
6
6
|
function mapConfigToInternal(
|
|
@@ -18,5 +18,7 @@ function mapConfigToInternal(
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export function setRNConfiguration(config: GeolocationConfiguration): void {
|
|
21
|
-
|
|
21
|
+
NitroGeolocationHybridCompatObject.setRNConfiguration(
|
|
22
|
+
mapConfigToInternal(config)
|
|
23
|
+
);
|
|
22
24
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NitroModules } from "react-native-nitro-modules";
|
|
2
|
-
import type {
|
|
2
|
+
import type { NitroGeolocationCompat } from "../NitroGeolocationCompat.nitro";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Stops observing all location updates.
|
|
@@ -7,6 +7,8 @@ import type { NitroGeolocation } from "./NitroGeolocation.nitro";
|
|
|
7
7
|
*/
|
|
8
8
|
export function stopObserving(): void {
|
|
9
9
|
const nitroGeolocation =
|
|
10
|
-
NitroModules.createHybridObject<
|
|
10
|
+
NitroModules.createHybridObject<NitroGeolocationCompat>(
|
|
11
|
+
"NitroGeolocationCompat"
|
|
12
|
+
);
|
|
11
13
|
nitroGeolocation.stopObserving();
|
|
12
14
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { NitroGeolocation } from "./NitroGeolocation.nitro";
|
|
1
|
+
import { NitroGeolocationHybridCompatObject } from "../NitroGeolocationModule";
|
|
3
2
|
import type {
|
|
4
3
|
GeolocationError,
|
|
5
4
|
GeolocationOptions,
|
|
6
5
|
GeolocationResponse
|
|
7
|
-
} from "
|
|
6
|
+
} from "../types";
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* Invokes the success callback whenever the location changes.
|
|
@@ -20,7 +19,9 @@ export function watchPosition(
|
|
|
20
19
|
error?: (error: GeolocationError) => void,
|
|
21
20
|
options?: GeolocationOptions
|
|
22
21
|
): number {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
return NitroGeolocationHybridCompatObject.watchPosition(
|
|
23
|
+
success,
|
|
24
|
+
error,
|
|
25
|
+
options
|
|
26
|
+
);
|
|
26
27
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
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;
|
|
@@ -0,0 +1,13 @@
|
|
|
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";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modern React hooks for geolocation.
|
|
3
|
+
* These hooks provide a declarative, React-friendly API for location services.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export * from "./useCheckPermission";
|
|
7
|
+
export * from "./useRequestPermission";
|
|
8
|
+
export * from "./useGetCurrentPosition";
|
|
9
|
+
export * from "./useWatchPosition";
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { 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 useWatchPosition hook.
|
|
11
|
+
*/
|
|
12
|
+
export interface UseWatchPositionOptions extends LocationRequestOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Whether to actively watch for location updates.
|
|
15
|
+
* When false, watching is paused and cleanup is performed.
|
|
16
|
+
* @default false
|
|
17
|
+
*/
|
|
18
|
+
enabled?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Hook for continuous location tracking.
|
|
23
|
+
* Automatically subscribes/unsubscribes based on component lifecycle.
|
|
24
|
+
*
|
|
25
|
+
* The subscription token is completely hidden from the user.
|
|
26
|
+
* Cleanup is automatic via useEffect.
|
|
27
|
+
*
|
|
28
|
+
* @param options - Location request options
|
|
29
|
+
* @returns Object containing current position data, error, and watching status
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* function LiveTracking() {
|
|
34
|
+
* const { data, error, isWatching } = useWatchPosition({
|
|
35
|
+
* enabled: true,
|
|
36
|
+
* enableHighAccuracy: true,
|
|
37
|
+
* distanceFilter: 10 // Update every 10 meters
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* if (!isWatching) return <Text>Not watching</Text>;
|
|
41
|
+
* if (error) return <Text>Error: {error.message}</Text>;
|
|
42
|
+
* if (!data) return <Text>Waiting for location...</Text>;
|
|
43
|
+
*
|
|
44
|
+
* return (
|
|
45
|
+
* <Text>
|
|
46
|
+
* Current: {data.coords.latitude}, {data.coords.longitude}
|
|
47
|
+
* Accuracy: {data.coords.accuracy}m
|
|
48
|
+
* </Text>
|
|
49
|
+
* );
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export function useWatchPosition(options?: UseWatchPositionOptions) {
|
|
54
|
+
const client = useGeolocationClient();
|
|
55
|
+
|
|
56
|
+
const [data, setData] = useState<GeolocationResponse | null>(null);
|
|
57
|
+
const [isWatching, setIsWatching] = useState(false);
|
|
58
|
+
|
|
59
|
+
// Store subscription token (hidden from user!)
|
|
60
|
+
const tokenRef = useRef<string | null>(null);
|
|
61
|
+
|
|
62
|
+
// Track if component is mounted to prevent state updates after unmount
|
|
63
|
+
const isMountedRef = useRef(true);
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
const enabled = options?.enabled ?? false;
|
|
67
|
+
|
|
68
|
+
if (!enabled) {
|
|
69
|
+
// Not enabled, ensure cleanup
|
|
70
|
+
if (tokenRef.current) {
|
|
71
|
+
client.unwatch(tokenRef.current);
|
|
72
|
+
tokenRef.current = null;
|
|
73
|
+
}
|
|
74
|
+
setIsWatching(false);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Start watching
|
|
79
|
+
setIsWatching(true);
|
|
80
|
+
|
|
81
|
+
const token = client.watchPosition(
|
|
82
|
+
(position: GeolocationResponse) => {
|
|
83
|
+
// Success callback
|
|
84
|
+
if (!isMountedRef.current) return;
|
|
85
|
+
setData(position);
|
|
86
|
+
},
|
|
87
|
+
(err: LocationError) => {
|
|
88
|
+
// Error callback - throw to be caught by Error Boundary
|
|
89
|
+
if (!isMountedRef.current) return;
|
|
90
|
+
throw new Error(err.message);
|
|
91
|
+
},
|
|
92
|
+
options
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
tokenRef.current = token;
|
|
96
|
+
|
|
97
|
+
// Cleanup function
|
|
98
|
+
return () => {
|
|
99
|
+
if (token) {
|
|
100
|
+
client.unwatch(token);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
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
|
+
]);
|
|
114
|
+
|
|
115
|
+
// Track mount status
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
isMountedRef.current = true;
|
|
118
|
+
return () => {
|
|
119
|
+
isMountedRef.current = false;
|
|
120
|
+
};
|
|
121
|
+
}, []);
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
data,
|
|
125
|
+
isWatching
|
|
126
|
+
};
|
|
127
|
+
}
|
package/src/index.tsx
CHANGED
|
@@ -1,34 +1,79 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Modern Geolocation API for React Native.
|
|
3
|
+
*
|
|
4
|
+
* This is the main entry point for the modern, React-friendly API.
|
|
5
|
+
* For legacy compatibility, use: import Geolocation from 'react-native-nitro-geolocation/compat'
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import {
|
|
10
|
+
* GeolocationClient,
|
|
11
|
+
* GeolocationClientProvider,
|
|
12
|
+
* useRequestPermission,
|
|
13
|
+
* useGetCurrentPosition,
|
|
14
|
+
* useWatchPosition
|
|
15
|
+
* } from 'react-native-nitro-geolocation';
|
|
16
|
+
*
|
|
17
|
+
* // Create GeolocationClient instance
|
|
18
|
+
* const geolocationClient = new GeolocationClient({
|
|
19
|
+
* authorizationLevel: 'whenInUse',
|
|
20
|
+
* enableBackgroundLocationUpdates: false,
|
|
21
|
+
* locationProvider: 'auto'
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* function App() {
|
|
25
|
+
* return (
|
|
26
|
+
* <GeolocationClientProvider client={geolocationClient}>
|
|
27
|
+
* <YourApp />
|
|
28
|
+
* </GeolocationClientProvider>
|
|
29
|
+
* );
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* function LocationButton() {
|
|
33
|
+
* const { getCurrentPosition } = useGetCurrentPosition();
|
|
34
|
+
* const [loading, setLoading] = useState(false);
|
|
35
|
+
*
|
|
36
|
+
* const handlePress = async () => {
|
|
37
|
+
* setLoading(true);
|
|
38
|
+
* try {
|
|
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
|
+
* };
|
|
47
|
+
*
|
|
48
|
+
* return <Button onPress={handlePress} disabled={loading} />;
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
8
52
|
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import { requestAuthorization } from "./requestAuthorization";
|
|
13
|
-
import { setRNConfiguration } from "./setRNConfiguration";
|
|
14
|
-
import { stopObserving } from "./stopObserving";
|
|
15
|
-
import { watchPosition } from "./watchPosition";
|
|
53
|
+
// Core
|
|
54
|
+
export { GeolocationClient } from "./GeolocationClient";
|
|
55
|
+
export type { GeolocationClientConfig } from "./GeolocationClient";
|
|
16
56
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
57
|
+
// Components
|
|
58
|
+
export * from "./components";
|
|
59
|
+
|
|
60
|
+
// Hooks
|
|
61
|
+
export * from "./hooks";
|
|
62
|
+
|
|
63
|
+
// Types from Nitro spec
|
|
64
|
+
export type {
|
|
65
|
+
PermissionStatus,
|
|
66
|
+
LocationRequestOptions,
|
|
67
|
+
LocationError
|
|
68
|
+
} from "./NitroGeolocation.nitro";
|
|
25
69
|
|
|
26
|
-
// Export types
|
|
27
70
|
export type {
|
|
28
|
-
GeolocationConfiguration,
|
|
29
71
|
GeolocationResponse,
|
|
30
|
-
|
|
31
|
-
|
|
72
|
+
GeolocationCoordinates,
|
|
73
|
+
AuthorizationLevel,
|
|
74
|
+
LocationProvider,
|
|
75
|
+
ModernGeolocationConfiguration
|
|
32
76
|
} from "./types";
|
|
33
77
|
|
|
34
|
-
|
|
78
|
+
// Pure utility functions (advanced users only)
|
|
79
|
+
export * from "./utils";
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,34 @@
|
|
|
1
1
|
// Public API types (compatible with @react-native-community/geolocation)
|
|
2
2
|
export type AuthorizationLevel = "always" | "whenInUse" | "auto";
|
|
3
3
|
export type LocationProvider = "playServices" | "android" | "auto";
|
|
4
|
+
export type NullableDouble = number | null;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* User-facing geolocation configuration.
|
|
8
|
+
* This uses "android" instead of "android_platform" for better DX.
|
|
9
|
+
*/
|
|
10
|
+
export interface ModernGeolocationConfiguration {
|
|
11
|
+
/**
|
|
12
|
+
* Automatically request location permission when GeolocationProvider mounts.
|
|
13
|
+
* @default false
|
|
14
|
+
*/
|
|
15
|
+
autoRequestPermission?: boolean;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* iOS: Authorization level
|
|
19
|
+
*/
|
|
20
|
+
authorizationLevel?: AuthorizationLevel;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* iOS: Enable background location updates.
|
|
24
|
+
*/
|
|
25
|
+
enableBackgroundLocationUpdates?: boolean;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Android: Location provider
|
|
29
|
+
*/
|
|
30
|
+
locationProvider?: LocationProvider;
|
|
31
|
+
}
|
|
4
32
|
|
|
5
33
|
export interface GeolocationConfiguration {
|
|
6
34
|
skipPermissionRequests: boolean;
|
|
@@ -12,11 +40,11 @@ export interface GeolocationConfiguration {
|
|
|
12
40
|
export interface GeolocationCoordinates {
|
|
13
41
|
latitude: number;
|
|
14
42
|
longitude: number;
|
|
15
|
-
altitude:
|
|
43
|
+
altitude: NullableDouble;
|
|
16
44
|
accuracy: number;
|
|
17
|
-
altitudeAccuracy:
|
|
18
|
-
heading:
|
|
19
|
-
speed:
|
|
45
|
+
altitudeAccuracy: NullableDouble;
|
|
46
|
+
heading: NullableDouble;
|
|
47
|
+
speed: NullableDouble;
|
|
20
48
|
}
|
|
21
49
|
|
|
22
50
|
export interface GeolocationResponse {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates whether a cached location is still fresh based on its age.
|
|
3
|
+
*
|
|
4
|
+
* @param timestampMs - The timestamp of the cached location (in milliseconds)
|
|
5
|
+
* @param currentTimeMs - The current time (in milliseconds)
|
|
6
|
+
* @param maximumAgeMs - The maximum age allowed for the cache (in milliseconds)
|
|
7
|
+
* @returns true if the cache is still valid, false otherwise
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const timestampMs = Date.now() - 5000; // 5 seconds ago
|
|
12
|
+
* const currentTimeMs = Date.now();
|
|
13
|
+
* const maximumAgeMs = 10000; // 10 seconds
|
|
14
|
+
*
|
|
15
|
+
* isCachedLocationValid(timestampMs, currentTimeMs, maximumAgeMs); // true
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export function isCachedLocationValid(
|
|
19
|
+
timestampMs: number,
|
|
20
|
+
currentTimeMs: number,
|
|
21
|
+
maximumAgeMs: number
|
|
22
|
+
): boolean {
|
|
23
|
+
const age = currentTimeMs - timestampMs;
|
|
24
|
+
return age < maximumAgeMs;
|
|
25
|
+
}
|