feat(smart-app): implement complete mobile app MVP

- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
This commit is contained in:
Eric FELIXINE
2026-06-01 18:00:35 -04:00
parent 08ca495bde
commit e30ae8ed09
35578 changed files with 3703534 additions and 43 deletions

View File

@@ -0,0 +1,3 @@
declare const _default: any;
export default _default;
//# sourceMappingURL=ExpoLocation.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ExpoLocation.d.ts","sourceRoot":"","sources":["../src/ExpoLocation.ts"],"names":[],"mappings":";AACA,wBAAmD"}

View File

@@ -0,0 +1,3 @@
import { requireNativeModule } from 'expo-modules-core';
export default requireNativeModule('ExpoLocation');
//# sourceMappingURL=ExpoLocation.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ExpoLocation.js","sourceRoot":"","sources":["../src/ExpoLocation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,eAAe,mBAAmB,CAAC,cAAc,CAAC,CAAC","sourcesContent":["import { requireNativeModule } from 'expo-modules-core';\nexport default requireNativeModule('ExpoLocation');\n"]}

View File

@@ -0,0 +1,31 @@
import { PermissionResponse } from 'expo-modules-core';
import { LocationLastKnownOptions, LocationObject, LocationOptions } from './Location.types';
/**
* Gets the permission details. The implementation is not very good as it's not
* possible to query for permission on all browsers, apparently only the
* latest versions will support this.
*/
declare function getPermissionsAsync(shouldAsk?: boolean): Promise<PermissionResponse>;
declare const _default: {
getProviderStatusAsync(): Promise<{
locationServicesEnabled: boolean;
}>;
getLastKnownPositionAsync(options?: LocationLastKnownOptions): Promise<LocationObject | null>;
getCurrentPositionAsync(options: LocationOptions): Promise<LocationObject>;
removeWatchAsync(watchId: any): Promise<void>;
watchDeviceHeading(headingId: any): Promise<void>;
hasServicesEnabledAsync(): Promise<boolean>;
geocodeAsync(): Promise<any[]>;
reverseGeocodeAsync(): Promise<any[]>;
watchPositionImplAsync(watchId: string, options: LocationOptions): Promise<string>;
getPermissionsAsync: typeof getPermissionsAsync;
requestPermissionsAsync(): Promise<PermissionResponse>;
requestForegroundPermissionsAsync(): Promise<PermissionResponse>;
requestBackgroundPermissionsAsync(): Promise<PermissionResponse>;
getForegroundPermissionsAsync(): Promise<PermissionResponse>;
getBackgroundPermissionsAsync(): Promise<PermissionResponse>;
startObserving(): void;
stopObserving(): void;
};
export default _default;
//# sourceMappingURL=ExpoLocation.web.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ExpoLocation.web.d.ts","sourceRoot":"","sources":["../src/ExpoLocation.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAyC,MAAM,mBAAmB,CAAC;AAE9F,OAAO,EAEL,wBAAwB,EACxB,cAAc,EACd,eAAe,EAChB,MAAM,kBAAkB,CAAC;AA2C1B;;;;GAIG;AACH,iBAAe,mBAAmB,CAAC,SAAS,UAAQ,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAkEjF;;8BAKiC,QAAQ;QAAE,uBAAuB,EAAE,OAAO,CAAA;KAAE,CAAC;wCAMlE,wBAAwB,GAChC,QAAQ,cAAc,GAAG,IAAI,CAAC;qCAMM,eAAe,GAAG,QAAQ,cAAc,CAAC;oCAa/C,QAAQ,IAAI,CAAC;wCAGT,QAAQ,IAAI,CAAC;+BAGjB,QAAQ,OAAO,CAAC;oBAG3B,QAAQ,GAAG,EAAE,CAAC;2BAGP,QAAQ,GAAG,EAAE,CAAC;oCAGL,MAAM,WAAW,eAAe,GAAG,QAAQ,MAAM,CAAC;;+BAoBvD,QAAQ,kBAAkB,CAAC;yCAGjB,QAAQ,kBAAkB,CAAC;yCAG3B,QAAQ,kBAAkB,CAAC;qCAG/B,QAAQ,kBAAkB,CAAC;qCAG3B,QAAQ,kBAAkB,CAAC;;;;AA1EpE,wBAiFE"}

View File

@@ -0,0 +1,177 @@
import { PermissionStatus, UnavailabilityError } from 'expo-modules-core';
import { LocationAccuracy, } from './Location.types';
import { LocationEventEmitter } from './LocationEventEmitter';
class GeocoderError extends Error {
code;
constructor() {
super('Geocoder service is not available for this device.');
this.code = 'E_NO_GEOCODER';
}
}
/**
* Converts `GeolocationPosition` to JavaScript object.
*/
function geolocationPositionToJSON(position) {
const { coords, timestamp } = position;
return {
coords: {
latitude: coords.latitude,
longitude: coords.longitude,
altitude: coords.altitude,
accuracy: coords.accuracy,
altitudeAccuracy: coords.altitudeAccuracy,
heading: coords.heading,
speed: coords.speed,
},
timestamp,
};
}
/**
* Checks whether given location didn't exceed given `maxAge` and fits in the required accuracy.
*/
function isLocationValid(location, options) {
const maxAge = typeof options.maxAge === 'number' ? options.maxAge : Infinity;
const requiredAccuracy = typeof options.requiredAccuracy === 'number' ? options.requiredAccuracy : Infinity;
const locationAccuracy = location.coords.accuracy ?? Infinity;
return Date.now() - location.timestamp <= maxAge && locationAccuracy <= requiredAccuracy;
}
/**
* Gets the permission details. The implementation is not very good as it's not
* possible to query for permission on all browsers, apparently only the
* latest versions will support this.
*/
async function getPermissionsAsync(shouldAsk = false) {
if (!navigator?.permissions?.query) {
throw new UnavailabilityError('expo-location', 'navigator.permissions API is not available');
}
const permission = await navigator.permissions.query({ name: 'geolocation' });
if (permission.state === 'granted') {
return {
status: PermissionStatus.GRANTED,
granted: true,
canAskAgain: true,
expires: 0,
};
}
if (permission.state === 'denied') {
return {
status: PermissionStatus.DENIED,
granted: false,
canAskAgain: true,
expires: 0,
};
}
if (shouldAsk) {
return new Promise((resolve) => {
navigator.geolocation.getCurrentPosition(() => {
resolve({
status: PermissionStatus.GRANTED,
granted: true,
canAskAgain: true,
expires: 0,
});
}, (positionError) => {
if (positionError.code === positionError.PERMISSION_DENIED) {
resolve({
status: PermissionStatus.DENIED,
granted: false,
canAskAgain: true,
expires: 0,
});
return;
}
resolve({
status: PermissionStatus.GRANTED,
granted: false,
canAskAgain: true,
expires: 0,
});
});
});
}
// The permission state is 'prompt' when the permission has not been requested
// yet, tested on Chrome.
return {
status: PermissionStatus.UNDETERMINED,
granted: false,
canAskAgain: true,
expires: 0,
};
}
let lastKnownPosition = null;
export default {
async getProviderStatusAsync() {
return {
locationServicesEnabled: 'geolocation' in navigator,
};
},
async getLastKnownPositionAsync(options = {}) {
if (lastKnownPosition && isLocationValid(lastKnownPosition, options)) {
return lastKnownPosition;
}
return null;
},
async getCurrentPositionAsync(options) {
return new Promise((resolve, reject) => {
const resolver = (position) => {
lastKnownPosition = geolocationPositionToJSON(position);
resolve(lastKnownPosition);
};
navigator.geolocation.getCurrentPosition(resolver, reject, {
maximumAge: Infinity,
enableHighAccuracy: (options.accuracy ?? 0) > LocationAccuracy.Balanced,
...options,
});
});
},
async removeWatchAsync(watchId) {
navigator.geolocation.clearWatch(watchId);
},
async watchDeviceHeading(headingId) {
console.warn('Location.watchDeviceHeading: is not supported on web');
},
async hasServicesEnabledAsync() {
return 'geolocation' in navigator;
},
async geocodeAsync() {
throw new GeocoderError();
},
async reverseGeocodeAsync() {
throw new GeocoderError();
},
async watchPositionImplAsync(watchId, options) {
return new Promise((resolve) => {
// @ts-ignore: the types here need to be fixed
watchId = global.navigator.geolocation.watchPosition((position) => {
lastKnownPosition = geolocationPositionToJSON(position);
LocationEventEmitter.emit('Expo.locationChanged', {
watchId,
location: lastKnownPosition,
});
}, undefined,
// @ts-ignore: the options object needs to be fixed
options);
resolve(watchId);
});
},
getPermissionsAsync,
async requestPermissionsAsync() {
return getPermissionsAsync(true);
},
async requestForegroundPermissionsAsync() {
return getPermissionsAsync(true);
},
async requestBackgroundPermissionsAsync() {
return getPermissionsAsync(true);
},
async getForegroundPermissionsAsync() {
return getPermissionsAsync();
},
async getBackgroundPermissionsAsync() {
return getPermissionsAsync();
},
// no-op
startObserving() { },
stopObserving() { },
};
//# sourceMappingURL=ExpoLocation.web.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
/**
* Polyfills `navigator.geolocation` for interop with the core React Native and Web API approach to geolocation.
*/
export declare function installWebGeolocationPolyfill(): void;
//# sourceMappingURL=GeolocationPolyfill.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"GeolocationPolyfill.d.ts","sourceRoot":"","sources":["../src/GeolocationPolyfill.ts"],"names":[],"mappings":"AAgBA;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,IAAI,CAqBpD"}

