mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import {useEffect, useRef} from 'react'
2import * as Location from 'expo-location'
3
4import {logger} from '#/state/geolocation/logger'
5import {getDeviceGeolocation} from '#/state/geolocation/util'
6import {device, useStorage} from '#/storage'
7
8/**
9 * Hook to get and sync the device geolocation from the device GPS and store it
10 * using device storage. If permissions are not granted, it will clear any cached
11 * storage value.
12 */
13export function useSyncedDeviceGeolocation() {
14 const synced = useRef(false)
15 const [status] = Location.useForegroundPermissions()
16 const [deviceGeolocation, setDeviceGeolocation] = useStorage(device, [
17 'deviceGeolocation',
18 ])
19
20 useEffect(() => {
21 async function get() {
22 // no need to set this more than once per session
23 if (synced.current) return
24
25 logger.debug('useSyncedDeviceGeolocation: checking perms')
26
27 if (status?.granted) {
28 const location = await getDeviceGeolocation()
29 if (location) {
30 logger.debug('useSyncedDeviceGeolocation: syncing location')
31 setDeviceGeolocation(location)
32 synced.current = true
33 }
34 } else {
35 const hasCachedValue = device.get(['deviceGeolocation']) !== undefined
36
37 /**
38 * If we have a cached value, but user has revoked permissions,
39 * quietly (will take effect lazily) clear this out.
40 */
41 if (hasCachedValue) {
42 logger.debug(
43 'useSyncedDeviceGeolocation: clearing cached location, perms revoked',
44 )
45 device.set(['deviceGeolocation'], undefined)
46 }
47 }
48 }
49
50 get().catch(e => {
51 logger.error('useSyncedDeviceGeolocation: failed to sync', {
52 safeMessage: e,
53 })
54 })
55 }, [status, setDeviceGeolocation])
56
57 return [deviceGeolocation, setDeviceGeolocation] as const
58}