diff --git a/configs/jsactions/rollup.config.mjs b/configs/jsactions/rollup.config.mjs index d8691fac1..6930d6bd7 100644 --- a/configs/jsactions/rollup.config.mjs +++ b/configs/jsactions/rollup.config.mjs @@ -34,6 +34,7 @@ export default async args => { types: ["mendix-client", "react-native"], allowSyntheticDefaultImports: true, compilerOptions: { + jsx: "react-native", newLine: "CRLF" } }); diff --git a/package.json b/package.json index dc008b4b4..b79677d0d 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,8 @@ "react-native-gesture-handler@2.31.2": "patches/react-native-gesture-handler+2.31.2.patch", "react-native-slider@0.11.0": "patches/react-native-slider+0.11.0.patch", "react-native-snap-carousel@3.9.1": "patches/react-native-snap-carousel+3.9.1.patch", - "react-native-track-player@4.1.2": "patches/react-native-track-player@4.1.2.patch" + "react-native-track-player@4.1.2": "patches/react-native-track-player@4.1.2.patch", + "react-native-nitro-geolocation@1.4.2": "patches/react-native-nitro-geolocation+1.4.2.patch" } }, "packageManager": "pnpm@10.32.0+sha512.9b2634bb3fed5601c33633f2d92593f506270a3963b8c51d2b2d6a828da615ce4e9deebef9614ccebbc13ac8d3c0f9c9ccceb583c69c8578436fa477dbb20d70" diff --git a/packages/jsActions/nanoflow-actions-native/CHANGELOG.md b/packages/jsActions/nanoflow-actions-native/CHANGELOG.md index 0a18c5fe2..d9f21987f 100644 --- a/packages/jsActions/nanoflow-actions-native/CHANGELOG.md +++ b/packages/jsActions/nanoflow-actions-native/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Changed + +- Migrated the geolocation actions (`Get current location` and `Get current location with minimum accuracy`) from `@react-native-community/geolocation` to `react-native-nitro-geolocation`. + ## [7.1.0] Nanoflow Commons - 2026-6-5 ### Changed diff --git a/packages/jsActions/nanoflow-actions-native/package.json b/packages/jsActions/nanoflow-actions-native/package.json index aea3b75f4..929d20c4b 100644 --- a/packages/jsActions/nanoflow-actions-native/package.json +++ b/packages/jsActions/nanoflow-actions-native/package.json @@ -27,9 +27,10 @@ }, "dependencies": { "@react-native-async-storage/async-storage": "2.2.0", - "@react-native-community/geolocation": "3.4.0", "invariant": "^2.2.4", "js-base64": "~3.7.2", + "react-native-nitro-geolocation": "1.4.2", + "react-native-nitro-modules": "0.35.9", "react-native-permissions": "5.5.1", "react-native-geocoder": "0.5.0" }, diff --git a/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocation.ts b/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocation.ts index b333c81d4..9883dcbc0 100644 --- a/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocation.ts +++ b/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocation.ts @@ -10,7 +10,7 @@ import Geolocation, { GeolocationError, GeolocationOptions, GeolocationResponse -} from "@react-native-community/geolocation"; +} from "react-native-nitro-geolocation/src/compat"; import type { Platform, NativeModules } from "react-native"; import type { GeoError, GeoPosition, GeoOptions } from "../../typings/Geolocation"; @@ -40,7 +40,7 @@ export async function GetCurrentLocation( // BEGIN USER CODE let reactNativeModule: { NativeModules: typeof NativeModules; Platform: typeof Platform } | undefined; - let geolocationModule: typeof import("@react-native-community/geolocation").default | Geolocation; + let geolocationModule: typeof import("react-native-nitro-geolocation/src/compat").default | Geolocation; if (navigator && navigator.product === "ReactNative") { reactNativeModule = require("react-native"); @@ -49,13 +49,7 @@ export async function GetCurrentLocation( return Promise.reject(new Error("React Native module could not be found")); } - if (reactNativeModule.NativeModules.RNFusedLocation) { - geolocationModule = (await import("@react-native-community/geolocation")).default; - } else if (reactNativeModule.NativeModules.RNCGeolocation) { - geolocationModule = Geolocation; - } else { - return Promise.reject(new Error("Geolocation module could not be found")); - } + geolocationModule = Geolocation; } else if (navigator && navigator.geolocation) { geolocationModule = navigator.geolocation; } else { diff --git a/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocationMinimumAccuracy.ts b/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocationMinimumAccuracy.ts index 7756b3e1b..ca00752a0 100644 --- a/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocationMinimumAccuracy.ts +++ b/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocationMinimumAccuracy.ts @@ -10,7 +10,7 @@ import Geolocation, { GeolocationError, GeolocationOptions, GeolocationResponse -} from "@react-native-community/geolocation"; +} from "react-native-nitro-geolocation/src/compat"; import type { Platform, NativeModules } from "react-native"; import type { GeoError, GeoPosition, GeoOptions } from "../../typings/Geolocation"; @@ -44,7 +44,7 @@ export async function GetCurrentLocationMinimumAccuracy( // BEGIN USER CODE let reactNativeModule: { NativeModules: typeof NativeModules; Platform: typeof Platform } | undefined; - let geolocationModule: typeof import("@react-native-community/geolocation").default | Geolocation; + let geolocationModule: typeof import("react-native-nitro-geolocation/src/compat").default | Geolocation; if (navigator && navigator.product === "ReactNative") { reactNativeModule = require("react-native"); @@ -53,13 +53,7 @@ export async function GetCurrentLocationMinimumAccuracy( return Promise.reject(new Error("React Native module could not be found")); } - if (reactNativeModule.NativeModules.RNFusedLocation) { - geolocationModule = (await import("@react-native-community/geolocation")).default; - } else if (reactNativeModule.NativeModules.RNCGeolocation) { - geolocationModule = Geolocation; - } else { - return Promise.reject(new Error("Geolocation module could not be found")); - } + geolocationModule = Geolocation; } else if (navigator && navigator.geolocation) { geolocationModule = navigator.geolocation; } else { diff --git a/packages/jsActions/nanoflow-actions-native/typings/Geolocation.d.ts b/packages/jsActions/nanoflow-actions-native/typings/Geolocation.d.ts index c92f243d4..dab2297eb 100644 --- a/packages/jsActions/nanoflow-actions-native/typings/Geolocation.d.ts +++ b/packages/jsActions/nanoflow-actions-native/typings/Geolocation.d.ts @@ -1,15 +1,17 @@ import type { - AuthorizationLevel, - AuthorizationResult, - GeoError, - GeoPosition, - GeoOptions, + GeolocationError, + GeolocationOptions, + GeolocationResponse, getCurrentPosition, requestAuthorization, watchPosition, clearWatch, stopObserving -} from "@react-native-community/geolocation"; +} from "react-native-nitro-geolocation/src/compat"; + +type GeoError = GeolocationError; +type GeoPosition = GeolocationResponse; +type GeoOptions = GeolocationOptions; type GeolocationServiceStatic = { getCurrentPosition: typeof getCurrentPosition; @@ -19,4 +21,4 @@ type GeolocationServiceStatic = { stopObserving: typeof stopObserving; }; -export type { GeolocationServiceStatic, AuthorizationLevel, AuthorizationResult, GeoError, GeoPosition, GeoOptions }; +export type { GeolocationServiceStatic, GeoError, GeoPosition, GeoOptions }; diff --git a/patches/react-native-nitro-geolocation+1.4.2.patch b/patches/react-native-nitro-geolocation+1.4.2.patch new file mode 100644 index 000000000..ec9dfb1eb --- /dev/null +++ b/patches/react-native-nitro-geolocation+1.4.2.patch @@ -0,0 +1,314 @@ +diff --git a/android/src/main/java/com/margelo/nitro/nitrogeolocation/GetCurrentPosition.kt b/android/src/main/java/com/margelo/nitro/nitrogeolocation/GetCurrentPosition.kt +--- a/android/src/main/java/com/margelo/nitro/nitrogeolocation/GetCurrentPosition.kt ++++ b/android/src/main/java/com/margelo/nitro/nitrogeolocation/GetCurrentPosition.kt +@@ -12,6 +12,15 @@ + import android.util.Log + import androidx.core.content.ContextCompat + import com.facebook.react.bridge.ReactApplicationContext ++import com.google.android.gms.common.ConnectionResult ++import com.google.android.gms.common.GoogleApiAvailability ++import com.google.android.gms.location.FusedLocationProviderClient ++import com.google.android.gms.location.LocationCallback ++import com.google.android.gms.location.LocationRequest ++import com.google.android.gms.location.LocationResult ++import com.google.android.gms.location.LocationServices ++import com.google.android.gms.location.Priority ++import com.google.android.gms.location.LocationAvailability + + class GetCurrentPosition(private val reactContext: ReactApplicationContext) { + +@@ -19,6 +28,121 @@ + success: (position: CompatGeolocationResponse) -> Unit, + error: ((error: CompatGeolocationError) -> Unit)?, + options: CompatGeolocationOptions? ++ ) { ++ val opts = parseOptions(options) ++ ++ // Use FusedLocationProviderClient when Play Services are available ++ if (isGooglePlayServicesAvailable()) { ++ getCurrentPositionWithFused(success, error, opts) ++ return ++ } ++ ++ // Fallback to basic LocationManager ++ getCurrentPositionWithLocationManager(success, error, opts) ++ } ++ ++ // ===== Fused Location Provider (Play Services) Path ===== ++ ++ private fun getCurrentPositionWithFused( ++ success: (CompatGeolocationResponse) -> Unit, ++ error: ((CompatGeolocationError) -> Unit)?, ++ options: ParsedOptions ++ ) { ++ val fusedLocationClient = LocationServices.getFusedLocationProviderClient(reactContext) ++ ++ try { ++ fusedLocationClient.lastLocation ++ .addOnSuccessListener { location -> ++ if (location != null && isCachedLocationValid(location, options)) { ++ success(locationToPosition(location)) ++ } else { ++ requestFreshFusedLocation(fusedLocationClient, success, error, options) ++ } ++ } ++ .addOnFailureListener { ++ requestFreshFusedLocation(fusedLocationClient, success, error, options) ++ } ++ } catch (e: SecurityException) { ++ Log.e(TAG, "Security exception: ${e.message}") ++ error?.invoke( ++ createError(PERMISSION_DENIED, "Location permission denied: ${e.message}") ++ ) ++ } ++ } ++ ++ private fun requestFreshFusedLocation( ++ fusedLocationClient: FusedLocationProviderClient, ++ success: (CompatGeolocationResponse) -> Unit, ++ error: ((CompatGeolocationError) -> Unit)?, ++ options: ParsedOptions ++ ) { ++ val handler = Handler(Looper.getMainLooper()) ++ var isResolved = false ++ ++ val locationRequest = LocationRequest.Builder(0) ++ .setPriority( ++ if (options.androidAccuracy.mode == AndroidAccuracyMode.HIGH) ++ Priority.PRIORITY_HIGH_ACCURACY ++ else ++ Priority.PRIORITY_BALANCED_POWER_ACCURACY ++ ) ++ .setMaxUpdateAgeMillis(options.maximumAge.toLong().coerceAtLeast(0L)) ++ .setMinUpdateDistanceMeters(0f) ++ .setMaxUpdates(1) ++ .build() ++ ++ val locationCallback = object : LocationCallback() { ++ override fun onLocationResult(locationResult: LocationResult) { ++ val location = locationResult.lastLocation ++ ++ if (location == null) { ++ // Don't error on null location - wait for timeout or next callback ++ return ++ } ++ ++ if (!isResolved) { ++ isResolved = true ++ handler.removeCallbacksAndMessages(null) ++ fusedLocationClient.removeLocationUpdates(this) ++ success(locationToPosition(location)) ++ } ++ } ++ ++ override fun onLocationAvailability(locationAvailability: LocationAvailability) { ++ if (!locationAvailability.isLocationAvailable) { ++ // Don't error immediately - wait for timeout or a location update ++ return ++ } ++ } ++ } ++ ++ val timeoutRunnable = Runnable { ++ if (!isResolved) { ++ isResolved = true ++ fusedLocationClient.removeLocationUpdates(locationCallback) ++ error?.invoke(createError(TIMEOUT, "Location request timed out")) ++ } ++ } ++ ++ try { ++ fusedLocationClient.requestLocationUpdates( ++ locationRequest, ++ locationCallback, ++ Looper.getMainLooper() ++ ) ++ handler.postDelayed(timeoutRunnable, options.timeout.toLong()) ++ } catch (e: SecurityException) { ++ Log.e(TAG, "SecurityException in fused request: ${e.message}") ++ error?.invoke(createError(PERMISSION_DENIED, "Permission denied: ${e.message}")) ++ } ++ } ++ ++ // ===== Basic LocationManager Path (Fallback) ===== ++ ++ private fun getCurrentPositionWithLocationManager( ++ success: (CompatGeolocationResponse) -> Unit, ++ error: ((CompatGeolocationError) -> Unit)?, ++ options: ParsedOptions + ) { + val locationManager = + reactContext.getSystemService(Context.LOCATION_SERVICE) as? LocationManager +@@ -28,8 +152,7 @@ + return + } + +- val opts = parseOptions(options) +- val provider = getValidProvider(locationManager, opts.androidAccuracy) ++ val provider = getValidProvider(locationManager, options.androidAccuracy) + + if (provider == null) { + Log.e(TAG, "No location provider available") +@@ -41,19 +164,19 @@ + val lastKnownLocation = locationManager.getLastKnownLocation(provider) + + // Check if cached location is fresh enough +- if (lastKnownLocation != null && isCachedLocationValid(lastKnownLocation, opts)) { ++ if (lastKnownLocation != null && isCachedLocationValid(lastKnownLocation, options)) { + success(locationToPosition(lastKnownLocation)) + return + } + + // If maximumAge is Infinity and we have a last known location, use it +- if (lastKnownLocation != null && opts.maximumAge == Double.POSITIVE_INFINITY) { ++ if (lastKnownLocation != null && options.maximumAge == Double.POSITIVE_INFINITY) { + success(locationToPosition(lastKnownLocation)) + return + } + + // Request fresh location +- requestFreshLocation(locationManager, provider, opts, success, error, lastKnownLocation) ++ requestFreshLocation(locationManager, provider, options, success, error, lastKnownLocation) + } catch (e: SecurityException) { + Log.e(TAG, "Security exception: ${e.message}") + error?.invoke( +@@ -64,6 +187,11 @@ + + // ===== Helper Functions ===== + ++ private fun isGooglePlayServicesAvailable(): Boolean { ++ return GoogleApiAvailability.getInstance() ++ .isGooglePlayServicesAvailable(reactContext.applicationContext) == ConnectionResult.SUCCESS ++ } ++ + private fun parseOptions(options: CompatGeolocationOptions?): ParsedOptions { + return ParsedOptions( + timeout = options?.timeout ?: DEFAULT_TIMEOUT, + +diff --git a/android/src/main/java/com/margelo/nitro/nitrogeolocation/WatchPosition.kt b/android/src/main/java/com/margelo/nitro/nitrogeolocation/WatchPosition.kt +--- a/android/src/main/java/com/margelo/nitro/nitrogeolocation/WatchPosition.kt ++++ b/android/src/main/java/com/margelo/nitro/nitrogeolocation/WatchPosition.kt +@@ -11,6 +11,14 @@ + import android.util.Log + import androidx.core.content.ContextCompat + import com.facebook.react.bridge.ReactApplicationContext ++import com.google.android.gms.common.ConnectionResult ++import com.google.android.gms.common.GoogleApiAvailability ++import com.google.android.gms.location.FusedLocationProviderClient ++import com.google.android.gms.location.LocationCallback ++import com.google.android.gms.location.LocationRequest ++import com.google.android.gms.location.LocationResult ++import com.google.android.gms.location.LocationServices ++import com.google.android.gms.location.Priority + import java.util.concurrent.ConcurrentHashMap + import java.util.concurrent.atomic.AtomicInteger + +@@ -19,8 +27,11 @@ + private val watchCallbacks = ConcurrentHashMap() + private val watchIdGenerator = AtomicInteger(0) + private var locationListener: LocationListener? = null ++ private var fusedLocationCallback: LocationCallback? = null ++ private var fusedLocationClient: FusedLocationProviderClient? = null + private var watchedProvider: String? = null + private var currentOptions: CompatGeolocationOptions? = null ++ private var usingFusedProvider = false + + data class WatchCallback( + val success: (CompatGeolocationResponse) -> Unit, +@@ -54,18 +65,80 @@ + } + + fun stopObserving() { +- val locationManager = +- reactContext.getSystemService(Context.LOCATION_SERVICE) as? LocationManager ++ if (usingFusedProvider) { ++ fusedLocationCallback?.let { callback -> ++ fusedLocationClient?.removeLocationUpdates(callback) ++ } ++ fusedLocationCallback = null ++ fusedLocationClient = null ++ } else { ++ val locationManager = ++ reactContext.getSystemService(Context.LOCATION_SERVICE) as? LocationManager ++ locationListener?.let { listener -> locationManager?.removeUpdates(listener) } ++ } + +- locationListener?.let { listener -> locationManager?.removeUpdates(listener) } +- + locationListener = null + watchedProvider = null + currentOptions = null ++ usingFusedProvider = false + watchCallbacks.clear() + } + + private fun startObserving(options: CompatGeolocationOptions?) { ++ // Use FusedLocationProviderClient when Play Services are available ++ if (isGooglePlayServicesAvailable()) { ++ startObservingWithFused(options) ++ return ++ } ++ ++ // Fallback to basic LocationManager ++ startObservingWithLocationManager(options) ++ } ++ ++ private fun startObservingWithFused(options: CompatGeolocationOptions?) { ++ val opts = parseOptions(options) ++ val client = LocationServices.getFusedLocationProviderClient(reactContext) ++ ++ val locationRequest = LocationRequest.Builder( ++ if (opts.androidAccuracy.mode == AndroidAccuracyMode.HIGH) ++ Priority.PRIORITY_HIGH_ACCURACY ++ else ++ Priority.PRIORITY_BALANCED_POWER_ACCURACY, ++ opts.interval.toLong() ++ ) ++ .setMinUpdateDistanceMeters(opts.distanceFilter.toFloat()) ++ .build() ++ ++ val callback = object : LocationCallback() { ++ override fun onLocationResult(locationResult: LocationResult) { ++ val location = locationResult.lastLocation ?: return ++ val position = locationToPosition(location) ++ watchCallbacks.values.forEach { watchCallback -> watchCallback.success(position) } ++ } ++ } ++ ++ try { ++ client.requestLocationUpdates( ++ locationRequest, ++ callback, ++ Looper.getMainLooper() ++ ) ++ fusedLocationClient = client ++ fusedLocationCallback = callback ++ usingFusedProvider = true ++ currentOptions = options ++ } catch (e: SecurityException) { ++ Log.e(TAG, "SecurityException: ${e.message}") ++ emitErrorToAll( ++ createError( ++ GetCurrentPosition.PERMISSION_DENIED, ++ "Location permission denied: ${e.message}" ++ ) ++ ) ++ } ++ } ++ ++ private fun startObservingWithLocationManager(options: CompatGeolocationOptions?) { + val locationManager = + reactContext.getSystemService(Context.LOCATION_SERVICE) as? LocationManager + +@@ -143,6 +216,11 @@ + } + } + ++ private fun isGooglePlayServicesAvailable(): Boolean { ++ return GoogleApiAvailability.getInstance() ++ .isGooglePlayServicesAvailable(reactContext.applicationContext) == ConnectionResult.SUCCESS ++ } ++ + private fun emitErrorToAll(error: CompatGeolocationError) { + watchCallbacks.values.forEach { callback -> callback.error?.invoke(error) } + } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f9873dfbc..761d0463e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -209,9 +209,6 @@ importers: '@react-native-async-storage/async-storage': specifier: 2.2.0 version: 2.2.0(react-native@0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3)) - '@react-native-community/geolocation': - specifier: 3.4.0 - version: 3.4.0(react-native@0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3))(react@19.2.3) invariant: specifier: ^2.2.4 version: 2.2.4 @@ -221,6 +218,12 @@ importers: react-native-geocoder: specifier: 0.5.0 version: 0.5.0 + react-native-nitro-geolocation: + specifier: 1.4.2 + version: 1.4.2(react-native-nitro-modules@0.35.9(react-native@0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3))(react@19.2.3))(react-native@0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3))(react@19.2.3) + react-native-nitro-modules: + specifier: 0.35.9 + version: 0.35.9(react-native@0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3))(react@19.2.3) react-native-permissions: specifier: 5.5.1 version: 5.5.1(react-native@0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3))(react@19.2.3) @@ -2099,13 +2102,6 @@ packages: peerDependencies: react-native: 0.84.1 - '@react-native-community/geolocation@3.4.0': - resolution: {integrity: sha512-bzZH89/cwmpkPMKKveoC72C4JH0yF4St5Ceg/ZM9pA1SqX9MlRIrIrrOGZ/+yi++xAvFDiYfihtn9TvXWU9/rA==} - engines: {node: '>=18.0.0'} - peerDependencies: - react: 19.2.3 - react-native: 0.84.1 - '@react-native-community/netinfo@11.5.2': resolution: {integrity: sha512-/g0m65BtX9HU+bPiCH2517bOHpEIUsGrWFXDzi1a5nNKn5KujQgm04WhL7/OSXWKHyrT8VVtUoJA0XKRxueBpQ==} peerDependencies: @@ -6138,6 +6134,19 @@ packages: react: 19.2.3 react-native: 0.84.1 + react-native-nitro-geolocation@1.4.2: + resolution: {integrity: sha512-woUfdQgzWeTFrluUkfLyHIAPCJFCX00BPWDC+1w6c0eLkkr9SNFX0UFANdEP5aOBw+LGhb4utH/LmeVl3X3MmQ==} + peerDependencies: + react: 19.2.3 + react-native: 0.84.1 + react-native-nitro-modules: '*' + + react-native-nitro-modules@0.35.9: + resolution: {integrity: sha512-yCO6eJ85SPPUo4a4an7H5oj6wPCSIT72fbjr5WZ/20n6zswaJ2gNNpnWtg2We0AZwkAOjSqkOJ0Vjc05p6kGiA==} + peerDependencies: + react: 19.2.3 + react-native: 0.84.1 + react-native-permissions@5.5.1: resolution: {integrity: sha512-nTKFoj47b6EXNqbbg+8VFwBWMpxF1/UTbrNBLpXkWpt005pH4BeFv/NwpcC1iNhToKBrxQD+5kI0z6+kTYoYWA==} peerDependencies: @@ -9006,11 +9015,6 @@ snapshots: dependencies: react-native: 0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3) - '@react-native-community/geolocation@3.4.0(react-native@0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3))(react@19.2.3)': - dependencies: - react: 19.2.3 - react-native: 0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3) - '@react-native-community/netinfo@11.5.2(react-native@0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3))(react@19.2.3)': dependencies: react: 19.2.3 @@ -13972,6 +13976,17 @@ snapshots: react-native: 0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3) react-native-animatable: 1.3.3 + react-native-nitro-geolocation@1.4.2(react-native-nitro-modules@0.35.9(react-native@0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3))(react@19.2.3))(react-native@0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3))(react@19.2.3): + dependencies: + react: 19.2.3 + react-native: 0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3) + react-native-nitro-modules: 0.35.9(react-native@0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3))(react@19.2.3) + + react-native-nitro-modules@0.35.9(react-native@0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3))(react@19.2.3): + dependencies: + react: 19.2.3 + react-native: 0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3) + react-native-permissions@5.5.1(react-native@0.84.1(@babel/core@7.29.0)(@react-native/metro-config@0.85.3(@babel/core@7.29.0))(@types/react@19.2.15)(react@19.2.3))(react@19.2.3): dependencies: react: 19.2.3