View File

@@ -0,0 +1,62 @@
import { Platform } from 'expo-modules-core';
import ExpoLocation from './ExpoLocation';
import { LocationAccuracy } from './Location.types';
import { LocationSubscriber } from './LocationSubscribers';
// @needsAudit
/**
* Polyfills `navigator.geolocation` for interop with the core React Native and Web API approach to geolocation.
*/
export function installWebGeolocationPolyfill() {
if (Platform.OS !== 'web') {
// Make sure `window.navigator` is defined in the global scope.
if (!('window' in global)) {
global.window = global;
}
if (!('navigator' in global.window)) {
global.window.navigator = {};
}
// @ts-ignore
window.navigator.geolocation = {
getCurrentPosition,
watchPosition,
clearWatch,
// We don't polyfill stopObserving, this is an internal method that probably should not even exist
// in react-native docs
stopObserving: () => { },
};
}
}
function convertGeolocationOptions(options) {
return {
accuracy: options.enableHighAccuracy ? LocationAccuracy.High : LocationAccuracy.Balanced,
};
}
function getCurrentPosition(success, error = () => { }, options = {}) {
_getCurrentPositionAsyncWrapper(success, error, options);
}
// This function exists to let us continue to return undefined from getCurrentPosition, while still
// using async/await for the internal implementation of it
async function _getCurrentPositionAsyncWrapper(success, error, options) {
try {
await ExpoLocation.requestPermissionsAsync();
const result = await ExpoLocation.getCurrentPositionAsync(convertGeolocationOptions(options));
success(result);
}
catch (e) {
error(e);
}
}
// Polyfill: navigator.geolocation.watchPosition
function watchPosition(success, error, options) {
const watchId = LocationSubscriber.registerCallback(success);
ExpoLocation.watchPositionImplAsync(watchId, options).catch((err) => {
LocationSubscriber.unregisterCallback(watchId);
error({ watchId, message: err.message, code: err.code });
});
return watchId;
}
// Polyfill: navigator.geolocation.clearWatch
function clearWatch(watchId) {
LocationSubscriber.unregisterCallback(watchId);
}
//# sourceMappingURL=GeolocationPolyfill.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"GeolocationPolyfill.js","sourceRoot":"","sources":["../src/GeolocationPolyfill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAkB,gBAAgB,EAAmB,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAW3D,cAAc;AACd;;GAEG;AACH,MAAM,UAAU,6BAA6B;IAC3C,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE;QACzB,+DAA+D;QAC/D,IAAI,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,EAAE;YACzB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;SACxB;QACD,IAAI,CAAC,CAAC,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE;YACnC,MAAM,CAAC,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC;SAC9B;QAED,aAAa;QACb,MAAM,CAAC,SAAS,CAAC,WAAW,GAAG;YAC7B,kBAAkB;YAClB,aAAa;YACb,UAAU;YAEV,kGAAkG;YAClG,uBAAuB;YACvB,aAAa,EAAE,GAAG,EAAE,GAAE,CAAC;SACxB,CAAC;KACH;AACH,CAAC;AAED,SAAS,yBAAyB,CAAC,OAA2B;IAC5D,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,QAAQ;KACzF,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CACzB,OAAmC,EACnC,QAAkC,GAAG,EAAE,GAAE,CAAC,EAC1C,UAA8B,EAAE;IAEhC,+BAA+B,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC;AAED,mGAAmG;AACnG,0DAA0D;AAC1D,KAAK,UAAU,+BAA+B,CAC5C,OAAmC,EACnC,KAA+B,EAC/B,OAA2B;IAE3B,IAAI;QACF,MAAM,YAAY,CAAC,uBAAuB,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,uBAAuB,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9F,OAAO,CAAC,MAAM,CAAC,CAAC;KACjB;IAAC,OAAO,CAAC,EAAE;QACV,KAAK,CAAC,CAAC,CAAC,CAAC;KACV;AACH,CAAC;AAED,gDAAgD;AAChD,SAAS,aAAa,CACpB,OAAmC,EACnC,KAA+B,EAC/B,OAA2B;IAE3B,MAAM,OAAO,GAAG,kBAAkB,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE7D,YAAY,CAAC,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QAClE,kBAAkB,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAC/C,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,6CAA6C;AAC7C,SAAS,UAAU,CAAC,OAAe;IACjC,kBAAkB,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACjD,CAAC","sourcesContent":["import { Platform } from 'expo-modules-core';\n\nimport ExpoLocation from './ExpoLocation';\nimport { LocationObject, LocationAccuracy, LocationOptions } from './Location.types';\nimport { LocationSubscriber } from './LocationSubscribers';\n\ntype GeolocationSuccessCallback = (data: LocationObject) => void;\ntype GeolocationErrorCallback = (error: any) => void;\n\ntype GeolocationOptions = {\n enableHighAccuracy?: boolean;\n};\n\ndeclare const global: any;\n\n// @needsAudit\n/**\n * Polyfills `navigator.geolocation` for interop with the core React Native and Web API approach to geolocation.\n */\nexport function installWebGeolocationPolyfill(): void {\n if (Platform.OS !== 'web') {\n // Make sure `window.navigator` is defined in the global scope.\n if (!('window' in global)) {\n global.window = global;\n }\n if (!('navigator' in global.window)) {\n global.window.navigator = {};\n }\n\n // @ts-ignore\n window.navigator.geolocation = {\n getCurrentPosition,\n watchPosition,\n clearWatch,\n\n // We don't polyfill stopObserving, this is an internal method that probably should not even exist\n // in react-native docs\n stopObserving: () => {},\n };\n }\n}\n\nfunction convertGeolocationOptions(options: GeolocationOptions): LocationOptions {\n return {\n accuracy: options.enableHighAccuracy ? LocationAccuracy.High : LocationAccuracy.Balanced,\n };\n}\n\nfunction getCurrentPosition(\n success: GeolocationSuccessCallback,\n error: GeolocationErrorCallback = () => {},\n options: GeolocationOptions = {}\n): void {\n _getCurrentPositionAsyncWrapper(success, error, options);\n}\n\n// This function exists to let us continue to return undefined from getCurrentPosition, while still\n// using async/await for the internal implementation of it\nasync function _getCurrentPositionAsyncWrapper(\n success: GeolocationSuccessCallback,\n error: GeolocationErrorCallback,\n options: GeolocationOptions\n): Promise<any> {\n try {\n await ExpoLocation.requestPermissionsAsync();\n const result = await ExpoLocation.getCurrentPositionAsync(convertGeolocationOptions(options));\n success(result);\n } catch (e) {\n error(e);\n }\n}\n\n// Polyfill: navigator.geolocation.watchPosition\nfunction watchPosition(\n success: GeolocationSuccessCallback,\n error: GeolocationErrorCallback,\n options: GeolocationOptions\n) {\n const watchId = LocationSubscriber.registerCallback(success);\n\n ExpoLocation.watchPositionImplAsync(watchId, options).catch((err) => {\n LocationSubscriber.unregisterCallback(watchId);\n error({ watchId, message: err.message, code: err.code });\n });\n\n return watchId;\n}\n\n// Polyfill: navigator.geolocation.clearWatch\nfunction clearWatch(watchId: number) {\n LocationSubscriber.unregisterCallback(watchId);\n}\n"]}

View File

