Bluesky app fork with some witchin' additions 馃挮 witchsky.app
bluesky fork client
119
fork

Configure Feed

Select the types of activity you want to include in your feed.

at a876aae44ea07494ebea9727350aa060b81f317b 87 lines 2.1 kB view raw
1import {createContext, useContext} from 'react' 2import {QueryClient, useQuery} from '@tanstack/react-query' 3 4import {APP_CONFIG_URL} from '#/env' 5 6const qc = new QueryClient() 7const appConfigQueryKey = ['app-config'] 8 9/** 10 * Matches the types defined in our `app-config` worker 11 */ 12type AppConfigResponse = { 13 liveNow: { 14 allow: string[] 15 exceptions: { 16 did: string 17 allow: string[] 18 }[] 19 } 20} 21 22export const DEFAULT_APP_CONFIG_RESPONSE: AppConfigResponse = { 23 liveNow: { 24 allow: [], 25 exceptions: [], 26 }, 27} 28 29let fetchAppConfigPromise: Promise<AppConfigResponse> | undefined 30 31async function fetchAppConfig(): Promise<AppConfigResponse | null> { 32 try { 33 if (!fetchAppConfigPromise) { 34 fetchAppConfigPromise = (async () => { 35 const r = await fetch(`${APP_CONFIG_URL}/config`) 36 if (!r.ok) throw new Error(await r.text()) 37 const data = await r.json() 38 return data 39 })() 40 } 41 return await fetchAppConfigPromise 42 } catch (e) { 43 fetchAppConfigPromise = undefined 44 throw e 45 } 46} 47 48const Context = createContext<AppConfigResponse>(DEFAULT_APP_CONFIG_RESPONSE) 49 50export function Provider({children}: React.PropsWithChildren<{}>) { 51 const {data} = useQuery<AppConfigResponse | null>( 52 { 53 staleTime: Infinity, 54 queryKey: appConfigQueryKey, 55 refetchInterval: query => { 56 // refetch regularly if fetch failed, otherwise never refetch 57 return query.state.status === 'error' ? 60e3 : Infinity 58 }, 59 async queryFn() { 60 return fetchAppConfig() 61 }, 62 }, 63 qc, 64 ) 65 return ( 66 <Context.Provider value={data ?? DEFAULT_APP_CONFIG_RESPONSE}> 67 {children} 68 </Context.Provider> 69 ) 70} 71 72export async function prefetchAppConfig() { 73 try { 74 const data = await fetchAppConfig() 75 if (data) { 76 qc.setQueryData(appConfigQueryKey, data) 77 } 78 } catch {} 79} 80 81export function useAppConfig() { 82 const ctx = useContext(Context) 83 if (!ctx) { 84 throw new Error('useAppConfig must be used within a Provider') 85 } 86 return ctx 87}