122 lines
3.2 KiB
JavaScript
122 lines
3.2 KiB
JavaScript
import BackgroundGeolocation from "react-native-background-geolocation";
|
|
import { createLogger } from "~/lib/logger";
|
|
import { BACKGROUND_SCOPES } from "~/lib/logger/scopes";
|
|
|
|
import { BASE_GEOLOCATION_CONFIG } from "./backgroundGeolocationConfig";
|
|
|
|
const bgGeoLogger = createLogger({
|
|
module: BACKGROUND_SCOPES.GEOLOCATION,
|
|
feature: "bg-geo-service",
|
|
});
|
|
|
|
let readyPromise = null;
|
|
let lastReadyState = null;
|
|
|
|
let subscriptions = [];
|
|
let handlersSignature = null;
|
|
|
|
export async function ensureBackgroundGeolocationReady(
|
|
config = BASE_GEOLOCATION_CONFIG,
|
|
) {
|
|
if (readyPromise) return readyPromise;
|
|
|
|
readyPromise = (async () => {
|
|
bgGeoLogger.info("Calling BackgroundGeolocation.ready");
|
|
const state = await BackgroundGeolocation.ready(config);
|
|
lastReadyState = state;
|
|
bgGeoLogger.info("BackgroundGeolocation is ready", {
|
|
enabled: state?.enabled,
|
|
isMoving: state?.isMoving,
|
|
trackingMode: state?.trackingMode,
|
|
schedulerEnabled: state?.schedulerEnabled,
|
|
});
|
|
return state;
|
|
})().catch((error) => {
|
|
// Allow retry if ready fails.
|
|
readyPromise = null;
|
|
lastReadyState = null;
|
|
bgGeoLogger.error("BackgroundGeolocation.ready failed", {
|
|
error: error?.message,
|
|
stack: error?.stack,
|
|
code: error?.code,
|
|
});
|
|
throw error;
|
|
});
|
|
|
|
return readyPromise;
|
|
}
|
|
|
|
export function getLastReadyState() {
|
|
return lastReadyState;
|
|
}
|
|
|
|
export function setBackgroundGeolocationEventHandlers({
|
|
onLocation,
|
|
onLocationError,
|
|
onHttp,
|
|
onMotionChange,
|
|
onActivityChange,
|
|
onProviderChange,
|
|
onConnectivityChange,
|
|
onEnabledChange,
|
|
} = {}) {
|
|
// Avoid duplicate registration when `trackLocation()` is called multiple times.
|
|
// We use a simple signature so calling with identical functions is a no-op.
|
|
const sig = [
|
|
onLocation ? "L1" : "L0",
|
|
onHttp ? "H1" : "H0",
|
|
onMotionChange ? "M1" : "M0",
|
|
onActivityChange ? "A1" : "A0",
|
|
onProviderChange ? "P1" : "P0",
|
|
onConnectivityChange ? "C1" : "C0",
|
|
onEnabledChange ? "E1" : "E0",
|
|
].join("-");
|
|
if (handlersSignature === sig && subscriptions.length) {
|
|
return;
|
|
}
|
|
|
|
subscriptions.forEach((s) => s?.remove?.());
|
|
subscriptions = [];
|
|
|
|
if (onLocation) {
|
|
subscriptions.push(
|
|
BackgroundGeolocation.onLocation(onLocation, onLocationError),
|
|
);
|
|
}
|
|
if (onHttp) {
|
|
subscriptions.push(BackgroundGeolocation.onHttp(onHttp));
|
|
}
|
|
if (onMotionChange) {
|
|
subscriptions.push(BackgroundGeolocation.onMotionChange(onMotionChange));
|
|
}
|
|
if (onActivityChange) {
|
|
subscriptions.push(
|
|
BackgroundGeolocation.onActivityChange(onActivityChange),
|
|
);
|
|
}
|
|
if (onProviderChange) {
|
|
subscriptions.push(
|
|
BackgroundGeolocation.onProviderChange(onProviderChange),
|
|
);
|
|
}
|
|
if (onConnectivityChange) {
|
|
subscriptions.push(
|
|
BackgroundGeolocation.onConnectivityChange(onConnectivityChange),
|
|
);
|
|
}
|
|
if (onEnabledChange) {
|
|
subscriptions.push(BackgroundGeolocation.onEnabledChange(onEnabledChange));
|
|
}
|
|
|
|
handlersSignature = sig;
|
|
}
|
|
|
|
export async function stopBackgroundGeolocation() {
|
|
await ensureBackgroundGeolocationReady();
|
|
return BackgroundGeolocation.stop();
|
|
}
|
|
|
|
export async function startBackgroundGeolocation() {
|
|
await ensureBackgroundGeolocationReady();
|
|
return BackgroundGeolocation.start();
|
|
}
|