forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {
2 createContext,
3 type ReactNode,
4 useContext,
5 useEffect,
6 useMemo,
7} from 'react'
8
9import {useSyncDeviceGeolocationOnStartup} from '#/geolocation/device'
10import {useGeolocationServiceResponse} from '#/geolocation/service'
11import {type Geolocation} from '#/geolocation/types'
12import {mergeGeolocations} from '#/geolocation/util'
13import {device, useStorage} from '#/storage'
14
15export {useRequestDeviceGeolocation} from '#/geolocation/device'
16export {resolve} from '#/geolocation/service'
17export * from '#/geolocation/types'
18
19const GeolocationContext = createContext<Geolocation>({
20 countryCode: undefined,
21 regionCode: undefined,
22})
23
24const DeviceGeolocationAPIContext = createContext<{
25 setDeviceGeolocation(deviceGeolocation: Geolocation): void
26}>({
27 setDeviceGeolocation: () => {},
28})
29
30export function useGeolocation() {
31 return useContext(GeolocationContext)
32}
33
34export function useDeviceGeolocationApi() {
35 return useContext(DeviceGeolocationAPIContext)
36}
37
38export function Provider({children}: {children: ReactNode}) {
39 const geolocationService = useGeolocationServiceResponse()
40 const [deviceGeolocation, setDeviceGeolocation] = useStorage(device, [
41 'deviceGeolocation',
42 ])
43 const geolocation = useMemo(() => {
44 return mergeGeolocations(deviceGeolocation, geolocationService)
45 }, [deviceGeolocation, geolocationService])
46
47 useEffect(() => {
48 /**
49 * Save this for out-of-band-reads during future cold starts of the app.
50 * Needs to be available for the data prefetching we do on boot.
51 */
52 device.set(['mergedGeolocation'], geolocation)
53 }, [geolocation])
54
55 useSyncDeviceGeolocationOnStartup(setDeviceGeolocation)
56
57 return (
58 <GeolocationContext.Provider value={geolocation}>
59 <DeviceGeolocationAPIContext.Provider
60 value={useMemo(() => ({setDeviceGeolocation}), [setDeviceGeolocation])}>
61 {children}
62 </DeviceGeolocationAPIContext.Provider>
63 </GeolocationContext.Provider>
64 )
65}