@@ -0,0 +1,256 @@
import { PermissionStatus, PermissionResponse, PermissionHookOptions } from 'expo-modules-core';
import { LocationAccuracy, LocationCallback, LocationGeocodedAddress, LocationGeocodedLocation, LocationHeadingCallback, LocationHeadingObject, LocationLastKnownOptions, LocationObject, LocationOptions, LocationPermissionResponse, LocationProviderStatus, LocationRegion, LocationSubscription, LocationTaskOptions, LocationActivityType, LocationGeofencingEventType, LocationGeofencingRegionState, LocationGeocodingOptions } from './Location.types';
import { LocationEventEmitter } from './LocationEventEmitter';
import { _getCurrentWatchId } from './LocationSubscribers';
/**
* @deprecated The Geocoding web api is no longer available from SDK 49 onwards. Use [Place Autocomplete](https://developers.google.com/maps/documentation/places/web-service/autocomplete) instead.
* @param _apiKey Google API key obtained from Google API Console. This API key must have `Geocoding API`
* enabled, otherwise your geocoding requests will be denied.
*/
declare function setGoogleApiKey(_apiKey: string): void;
/**
* Check status of location providers.
* @return A promise which fulfills with an object of type [LocationProviderStatus](#locationproviderstatus).
*/
export declare function getProviderStatusAsync(): Promise<LocationProviderStatus>;
/**
* Asks the user to turn on high accuracy location mode which enables network provider that uses
* Google Play services to improve location accuracy and location-based services.
* @return A promise resolving as soon as the user accepts the dialog. Rejects if denied.
*/
export declare function enableNetworkProviderAsync(): Promise<void>;
/**
* Requests for one-time delivery of the user's current location.
* Depending on given `accuracy` option it may take some time to resolve,
* especially when you're inside a building.
* > __Note:__ Calling it causes the location manager to obtain a location fix which may take several
* > seconds. Consider using [`Location.getLastKnownPositionAsync`](#locationgetlastknownpositionasyncoptions)
* > if you expect to get a quick response and high accuracy is not required.
* @param options
* @return A promise which fulfills with an object of type [`LocationObject`](#locationobject).
*/
export declare function getCurrentPositionAsync(options?: LocationOptions): Promise<LocationObject>;
/**
* Gets the last known position of the device or `null` if it's not available or doesn't match given
* requirements such as maximum age or required accuracy.
* It's considered to be faster than `getCurrentPositionAsync` as it doesn't request for the current
* location, but keep in mind the returned location may not be up-to-date.
* @param options
* @return A promise which fulfills with an object of type [LocationObject](#locationobject) or
* `null` if it's not available or doesn't match given requirements such as maximum age or required
* accuracy.
*/
export declare function getLastKnownPositionAsync(options?: LocationLastKnownOptions): Promise<LocationObject | null>;
/**
* Subscribe to location updates from the device. Please note that updates will only occur while the
* application is in the foreground. To get location updates while in background you'll need to use
* [Location.startLocationUpdatesAsync](#locationstartlocationupdatesasynctaskname-options).
* @param options
* @param callback This function is called on each location update. It receives an object of type
* [`LocationObject`](#locationobject) as the first argument.
* @return A promise which fulfills with a [`LocationSubscription`](#locationsubscription) object.
*/
export declare function watchPositionAsync(options: LocationOptions, callback: LocationCallback): Promise<LocationSubscription>;
/**
* Gets the current heading information from the device. To simplify, it calls `watchHeadingAsync`
* and waits for a couple of updates, and then returns the one that is accurate enough.
* @return A promise which fulfills with an object of type [LocationHeadingObject](#locationheadingobject).
*/
export declare function getHeadingAsync(): Promise<LocationHeadingObject>;
/**
* Subscribe to compass updates from the device.
* @param callback This function is called on each compass update. It receives an object of type
* [LocationHeadingObject](#locationheadingobject) as the first argument.
* @return A promise which fulfills with a [`LocationSubscription`](#locationsubscription) object.
*/
export declare function watchHeadingAsync(callback: LocationHeadingCallback): Promise<LocationSubscription>;
/**
* Geocode an address string to latitude-longitude location.
* > **Note**: Using the Geocoding web api is no longer supported. Use [Place Autocomplete](https://developers.google.com/maps/documentation/places/web-service/autocomplete) instead.
*
* > **Note**: Geocoding is resource consuming and has to be used reasonably. Creating too many
* > requests at a time can result in an error, so they have to be managed properly.
* > It's also discouraged to use geocoding while the app is in the background and its results won't
* > be shown to the user immediately.
*
* > On Android, you must request a location permission (`Permissions.LOCATION`) from the user
* > before geocoding can be used.
* @param address A string representing address, eg. `"Baker Street London"`.
* @param options
* @return A promise which fulfills with an array (in most cases its size is 1) of [`LocationGeocodedLocation`](#locationgeocodedlocation) objects.
*/
export declare function geocodeAsync(address: string, options?: LocationGeocodingOptions): Promise<LocationGeocodedLocation[]>;
/**
* Reverse geocode a location to postal address.
* > **Note**: Using the Geocoding web api is no longer supported. Use [Place Autocomplete](https://developers.google.com/maps/documentation/places/web-service/autocomplete) instead.
*
* > **Note**: Geocoding is resource consuming and has to be used reasonably. Creating too many
* > requests at a time can result in an error, so they have to be managed properly.
* > It's also discouraged to use geocoding while the app is in the background and its results won't
* > be shown to the user immediately.
*
* > On Android, you must request a location permission (`Permissions.LOCATION`) from the user
* > before geocoding can be used.
* @param location An object representing a location.
* @param options
* @return A promise which fulfills with an array (in most cases its size is 1) of [`LocationGeocodedAddress`](#locationgeocodedaddress) objects.
*/
export declare function reverseGeocodeAsync(location: Pick<LocationGeocodedLocation, 'latitude' | 'longitude'>, options?: LocationGeocodingOptions): Promise<LocationGeocodedAddress[]>;
/**
* Checks user's permissions for accessing location.
* @return A promise that fulfills with an object of type [LocationPermissionResponse](#locationpermissionresponse).
* @deprecated Use [`getForegroundPermissionsAsync`](#locationgetforegroundpermissionsasync) or [`getBackgroundPermissionsAsync`](#locationgetbackgroundpermissionsasync) instead.
*/
export declare function getPermissionsAsync(): Promise<LocationPermissionResponse>;
/**
* Asks the user to grant permissions for location.
* @return A promise that fulfills with an object of type [LocationPermissionResponse](#locationpermissionresponse).
* @deprecated Use [`requestForegroundPermissionsAsync`](#locationrequestforegroundpermissionsasync) or [`requestBackgroundPermissionsAsync`](#locationrequestbackgroundpermissionsasync) instead.
*/
export declare function requestPermissionsAsync(): Promise<LocationPermissionResponse>;
/**
* Checks user's permissions for accessing location while the app is in the foreground.
* @return A promise that fulfills with an object of type [PermissionResponse](#permissionresponse).
*/
export declare function getForegroundPermissionsAsync(): Promise<LocationPermissionResponse>;
/**
* Asks the user to grant permissions for location while the app is in the foreground.
* @return A promise that fulfills with an object of type [PermissionResponse](#permissionresponse).
*/
export declare function requestForegroundPermissionsAsync(): Promise<LocationPermissionResponse>;
/**
* Check or request permissions for the foreground location.
* This uses both `requestForegroundPermissionsAsync` and `getForegroundPermissionsAsync` to interact with the permissions.
*
* @example
* ```ts
* const [status, requestPermission] = Location.useForegroundPermissions();
* ```
*/
export declare const useForegroundPermissions: (options?: PermissionHookOptions<object> | undefined) => [LocationPermissionResponse | null, () => Promise<LocationPermissionResponse>, () => Promise<LocationPermissionResponse>];
/**
* Checks user's permissions for accessing location while the app is in the background.
* @return A promise that fulfills with an object of type [PermissionResponse](#permissionresponse).
*/
export declare function getBackgroundPermissionsAsync(): Promise<PermissionResponse>;
/**
* Asks the user to grant permissions for location while the app is in the background.
* On __Android 11 or higher__: this method will open the system settings page - before that happens
* you should explain to the user why your application needs background location permission.
* For example, you can use `Modal` component from `react-native` to do that.
* > __Note__: Foreground permissions should be granted before asking for the background permissions
* (your app can't obtain background permission without foreground permission).
* @return A promise that fulfills with an object of type [PermissionResponse](#permissionresponse).
*/
export declare function requestBackgroundPermissionsAsync(): Promise<PermissionResponse>;
/**
* Check or request permissions for the background location.
* This uses both `requestBackgroundPermissionsAsync` and `getBackgroundPermissionsAsync` to
* interact with the permissions.
*
* @example
* ```ts
* const [status, requestPermission] = Location.useBackgroundPermissions();
* ```
*/
export declare const useBackgroundPermissions: (options?: PermissionHookOptions<object> | undefined) => [PermissionResponse | null, () => Promise<PermissionResponse>, () => Promise<PermissionResponse>];
/**
* Checks whether location services are enabled by the user.
* @return A promise which fulfills to `true` if location services are enabled on the device,
* or `false` if not.
*/
export declare function hasServicesEnabledAsync(): Promise<boolean>;
export declare function isBackgroundLocationAvailableAsync(): Promise<boolean>;
/**
* Registers for receiving location updates that can also come when the app is in the background.
*
* # Task parameters
*
* Background location task will be receiving following data:
* - `locations` - An array of the new locations.
*
* ```ts
* import * as TaskManager from 'expo-task-manager';
*
* TaskManager.defineTask(YOUR_TASK_NAME, ({ data: { locations }, error }) => {
* if (error) {
* // check `error.message` for more details.
* return;
* }
* console.log('Received new locations', locations);
* });
* ```
*
* @param taskName Name of the task receiving location updates.
* @param options An object of options passed to the location manager.
*
* @return A promise resolving once the task with location updates is registered.
*/
export declare function startLocationUpdatesAsync(taskName: string, options?: LocationTaskOptions): Promise<void>;
/**
* Stops geofencing for specified task.
* @param taskName Name of the background location task to stop.
* @return A promise resolving as soon as the task is unregistered.
*/
export declare function stopLocationUpdatesAsync(taskName: string): Promise<void>;
/**
* @param taskName Name of the location task to check.
* @return A promise which fulfills with boolean value indicating whether the location task is
* started or not.
*/
export declare function hasStartedLocationUpdatesAsync(taskName: string): Promise<boolean>;
/**
* Starts geofencing for given regions. When the new event comes, the task with specified name will
* be called with the region that the device enter to or exit from.
* If you want to add or remove regions from already running geofencing task, you can just call
* `startGeofencingAsync` again with the new array of regions.
*
* # Task parameters
*
* Geofencing task will be receiving following data:
* - `eventType` - Indicates the reason for calling the task, which can be triggered by entering or exiting the region.
* See [GeofencingEventType](#geofencingeventtype).
* - `region` - Object containing details about updated region. See [LocationRegion](#locationregion) for more details.
*
* @param taskName Name of the task that will be called when the device enters or exits from specified regions.
* @param regions Array of region objects to be geofenced.
*
* @return A promise resolving as soon as the task is registered.
*
* @example
* ```ts
* import { GeofencingEventType } from 'expo-location';
* import * as TaskManager from 'expo-task-manager';
*
* TaskManager.defineTask(YOUR_TASK_NAME, ({ data: { eventType, region }, error }) => {
* if (error) {
* // check `error.message` for more details.
* return;
* }
* if (eventType === GeofencingEventType.Enter) {
* console.log("You've entered region:", region);
* } else if (eventType === GeofencingEventType.Exit) {
* console.log("You've left region:", region);
* }
* });
* ```
*/
export declare function startGeofencingAsync(taskName: string, regions?: LocationRegion[]): Promise<void>;
/**
* Stops geofencing for specified task. It unregisters the background task so the app will not be
* receiving any updates, especially in the background.
* @param taskName Name of the task to unregister.
* @return A promise resolving as soon as the task is unregistered.
*/
export declare function stopGeofencingAsync(taskName: string): Promise<void>;
/**
* @param taskName Name of the geofencing task to check.
* @return A promise which fulfills with boolean value indicating whether the geofencing task is
* started or not.
*/
export declare function hasStartedGeofencingAsync(taskName: string): Promise<boolean>;
export { LocationEventEmitter as EventEmitter, _getCurrentWatchId };
export { LocationAccuracy as Accuracy, LocationActivityType as ActivityType, LocationGeofencingEventType as GeofencingEventType, LocationGeofencingRegionState as GeofencingRegionState, PermissionStatus, PermissionHookOptions, setGoogleApiKey, };
export { installWebGeolocationPolyfill } from './GeolocationPolyfill';
export * from './Location.types';
//# sourceMappingURL=Location.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Location.d.ts","sourceRoot":"","sources":["../src/Location.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,418 @@
import { PermissionStatus, createPermissionHook, Platform, } from 'expo-modules-core';
import ExpoLocation from './ExpoLocation';
import { LocationAccuracy, LocationActivityType, LocationGeofencingEventType, LocationGeofencingRegionState, } from './Location.types';
import { LocationEventEmitter } from './LocationEventEmitter';
import { LocationSubscriber, HeadingSubscriber, _getCurrentWatchId } from './LocationSubscribers';
// @needsAudit
/**
* @deprecated The Geocoding web api is no longer available from SDK 49 onwards. Use [Place Autocomplete](https://developers.google.com/maps/documentation/places/web-service/autocomplete) instead.
* @param _apiKey Google API key obtained from Google API Console. This API key must have `Geocoding API`
* enabled, otherwise your geocoding requests will be denied.
*/
function setGoogleApiKey(_apiKey) { }
// @needsAudit
/**
* Check status of location providers.
* @return A promise which fulfills with an object of type [LocationProviderStatus](#locationproviderstatus).
*/
export async function getProviderStatusAsync() {
return ExpoLocation.getProviderStatusAsync();
}
// @needsAudit
/**
* Asks the user to turn on high accuracy location mode which enables network provider that uses
* Google Play services to improve location accuracy and location-based services.
* @return A promise resolving as soon as the user accepts the dialog. Rejects if denied.
*/
export async function enableNetworkProviderAsync() {
// If network provider is disabled (user's location mode is set to "Device only"),
// Android's location provider may not give you any results. Use this method in order to ask the user
// to change the location mode to "High accuracy" which uses Google Play services and enables network provider.
// `getCurrentPositionAsync` and `watchPositionAsync` are doing it automatically anyway.
if (Platform.OS === 'android') {
return ExpoLocation.enableNetworkProviderAsync();
}
}
// @needsAudit
/**
* Requests for one-time delivery of the user's current location.
* Depending on given `accuracy` option it may take some time to resolve,
* especially when you're inside a building.
* > __Note:__ Calling it causes the location manager to obtain a location fix which may take several
* > seconds. Consider using [`Location.getLastKnownPositionAsync`](#locationgetlastknownpositionasyncoptions)
* > if you expect to get a quick response and high accuracy is not required.
* @param options
* @return A promise which fulfills with an object of type [`LocationObject`](#locationobject).
*/
export async function getCurrentPositionAsync(options = {}) {
return ExpoLocation.getCurrentPositionAsync(options);
}
// @needsAudit
/**
* Gets the last known position of the device or `null` if it's not available or doesn't match given
* requirements such as maximum age or required accuracy.
* It's considered to be faster than `getCurrentPositionAsync` as it doesn't request for the current
* location, but keep in mind the returned location may not be up-to-date.
* @param options
* @return A promise which fulfills with an object of type [LocationObject](#locationobject) or
* `null` if it's not available or doesn't match given requirements such as maximum age or required
* accuracy.
*/
export async function getLastKnownPositionAsync(options = {}) {
return ExpoLocation.getLastKnownPositionAsync(options);
}
// @needsAudit
/**
* Subscribe to location updates from the device. Please note that updates will only occur while the
* application is in the foreground. To get location updates while in background you'll need to use
* [Location.startLocationUpdatesAsync](#locationstartlocationupdatesasynctaskname-options).
* @param options
* @param callback This function is called on each location update. It receives an object of type
* [`LocationObject`](#locationobject) as the first argument.
* @return A promise which fulfills with a [`LocationSubscription`](#locationsubscription) object.
*/
export async function watchPositionAsync(options, callback) {
const watchId = LocationSubscriber.registerCallback(callback);
await ExpoLocation.watchPositionImplAsync(watchId, options);
return {
remove() {
LocationSubscriber.unregisterCallback(watchId);
},
};
}
// @needsAudit
/**
* Gets the current heading information from the device. To simplify, it calls `watchHeadingAsync`
* and waits for a couple of updates, and then returns the one that is accurate enough.
* @return A promise which fulfills with an object of type [LocationHeadingObject](#locationheadingobject).
*/
export async function getHeadingAsync() {
return new Promise(async (resolve) => {
let tries = 0;
const subscription = await watchHeadingAsync((heading) => {
if (heading.accuracy > 1 || tries > 5) {
subscription.remove();
resolve(heading);
}
else {
tries += 1;
}
});
});
}
// @needsAudit
/**
* Subscribe to compass updates from the device.
* @param callback This function is called on each compass update. It receives an object of type
* [LocationHeadingObject](#locationheadingobject) as the first argument.
* @return A promise which fulfills with a [`LocationSubscription`](#locationsubscription) object.
*/
export async function watchHeadingAsync(callback) {
const watchId = HeadingSubscriber.registerCallback(callback);
await ExpoLocation.watchDeviceHeading(watchId);
return {
remove() {
HeadingSubscriber.unregisterCallback(watchId);
},
};
}
// @needsAudit
/**
* Geocode an address string to latitude-longitude location.
* > **Note**: Using the Geocoding web api is no longer supported. Use [Place Autocomplete](https://developers.google.com/maps/documentation/places/web-service/autocomplete) instead.
*
* > **Note**: Geocoding is resource consuming and has to be used reasonably. Creating too many
* > requests at a time can result in an error, so they have to be managed properly.
* > It's also discouraged to use geocoding while the app is in the background and its results won't
* > be shown to the user immediately.
*
* > On Android, you must request a location permission (`Permissions.LOCATION`) from the user
* > before geocoding can be used.
* @param address A string representing address, eg. `"Baker Street London"`.
* @param options
* @return A promise which fulfills with an array (in most cases its size is 1) of [`LocationGeocodedLocation`](#locationgeocodedlocation) objects.
*/
export async function geocodeAsync(address, options) {
if (typeof address !== 'string') {
throw new TypeError(`Address to geocode must be a string. Got ${address} instead.`);
}
if (options?.useGoogleMaps || Platform.OS === 'web') {
if (__DEV__) {
console.warn('The Geocoding API has been removed in SDK 49, use Place Autocomplete service instead' +
'(https://developers.google.com/maps/documentation/places/web-service/autocomplete)');
}
return [];
}
return await ExpoLocation.geocodeAsync(address);
}
// @needsAudit
/**
* Reverse geocode a location to postal address.
* > **Note**: Using the Geocoding web api is no longer supported. Use [Place Autocomplete](https://developers.google.com/maps/documentation/places/web-service/autocomplete) instead.
*
* > **Note**: Geocoding is resource consuming and has to be used reasonably. Creating too many
* > requests at a time can result in an error, so they have to be managed properly.
* > It's also discouraged to use geocoding while the app is in the background and its results won't
* > be shown to the user immediately.
*
* > On Android, you must request a location permission (`Permissions.LOCATION`) from the user
* > before geocoding can be used.
* @param location An object representing a location.
* @param options
* @return A promise which fulfills with an array (in most cases its size is 1) of [`LocationGeocodedAddress`](#locationgeocodedaddress) objects.
*/
export async function reverseGeocodeAsync(location, options) {
if (typeof location.latitude !== 'number' || typeof location.longitude !== 'number') {
throw new TypeError('Location to reverse-geocode must be an object with number properties `latitude` and `longitude`.');
}
if (options?.useGoogleMaps || Platform.OS === 'web') {
if (__DEV__) {
console.warn('The Geocoding API has been removed in SDK 49, use Place Autocomplete service instead' +
'(https://developers.google.com/maps/documentation/places/web-service/autocomplete)');
}
return [];
}
return await ExpoLocation.reverseGeocodeAsync(location);
}
// @needsAudit
/**
* Checks user's permissions for accessing location.
* @return A promise that fulfills with an object of type [LocationPermissionResponse](#locationpermissionresponse).
* @deprecated Use [`getForegroundPermissionsAsync`](#locationgetforegroundpermissionsasync) or [`getBackgroundPermissionsAsync`](#locationgetbackgroundpermissionsasync) instead.
*/
export async function getPermissionsAsync() {
console.warn(`"getPermissionsAsync()" is now deprecated. Please use "getForegroundPermissionsAsync()" or "getBackgroundPermissionsAsync()" instead.`);
return await ExpoLocation.getPermissionsAsync();
}
// @needsAudit
/**
* Asks the user to grant permissions for location.
* @return A promise that fulfills with an object of type [LocationPermissionResponse](#locationpermissionresponse).
* @deprecated Use [`requestForegroundPermissionsAsync`](#locationrequestforegroundpermissionsasync) or [`requestBackgroundPermissionsAsync`](#locationrequestbackgroundpermissionsasync) instead.
*/
export async function requestPermissionsAsync() {
console.warn(`"requestPermissionsAsync()" is now deprecated. Please use "requestForegroundPermissionsAsync()" or "requestBackgroundPermissionsAsync()" instead.`);
return await ExpoLocation.requestPermissionsAsync();
}
// @needsAudit
/**
* Checks user's permissions for accessing location while the app is in the foreground.
* @return A promise that fulfills with an object of type [PermissionResponse](#permissionresponse).
*/
export async function getForegroundPermissionsAsync() {
return await ExpoLocation.getForegroundPermissionsAsync();
}
// @needsAudit
/**
* Asks the user to grant permissions for location while the app is in the foreground.
* @return A promise that fulfills with an object of type [PermissionResponse](#permissionresponse).
*/
export async function requestForegroundPermissionsAsync() {
return await ExpoLocation.requestForegroundPermissionsAsync();
}
// @needsAudit
/**
* Check or request permissions for the foreground location.
* This uses both `requestForegroundPermissionsAsync` and `getForegroundPermissionsAsync` to interact with the permissions.
*
* @example
* ```ts
* const [status, requestPermission] = Location.useForegroundPermissions();
* ```
*/
export const useForegroundPermissions = createPermissionHook({
getMethod: getForegroundPermissionsAsync,
requestMethod: requestForegroundPermissionsAsync,
});
// @needsAudit
/**
* Checks user's permissions for accessing location while the app is in the background.
* @return A promise that fulfills with an object of type [PermissionResponse](#permissionresponse).
*/
export async function getBackgroundPermissionsAsync() {
return await ExpoLocation.getBackgroundPermissionsAsync();
}
// @needsAudit
/**
* Asks the user to grant permissions for location while the app is in the background.
* On __Android 11 or higher__: this method will open the system settings page - before that happens
* you should explain to the user why your application needs background location permission.
* For example, you can use `Modal` component from `react-native` to do that.
* > __Note__: Foreground permissions should be granted before asking for the background permissions
* (your app can't obtain background permission without foreground permission).
* @return A promise that fulfills with an object of type [PermissionResponse](#permissionresponse).
*/
export async function requestBackgroundPermissionsAsync() {
return await ExpoLocation.requestBackgroundPermissionsAsync();
}
// @needsAudit
/**
* Check or request permissions for the background location.
* This uses both `requestBackgroundPermissionsAsync` and `getBackgroundPermissionsAsync` to
* interact with the permissions.
*
* @example
* ```ts
* const [status, requestPermission] = Location.useBackgroundPermissions();
* ```
*/
export const useBackgroundPermissions = createPermissionHook({
getMethod: getBackgroundPermissionsAsync,
requestMethod: requestBackgroundPermissionsAsync,
});
// --- Location service
// @needsAudit
/**
* Checks whether location services are enabled by the user.
* @return A promise which fulfills to `true` if location services are enabled on the device,
* or `false` if not.
*/
export async function hasServicesEnabledAsync() {
return await ExpoLocation.hasServicesEnabledAsync();
}
// --- Background location updates
function _validateTaskName(taskName) {
if (!taskName || typeof taskName !== 'string') {
throw new Error(`\`taskName\` must be a non-empty string. Got ${taskName} instead.`);
}
}
// @docsMissing
export async function isBackgroundLocationAvailableAsync() {
const providerStatus = await getProviderStatusAsync();
return providerStatus.backgroundModeEnabled;
}
// @needsAudit
/**
* Registers for receiving location updates that can also come when the app is in the background.
*
* # Task parameters
*
* Background location task will be receiving following data:
* - `locations` - An array of the new locations.
*
* ```ts
* import * as TaskManager from 'expo-task-manager';
*
* TaskManager.defineTask(YOUR_TASK_NAME, ({ data: { locations }, error }) => {
* if (error) {
* // check `error.message` for more details.
* return;
* }
* console.log('Received new locations', locations);
* });
* ```
*
* @param taskName Name of the task receiving location updates.
* @param options An object of options passed to the location manager.
*
* @return A promise resolving once the task with location updates is registered.
*/
export async function startLocationUpdatesAsync(taskName, options = { accuracy: LocationAccuracy.Balanced }) {
_validateTaskName(taskName);
await ExpoLocation.startLocationUpdatesAsync(taskName, options);
}
// @needsAudit
/**
* Stops geofencing for specified task.
* @param taskName Name of the background location task to stop.
* @return A promise resolving as soon as the task is unregistered.
*/
export async function stopLocationUpdatesAsync(taskName) {
_validateTaskName(taskName);
await ExpoLocation.stopLocationUpdatesAsync(taskName);
}
// @needsAudit
/**
* @param taskName Name of the location task to check.
* @return A promise which fulfills with boolean value indicating whether the location task is
* started or not.
*/
export async function hasStartedLocationUpdatesAsync(taskName) {
_validateTaskName(taskName);
return ExpoLocation.hasStartedLocationUpdatesAsync(taskName);
}
// --- Geofencing
function _validateRegions(regions) {
if (!regions || regions.length === 0) {
throw new Error('Regions array cannot be empty. Use `stopGeofencingAsync` if you want to stop geofencing all regions');
}
for (const region of regions) {
if (typeof region.latitude !== 'number') {
throw new TypeError(`Region's latitude must be a number. Got '${region.latitude}' instead.`);
}
if (typeof region.longitude !== 'number') {
throw new TypeError(`Region's longitude must be a number. Got '${region.longitude}' instead.`);
}
if (typeof region.radius !== 'number') {
throw new TypeError(`Region's radius must be a number. Got '${region.radius}' instead.`);
}
}
}
// @needsAudit
/**
* Starts geofencing for given regions. When the new event comes, the task with specified name will
* be called with the region that the device enter to or exit from.
* If you want to add or remove regions from already running geofencing task, you can just call
* `startGeofencingAsync` again with the new array of regions.
*
* # Task parameters
*
* Geofencing task will be receiving following data:
* - `eventType` - Indicates the reason for calling the task, which can be triggered by entering or exiting the region.
* See [GeofencingEventType](#geofencingeventtype).
* - `region` - Object containing details about updated region. See [LocationRegion](#locationregion) for more details.
*
* @param taskName Name of the task that will be called when the device enters or exits from specified regions.
* @param regions Array of region objects to be geofenced.
*
* @return A promise resolving as soon as the task is registered.
*
* @example
* ```ts
* import { GeofencingEventType } from 'expo-location';
* import * as TaskManager from 'expo-task-manager';
*
* TaskManager.defineTask(YOUR_TASK_NAME, ({ data: { eventType, region }, error }) => {
* if (error) {
* // check `error.message` for more details.
* return;
* }
* if (eventType === GeofencingEventType.Enter) {
* console.log("You've entered region:", region);
* } else if (eventType === GeofencingEventType.Exit) {
* console.log("You've left region:", region);
* }
* });
* ```
*/
export async function startGeofencingAsync(taskName, regions = []) {
_validateTaskName(taskName);
_validateRegions(regions);
await ExpoLocation.startGeofencingAsync(taskName, { regions });
}
// @needsAudit
/**
* Stops geofencing for specified task. It unregisters the background task so the app will not be
* receiving any updates, especially in the background.
* @param taskName Name of the task to unregister.
* @return A promise resolving as soon as the task is unregistered.
*/
export async function stopGeofencingAsync(taskName) {
_validateTaskName(taskName);
await ExpoLocation.stopGeofencingAsync(taskName);
}
// @needsAudit
/**
* @param taskName Name of the geofencing task to check.
* @return A promise which fulfills with boolean value indicating whether the geofencing task is
* started or not.
*/
export async function hasStartedGeofencingAsync(taskName) {
_validateTaskName(taskName);
return ExpoLocation.hasStartedGeofencingAsync(taskName);
}
export { LocationEventEmitter as EventEmitter, _getCurrentWatchId };
export { LocationAccuracy as Accuracy, LocationActivityType as ActivityType, LocationGeofencingEventType as GeofencingEventType, LocationGeofencingRegionState as GeofencingRegionState, PermissionStatus, setGoogleApiKey, };
export { installWebGeolocationPolyfill } from './GeolocationPolyfill';
export * from './Location.types';
//# sourceMappingURL=Location.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,463 @@
import { PermissionResponse } from 'expo-modules-core';
/**
* Enum with available location accuracies.
*/
export declare enum LocationAccuracy {
/**
* Accurate to the nearest three kilometers.
*/
Lowest = 1,
/**
* Accurate to the nearest kilometer.
*/
Low = 2,
/**
* Accurate to within one hundred meters.
*/
Balanced = 3,
/**
* Accurate to within ten meters of the desired target.
*/
High = 4,
/**
* The best level of accuracy available.
*/
Highest = 5,
/**
* The highest possible accuracy that uses additional sensor data to facilitate navigation apps.
*/
BestForNavigation = 6
}
/**
* Enum with available activity types of background location tracking.
*/
export declare enum LocationActivityType {
/**
* Default activity type. Use it if there is no other type that matches the activity you track.
*/
Other = 1,
/**
* Location updates are being used specifically during vehicular navigation to track location
* changes to the automobile.
*/
AutomotiveNavigation = 2,
/**
* Use this activity type if you track fitness activities such as walking, running, cycling,
* and so on.
*/
Fitness = 3,
/**
* Activity type for movements for other types of vehicular navigation that are not automobile
* related.
*/
OtherNavigation = 4,
/**
* Intended for airborne activities. Fall backs to `ActivityType.Other` if
* unsupported.
* @platform ios 12+
*/
Airborne = 5
}
/**
* A type of the event that geofencing task can receive.
*/
export declare enum LocationGeofencingEventType {
/**
* Emitted when the device entered observed region.
*/
Enter = 1,
/**
* Occurs as soon as the device left observed region
*/
Exit = 2
}
/**
* State of the geofencing region that you receive through the geofencing task.
*/
export declare enum LocationGeofencingRegionState {
/**
* Indicates that the device position related to the region is unknown.
*/
Unknown = 0,
/**
* Indicates that the device is inside the region.
*/
Inside = 1,
/**
* Inverse of inside state.
*/
Outside = 2
}
/**
* Type representing options argument in `getCurrentPositionAsync`.
*/
export type LocationOptions = {
/**
* Location manager accuracy. Pass one of `Accuracy` enum values.
* For low-accuracies the implementation can avoid geolocation providers
* that consume a significant amount of power (such as GPS).
*/
accuracy?: LocationAccuracy;
/**
* Specifies whether to ask the user to turn on improved accuracy location mode
* which uses Wi-Fi, cell networks and GPS sensor.
* @default true
* @platform android
*/
mayShowUserSettingsDialog?: boolean;
/**
* Minimum time to wait between each update in milliseconds.
* Default value may depend on `accuracy` option.
* @platform android
*/
timeInterval?: number;
/**
* Receive updates only when the location has changed by at least this distance in meters.
* Default value may depend on `accuracy` option.
*/
distanceInterval?: number;
};
/**
* Type representing options object that can be passed to `getLastKnownPositionAsync`.
*/
export type LocationLastKnownOptions = {
/**
* A number of milliseconds after which the last known location starts to be invalid and thus
* `null` is returned.
*/
maxAge?: number;
/**
* The maximum radius of uncertainty for the location, measured in meters. If the last known
* location's accuracy radius is bigger (less accurate) then `null` is returned.
*/
requiredAccuracy?: number;
};
/**
* Type representing background location task options.
*/
export type LocationTaskOptions = LocationOptions & {
/**
* A boolean indicating whether the status bar changes its appearance when
* location services are used in the background.
* @default false
* @platform ios 11+
*/
showsBackgroundLocationIndicator?: boolean;
/**
* The distance in meters that must occur between last reported location and the current location
* before deferred locations are reported.
* @default 0
*/
deferredUpdatesDistance?: number;
deferredUpdatesTimeout?: number;
/**
* Minimum time interval in milliseconds that must pass since last reported location before all
* later locations are reported in a batched update
* @default 0
*/
deferredUpdatesInterval?: number;
/**
* The type of user activity associated with the location updates.
* @see See [Apple docs](https://developer.apple.com/documentation/corelocation/cllocationmanager/1620567-activitytype) for more details.
* @default ActivityType.Other
* @platform ios
*/
activityType?: LocationActivityType;
/**
* A boolean value indicating whether the location manager can pause location
* updates to improve battery life without sacrificing location data. When this option is set to
* `true`, the location manager pauses updates (and powers down the appropriate hardware) at times
* when the location data is unlikely to change. You can help the determination of when to pause
* location updates by assigning a value to the `activityType` property.
* @default false
* @platform ios
*/
pausesUpdatesAutomatically?: boolean;
foregroundService?: LocationTaskServiceOptions;
};
export type LocationTaskServiceOptions = {
/**
* Title of the foreground service notification.
*/
notificationTitle: string;
/**
* Subtitle of the foreground service notification.
*/
notificationBody: string;
/**
* Color of the foreground service notification. Accepts `#RRGGBB` and `#AARRGGBB` hex formats.
*/
notificationColor?: string;
/**
* Boolean value whether to destroy the foreground service if the app is killed.
*/
killServiceOnDestroy?: boolean;
};
/**
* Type representing geofencing region object.
*/
export type LocationRegion = {
/**
* The identifier of the region object. Defaults to auto-generated UUID hash.
*/
identifier?: string;
/**
* The latitude in degrees of region's center point.
*/
latitude: number;
/**
* The longitude in degrees of region's center point.
*/
longitude: number;
/**
* The radius measured in meters that defines the region's outer boundary.
*/
radius: number;
/**
* Boolean value whether to call the task if the device enters the region.
* @default true
*/
notifyOnEnter?: boolean;
/**
* Boolean value whether to call the task if the device exits the region.
* @default true
*/
notifyOnExit?: boolean;
/**
* One of [GeofencingRegionState](#geofencingregionstate) region state. Determines whether the
* device is inside or outside a region.
*/
state?: LocationGeofencingRegionState;
};
/**
* Type representing the location object.
*/
export type LocationObject = {
/**
* The coordinates of the position.
*/
coords: LocationObjectCoords;
/**
* The time at which this position information was obtained, in milliseconds since epoch.
*/
timestamp: number;
/**
* Whether the location coordinates is mocked or not.
* @platform android
*/
mocked?: boolean;
};
/**
* Type representing the location GPS related data.
*/
export type LocationObjectCoords = {
/**
* The latitude in degrees.
*/
latitude: number;
/**
* The longitude in degrees.
*/
longitude: number;
/**
* The altitude in meters above the WGS 84 reference ellipsoid. Can be `null` on Web if it's not available.
*/
altitude: number | null;
/**
* The radius of uncertainty for the location, measured in meters. Can be `null` on Web if it's not available.
*/
accuracy: number | null;
/**
* The accuracy of the altitude value, in meters. Can be `null` on Web if it's not available.
*/
altitudeAccuracy: number | null;
/**
* Horizontal direction of travel of this device, measured in degrees starting at due north and
* continuing clockwise around the compass. Thus, north is 0 degrees, east is 90 degrees, south is
* 180 degrees, and so on. Can be `null` on Web if it's not available.
*/
heading: number | null;
/**
* The instantaneous speed of the device in meters per second. Can be `null` on Web if it's not available.
*/
speed: number | null;
};
/**
* Represents `watchPositionAsync` callback.
*/
export type LocationCallback = (location: LocationObject) => any;
/**
* Represents the object containing details about location provider.
*/
export type LocationProviderStatus = {
/**
* Whether location services are enabled. See [Location.hasServicesEnabledAsync](#locationhasservicesenabledasync)
* for a more convenient solution to get this value.
*/
locationServicesEnabled: boolean;
backgroundModeEnabled: boolean;
/**
* Whether the GPS provider is available. If `true` the location data will come
* from GPS, especially for requests with high accuracy.
* @platform android
*/
gpsAvailable?: boolean;
/**
* Whether the network provider is available. If `true` the location data will
* come from cellular network, especially for requests with low accuracy.
* @platform android
*/
networkAvailable?: boolean;
/**
* Whether the passive provider is available. If `true` the location data will
* be determined passively.
* @platform android
*/
passiveAvailable?: boolean;
};
/**
* Type of the object containing heading details and provided by `watchHeadingAsync` callback.
*/
export type LocationHeadingObject = {
/**
* Measure of true north in degrees (needs location permissions, will return `-1` if not given).
*/
trueHeading: number;
/**
* Measure of magnetic north in degrees.
*/
magHeading: number;
/**
* Level of calibration of compass.
* - `3`: high accuracy, `2`: medium accuracy, `1`: low accuracy, `0`: none
* Reference for iOS:
* - `3`: < 20 degrees uncertainty, `2`: < 35 degrees, `1`: < 50 degrees, `0`: > 50 degrees
*/
accuracy: number;
};
/**
* Represents `watchHeadingAsync` callback.
*/
export type LocationHeadingCallback = (location: LocationHeadingObject) => any;
/**
* An object of options for forward and reverse geocoding.
*/
export type LocationGeocodingOptions = {
/**
* Whether to force using Google Maps API instead of the native implementation.
* Used by default only on Web platform. Requires providing an API key by `setGoogleApiKey`.
*/
useGoogleMaps?: boolean;
};
/**
* Type representing a result of `geocodeAsync`.
*/
export type LocationGeocodedLocation = {
/**
* The latitude in degrees.
*/
latitude: number;
/**
* The longitude in degrees.
*/
longitude: number;
/**
* The altitude in meters above the WGS 84 reference ellipsoid.
*/
altitude?: number;
/**
* The radius of uncertainty for the location, measured in meters.
*/
accuracy?: number;
};
/**
* Type representing a result of `reverseGeocodeAsync`.
*/
export type LocationGeocodedAddress = {
/**
* City name of the address.
*/
city: string | null;
/**
* Additional city-level information like district name.
*/
district: string | null;
/**
* Street number of the address.
*/
streetNumber: string | null;
/**
* Street name of the address.
*/
street: string | null;
/**
* The state or province associated with the address.
*/
region: string | null;
/**
* Additional information about administrative area.
*/
subregion: string | null;
/**
* Localized country name of the address.
*/
country: string | null;
/**
* Postal code of the address.
*/
postalCode: string | null;
/**
* The name of the placemark, for example, "Tower Bridge".
*/
name: string | null;
/**
* Localized (ISO) country code of the address, if available.
*/
isoCountryCode: string | null;
/**
* The timezone identifier associated with the address.
* @platform ios
*/
timezone: string | null;
/**
* Composed string of the address components, for example, "111 8th Avenue, New York, NY".
* @platform android
*/
formattedAddress: string | null;
};
/**
* Represents subscription object returned by methods watching for new locations or headings.
*/
export type LocationSubscription = {
/**
* Call this function with no arguments to remove this subscription. The callback will no longer
* be called for location updates.
*/
remove: () => void;
};
export type PermissionDetailsLocationIOS = {
/**
* The scope of granted permission. Indicates when it's possible to use location.
*/
scope: 'whenInUse' | 'always' | 'none';
};
export type PermissionDetailsLocationAndroid = {
/**
* @deprecated Use `accuracy` field instead.
*/
scope: 'fine' | 'coarse' | 'none';
/**
* Indicates the type of location provider.
*/
accuracy: 'fine' | 'coarse' | 'none';
};
/**
* `LocationPermissionResponse` extends [PermissionResponse](#permissionresponse)
* type exported by `expo-modules-core` and contains additional platform-specific fields.
*/
export type LocationPermissionResponse = PermissionResponse & {
ios?: PermissionDetailsLocationIOS;
android?: PermissionDetailsLocationAndroid;
};
export type { PermissionResponse };
//# sourceMappingURL=Location.types.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Location.types.d.ts","sourceRoot":"","sources":["../src/Location.types.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,98 @@
// @needsAudit
/**
* Enum with available location accuracies.
*/
export var LocationAccuracy;
(function (LocationAccuracy) {
/**
* Accurate to the nearest three kilometers.
*/
LocationAccuracy[LocationAccuracy["Lowest"] = 1] = "Lowest";
/**
* Accurate to the nearest kilometer.
*/
LocationAccuracy[LocationAccuracy["Low"] = 2] = "Low";
/**
* Accurate to within one hundred meters.
*/
LocationAccuracy[LocationAccuracy["Balanced"] = 3] = "Balanced";
/**
* Accurate to within ten meters of the desired target.
*/
LocationAccuracy[LocationAccuracy["High"] = 4] = "High";
/**
* The best level of accuracy available.
*/
LocationAccuracy[LocationAccuracy["Highest"] = 5] = "Highest";
/**
* The highest possible accuracy that uses additional sensor data to facilitate navigation apps.
*/
LocationAccuracy[LocationAccuracy["BestForNavigation"] = 6] = "BestForNavigation";
})(LocationAccuracy || (LocationAccuracy = {}));
// @needsAudit
/**
* Enum with available activity types of background location tracking.
*/
export var LocationActivityType;
(function (LocationActivityType) {
/**
* Default activity type. Use it if there is no other type that matches the activity you track.
*/
LocationActivityType[LocationActivityType["Other"] = 1] = "Other";
/**
* Location updates are being used specifically during vehicular navigation to track location
* changes to the automobile.
*/
LocationActivityType[LocationActivityType["AutomotiveNavigation"] = 2] = "AutomotiveNavigation";
/**
* Use this activity type if you track fitness activities such as walking, running, cycling,
* and so on.
*/
LocationActivityType[LocationActivityType["Fitness"] = 3] = "Fitness";
/**
* Activity type for movements for other types of vehicular navigation that are not automobile
* related.
*/
LocationActivityType[LocationActivityType["OtherNavigation"] = 4] = "OtherNavigation";
/**
* Intended for airborne activities. Fall backs to `ActivityType.Other` if
* unsupported.
* @platform ios 12+
*/
LocationActivityType[LocationActivityType["Airborne"] = 5] = "Airborne";
})(LocationActivityType || (LocationActivityType = {}));
// @needsAudit
/**
* A type of the event that geofencing task can receive.
*/
export var LocationGeofencingEventType;
(function (LocationGeofencingEventType) {
/**
* Emitted when the device entered observed region.
*/
LocationGeofencingEventType[LocationGeofencingEventType["Enter"] = 1] = "Enter";
/**
* Occurs as soon as the device left observed region
*/
LocationGeofencingEventType[LocationGeofencingEventType["Exit"] = 2] = "Exit";
})(LocationGeofencingEventType || (LocationGeofencingEventType = {}));
// @needsAudit
/**
* State of the geofencing region that you receive through the geofencing task.
*/
export var LocationGeofencingRegionState;
(function (LocationGeofencingRegionState) {
/**
* Indicates that the device position related to the region is unknown.
*/
LocationGeofencingRegionState[LocationGeofencingRegionState["Unknown"] = 0] = "Unknown";
/**
* Indicates that the device is inside the region.
*/
LocationGeofencingRegionState[LocationGeofencingRegionState["Inside"] = 1] = "Inside";
/**
* Inverse of inside state.
*/
LocationGeofencingRegionState[LocationGeofencingRegionState["Outside"] = 2] = "Outside";
})(LocationGeofencingRegionState || (LocationGeofencingRegionState = {}));
//# sourceMappingURL=Location.types.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
import { EventEmitter } from 'expo-modules-core';
export declare const LocationEventEmitter: EventEmitter;
//# sourceMappingURL=LocationEventEmitter.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"LocationEventEmitter.d.ts","sourceRoot":"","sources":["../src/LocationEventEmitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjD,eAAO,MAAM,oBAAoB,cAAiC,CAAC"}

