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 {
16 useIsDeviceGeolocationGranted,
17 useRequestDeviceGeolocation,
18} from '#/geolocation/device'
19export {resolve} from '#/geolocation/service'
20export * from '#/geolocation/types'
21
22const GeolocationContext = createContext<Geolocation>({
23 countryCode: undefined,
24 regionCode: undefined,
25})
26
27const DeviceGeolocationAPIContext = createContext<{
28 setDeviceGeolocation(deviceGeolocation: Geolocation): void
29}>({
30 setDeviceGeolocation: () => {},
31})
32
33export function useGeolocation() {
34 return useContext(GeolocationContext)
35}
36
37export function useDeviceGeolocationApi() {
38 return useContext(DeviceGeolocationAPIContext)
39}
40
41export function Provider({children}: {children: ReactNode}) {
42 const geolocationService = useGeolocationServiceResponse()
43 const [deviceGeolocation, setDeviceGeolocation] = useStorage(device, [
44 'deviceGeolocation',
45 ])
46 const geolocation = useMemo(() => {
47 return mergeGeolocations(deviceGeolocation, geolocationService)
48 }, [deviceGeolocation, geolocationService])
49
50 useEffect(() => {
51 /**
52 * Save this for out-of-band-reads during future cold starts of the app.
53 * Needs to be available for the data prefetching we do on boot.
54 */
55 device.set(['mergedGeolocation'], geolocation)
56 }, [geolocation])
57
58 useSyncDeviceGeolocationOnStartup(setDeviceGeolocation)
59
60 return (
61 <GeolocationContext.Provider value={geolocation}>
62 <DeviceGeolocationAPIContext.Provider
63 value={useMemo(() => ({setDeviceGeolocation}), [setDeviceGeolocation])}>
64 {children}
65 </DeviceGeolocationAPIContext.Provider>
66 </GeolocationContext.Provider>
67 )
68}