From 5578b54427cb08400251857dae397cb3b604b856 Mon Sep 17 00:00:00 2001 From: Natan Cieplinski Date: Mon, 9 Aug 2021 16:47:40 +0200 Subject: [PATCH 1/2] Add getCurrentLocation and LocationProvider --- src/index.ts | 15 +++++++- src/location-provider/LocationProvider.tsx | 42 +++++++++++++++++++++ src/location-provider/getCurrentLocation.ts | 21 +++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/location-provider/LocationProvider.tsx create mode 100644 src/location-provider/getCurrentLocation.ts diff --git a/src/index.ts b/src/index.ts index 1154a59..cfec293 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,18 @@ import { useInterval } from './useInterval/useInterval' import { AsyncState, getAsyncState } from './async-data/asyncState' import { AsyncView } from './async-data/AsyncView' +import { + LocationProvider, + LocationContext, + LocationContextValue, +} from './location-provider/LocationProvider' -export { useInterval, AsyncState, getAsyncState, AsyncView } +export { + useInterval, + AsyncState, + getAsyncState, + AsyncView, + LocationProvider, + LocationContext, + LocationContextValue, +} diff --git a/src/location-provider/LocationProvider.tsx b/src/location-provider/LocationProvider.tsx new file mode 100644 index 0000000..cd8005d --- /dev/null +++ b/src/location-provider/LocationProvider.tsx @@ -0,0 +1,42 @@ +import React, { useEffect, useState } from 'react' +import { createContext } from 'react' +import { useInterval } from '../index' +import { getCurrentLocation } from './getCurrentLocation' + +export type LocationContextValue = { + location: Position | null +} + +export const LocationContext = createContext({ + location: null, +}) + +export const LocationProvider: React.FC<{ + highAccuracy: boolean + delay: number +}> = ({ highAccuracy, delay, children }) => { + const [location, setLocation] = useState({ + location: null, + }) + + const updateLocation = async () => { + const position = await getCurrentLocation(highAccuracy).catch( + () => location.location + ) + setLocation({ location: position }) + } + + useEffect(() => { + updateLocation() + }, []) + + useInterval(() => { + updateLocation() + }, delay) + + return ( + + {children} + + ) +} diff --git a/src/location-provider/getCurrentLocation.ts b/src/location-provider/getCurrentLocation.ts new file mode 100644 index 0000000..8e2933e --- /dev/null +++ b/src/location-provider/getCurrentLocation.ts @@ -0,0 +1,21 @@ +const getCurrentLocation = (highAccuracy = false): Promise => { + return new Promise((resolve, reject) => { + const successCallback = (position: Position): void => { + resolve(position) + } + + const errorCallback = (error: PositionError) => { + reject(error.message) + } + + if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition(successCallback, errorCallback, { + enableHighAccuracy: highAccuracy, + }) + } else { + reject('Geolocation not supported') + } + }) +} + +export { getCurrentLocation } From 7a1f40627fc624a5e681e20c6f11ab2fe79ae9b3 Mon Sep 17 00:00:00 2001 From: Natan Cieplinski Date: Mon, 9 Aug 2021 16:49:52 +0200 Subject: [PATCH 2/2] Fix Position type --- src/location-provider/LocationProvider.tsx | 2 +- src/location-provider/getCurrentLocation.ts | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/location-provider/LocationProvider.tsx b/src/location-provider/LocationProvider.tsx index cd8005d..470611b 100644 --- a/src/location-provider/LocationProvider.tsx +++ b/src/location-provider/LocationProvider.tsx @@ -4,7 +4,7 @@ import { useInterval } from '../index' import { getCurrentLocation } from './getCurrentLocation' export type LocationContextValue = { - location: Position | null + location: GeolocationPosition | null } export const LocationContext = createContext({ diff --git a/src/location-provider/getCurrentLocation.ts b/src/location-provider/getCurrentLocation.ts index 8e2933e..615271b 100644 --- a/src/location-provider/getCurrentLocation.ts +++ b/src/location-provider/getCurrentLocation.ts @@ -1,10 +1,12 @@ -const getCurrentLocation = (highAccuracy = false): Promise => { - return new Promise((resolve, reject) => { - const successCallback = (position: Position): void => { +const getCurrentLocation = ( + highAccuracy = false +): Promise => { + return new Promise((resolve, reject) => { + const successCallback = (position: GeolocationPosition): void => { resolve(position) } - const errorCallback = (error: PositionError) => { + const errorCallback = (error: GeolocationPositionError) => { reject(error.message) }