Skip to content

Commit

Permalink
feat: Use last known location if GPS fails to sync (#752)
Browse files Browse the repository at this point in the history
* Save last known location

* save location on manual selection too

* use saved location if available

* yarn lint

* use fp-ts idiomatic code and handle saving inside a useEffect hook

* yarn lint

* use a const variable rather than string literal
  • Loading branch information
HaramanJohal committed Oct 10, 2020
1 parent 122e4f8 commit f0a1716
Showing 1 changed file with 45 additions and 1 deletion.
46 changes: 45 additions & 1 deletion App/stores/location.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ import { pipe } from 'fp-ts/lib/pipeable';
import * as T from 'fp-ts/lib/Task';
import * as TE from 'fp-ts/lib/TaskEither';
import React, { createContext, useContext, useEffect, useState } from 'react';
import { AsyncStorage } from 'react-native';

import { sideEffect } from '../util/fp';
import { promiseToTE, sideEffect } from '../util/fp';
import { noop } from '@shootismoke/ui';
import { sentryError } from '../util/sentry';
import { ErrorContext } from './error';
Expand All @@ -30,6 +31,8 @@ import {
Location,
} from './util/fetchGpsPosition';

const LAST_KNOWN_LOCATION_KEY = 'LAST_KNOWN_LOCATION'

const DEFAULT_LAT_LNG: LatLng = {
latitude: 0,
longitude: 0,
Expand Down Expand Up @@ -88,6 +91,40 @@ export function LocationContextProvider({
)
)
),
TE.orElse((err) =>
pipe(
promiseToTE(
() => AsyncStorage.getItem('LAST_KNOWN_LOCATION'),
'LocationContext'
),
TE.chain((locationString) => {
// Skip parsing if AsyncStorage is empty.
if (!locationString) {
return TE.left(
new Error(
'AsyncStorage does not contain LAST_KNOWN_LOCATION'
)
);
}

const parsedLocation = JSON.parse(
locationString
) as Location;

// Make sure parsedLocation is well-formed.
return parsedLocation.latitude &&
parsedLocation.longitude
? TE.right(parsedLocation)
: TE.left(
new Error(
'AsyncStorage has ill-formatted LAST_KNOWN_LOCATION'
)
);
}),
// Show the initial error from fetchGpsPosition.
TE.mapLeft(() => err)
)
),
TE.fold(
(err) => {
setError(err);
Expand All @@ -109,6 +146,13 @@ export function LocationContextProvider({
)().catch(sentryError('LocationContextProvider'));
}, []); // eslint-disable-line react-hooks/exhaustive-deps

useEffect(() => {
AsyncStorage.setItem(
LAST_KNOWN_LOCATION_KEY,
JSON.stringify(currentLocation)
).catch(sentryError('LocationContextProvider'));
}, [currentLocation]);

return (
<GpsLocationContext.Provider value={gpsLocation}>
<CurrentLocationContext.Provider
Expand Down

0 comments on commit f0a1716

Please sign in to comment.