View File

@@ -0,0 +1,4 @@
import { EventEmitter } from 'expo-modules-core';
import ExpoLocation from './ExpoLocation';
export const LocationEventEmitter = new EventEmitter(ExpoLocation);
//# sourceMappingURL=LocationEventEmitter.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"LocationEventEmitter.js","sourceRoot":"","sources":["../src/LocationEventEmitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAE1C,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,YAAY,CAAC,YAAY,CAAC,CAAC","sourcesContent":["import { EventEmitter } from 'expo-modules-core';\n\nimport ExpoLocation from './ExpoLocation';\n\nexport const LocationEventEmitter = new EventEmitter(ExpoLocation);\n"]}

View File

@@ -0,0 +1,3 @@
import { EventEmitter } from 'expo-modules-core';
export declare const LocationEventEmitter: EventEmitter;
//# sourceMappingURL=LocationEventEmitter.web.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"LocationEventEmitter.web.d.ts","sourceRoot":"","sources":["../src/LocationEventEmitter.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,eAAO,MAAM,oBAAoB,cAA8B,CAAC"}

View File

@@ -0,0 +1,3 @@
import { EventEmitter } from 'expo-modules-core';
export const LocationEventEmitter = new EventEmitter({});
//# sourceMappingURL=LocationEventEmitter.web.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"LocationEventEmitter.web.js","sourceRoot":"","sources":["../src/LocationEventEmitter.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,YAAY,CAAC,EAAS,CAAC,CAAC","sourcesContent":["import { EventEmitter } from 'expo-modules-core';\n\nexport const LocationEventEmitter = new EventEmitter({} as any);\n"]}

View File

@@ -0,0 +1,30 @@
import { LocationCallback, LocationHeadingCallback } from './Location.types';
type EventObject = {
watchId: number;
[key: string]: any;
};
declare class Subscriber<CallbackType extends LocationCallback | LocationHeadingCallback> {
private eventName;
private eventDataField;
private callbacks;
private eventSubscription;
constructor(eventName: string, eventDataField: string);
maybeInitializeSubscription(): void;
/**
* Registers given callback under new id which is then returned.
*/
registerCallback(callback: CallbackType): number;
/**
* Unregisters a callback with given id and revokes the subscription if possible.
*/
unregisterCallback(id: number): void;
trigger(event: EventObject): void;
}
export declare const LocationSubscriber: Subscriber<LocationCallback>;
export declare const HeadingSubscriber: Subscriber<LocationHeadingCallback>;
/**
* @private Necessary for some unit tests.
*/
export declare function _getCurrentWatchId(): number;
export {};
//# sourceMappingURL=LocationSubscribers.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"LocationSubscribers.d.ts","sourceRoot":"","sources":["../src/LocationSubscribers.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAG7E,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB,CAAC;AAIF,cAAM,UAAU,CAAC,YAAY,SAAS,gBAAgB,GAAG,uBAAuB;IAC9E,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,iBAAiB,CAA6B;gBAE1C,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;IAKrD,2BAA2B;IAU3B;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM;IAOhD;;OAEG;IACH,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAepC,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;CAUlC;AAED,eAAO,MAAM,kBAAkB,8BAG9B,CAAC;AACF,eAAO,MAAM,iBAAiB,qCAG7B,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}

View File

@@ -0,0 +1,62 @@
import ExpoLocation from './ExpoLocation';
import { LocationEventEmitter } from './LocationEventEmitter';
let nextWatchId = 0;
class Subscriber {
eventName;
eventDataField;
callbacks = {};
eventSubscription = null;
constructor(eventName, eventDataField) {
this.eventName = eventName;
this.eventDataField = eventDataField;
}
maybeInitializeSubscription() {
if (this.eventSubscription) {
return;
}
this.eventSubscription = LocationEventEmitter.addListener(this.eventName, (event) => this.trigger(event));
}
/**
* Registers given callback under new id which is then returned.
*/
registerCallback(callback) {
this.maybeInitializeSubscription();
const id = ++nextWatchId;
this.callbacks[id] = callback;
return id;
}
/**
* Unregisters a callback with given id and revokes the subscription if possible.
*/
unregisterCallback(id) {
// Do nothing if we have already unregistered the callback.
if (!this.callbacks[id]) {
return;
}
delete this.callbacks[id];
ExpoLocation.removeWatchAsync(id);
if (Object.keys(this.callbacks).length === 0 && this.eventSubscription) {
LocationEventEmitter.removeSubscription(this.eventSubscription);
this.eventSubscription = null;
}
}
trigger(event) {
const watchId = event.watchId;
const callback = this.callbacks[watchId];
if (callback) {
callback(event[this.eventDataField]);
}
else {
ExpoLocation.removeWatchAsync(watchId);
}
}
}
export const LocationSubscriber = new Subscriber('Expo.locationChanged', 'location');
export const HeadingSubscriber = new Subscriber('Expo.headingChanged', 'heading');
/**
* @private Necessary for some unit tests.
*/
export function _getCurrentWatchId() {
return nextWatchId;
}
//# sourceMappingURL=LocationSubscribers.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"LocationSubscribers.js","sourceRoot":"","sources":["../src/LocationSubscribers.ts"],"names":[],"mappings":"AAEA,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAO9D,IAAI,WAAW,GAAG,CAAC,CAAC;AAEpB,MAAM,UAAU;IACN,SAAS,CAAS;IAClB,cAAc,CAAS;IACvB,SAAS,GAAmC,EAAE,CAAC;IAC/C,iBAAiB,GAAwB,IAAI,CAAC;IAEtD,YAAY,SAAiB,EAAE,cAAsB;QACnD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAED,2BAA2B;QACzB,IAAI,IAAI,CAAC,iBAAiB,EAAE;YAC1B,OAAO;SACR;QACD,IAAI,CAAC,iBAAiB,GAAG,oBAAoB,CAAC,WAAW,CACvD,IAAI,CAAC,SAAS,EACd,CAAC,KAAkB,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAC5C,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,QAAsB;QACrC,IAAI,CAAC,2BAA2B,EAAE,CAAC;QACnC,MAAM,EAAE,GAAG,EAAE,WAAW,CAAC;QACzB,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC;QAC9B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,EAAU;QAC3B,2DAA2D;QAC3D,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE;YACvB,OAAO;SACR;QAED,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC1B,YAAY,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAElC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,iBAAiB,EAAE;YACtE,oBAAoB,CAAC,kBAAkB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAChE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;SAC/B;IACH,CAAC;IAED,OAAO,CAAC,KAAkB;QACxB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAEzC,IAAI,QAAQ,EAAE;YACZ,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;SACtC;aAAM;YACL,YAAY,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;SACxC;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,UAAU,CAC9C,sBAAsB,EACtB,UAAU,CACX,CAAC;AACF,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,UAAU,CAC7C,qBAAqB,EACrB,SAAS,CACV,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["import { Subscription } from 'expo-modules-core';\n\nimport ExpoLocation from './ExpoLocation';\nimport { LocationCallback, LocationHeadingCallback } from './Location.types';\nimport { LocationEventEmitter } from './LocationEventEmitter';\n\ntype EventObject = {\n watchId: number;\n [key: string]: any;\n};\n\nlet nextWatchId = 0;\n\nclass Subscriber<CallbackType extends LocationCallback | LocationHeadingCallback> {\n private eventName: string;\n private eventDataField: string;\n private callbacks: { [id: string]: CallbackType } = {};\n private eventSubscription: Subscription | null = null;\n\n constructor(eventName: string, eventDataField: string) {\n this.eventName = eventName;\n this.eventDataField = eventDataField;\n }\n\n maybeInitializeSubscription() {\n if (this.eventSubscription) {\n return;\n }\n this.eventSubscription = LocationEventEmitter.addListener(\n this.eventName,\n (event: EventObject) => this.trigger(event)\n );\n }\n\n /**\n * Registers given callback under new id which is then returned.\n */\n registerCallback(callback: CallbackType): number {\n this.maybeInitializeSubscription();\n const id = ++nextWatchId;\n this.callbacks[id] = callback;\n return id;\n }\n\n /**\n * Unregisters a callback with given id and revokes the subscription if possible.\n */\n unregisterCallback(id: number): void {\n // Do nothing if we have already unregistered the callback.\n if (!this.callbacks[id]) {\n return;\n }\n\n delete this.callbacks[id];\n ExpoLocation.removeWatchAsync(id);\n\n if (Object.keys(this.callbacks).length === 0 && this.eventSubscription) {\n LocationEventEmitter.removeSubscription(this.eventSubscription);\n this.eventSubscription = null;\n }\n }\n\n trigger(event: EventObject): void {\n const watchId = event.watchId;\n const callback = this.callbacks[watchId];\n\n if (callback) {\n callback(event[this.eventDataField]);\n } else {\n ExpoLocation.removeWatchAsync(watchId);\n }\n }\n}\n\nexport const LocationSubscriber = new Subscriber<LocationCallback>(\n 'Expo.locationChanged',\n 'location'\n);\nexport const HeadingSubscriber = new Subscriber<LocationHeadingCallback>(\n 'Expo.headingChanged',\n 'heading'\n);\n\n/**\n * @private Necessary for some unit tests.\n */\nexport function _getCurrentWatchId(): number {\n return nextWatchId;\n}\n"]}