Bluesky app fork with some witchin' additions 馃挮
0
fork

Configure Feed

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

at theme-changes 73 lines 1.8 kB view raw
1import { 2 createContext, 3 useCallback, 4 useContext, 5 useEffect, 6 useMemo, 7 useState, 8} from 'react' 9import type {PropsWithChildren} from 'react' 10 11import * as persisted from '#/state/persisted' 12 13type SetStateCb = ( 14 s: persisted.Schema['hiddenPosts'], 15) => persisted.Schema['hiddenPosts'] 16type StateContext = persisted.Schema['hiddenPosts'] 17type ApiContext = { 18 hidePost: ({uri}: {uri: string}) => void 19 unhidePost: ({uri}: {uri: string}) => void 20} 21 22const stateContext = createContext<StateContext>(persisted.defaults.hiddenPosts) 23stateContext.displayName = 'HiddenPostsStateContext' 24const apiContext = createContext<ApiContext>({ 25 hidePost: () => {}, 26 unhidePost: () => {}, 27}) 28apiContext.displayName = 'HiddenPostsApiContext' 29 30export function Provider({children}: PropsWithChildren<{}>) { 31 const [state, setState] = useState(persisted.get('hiddenPosts')) 32 33 const setStateWrapped = useCallback( 34 (fn: SetStateCb) => { 35 const s = fn(persisted.get('hiddenPosts')) 36 setState(s) 37 persisted.write('hiddenPosts', s) 38 }, 39 [setState], 40 ) 41 42 const api = useMemo( 43 () => ({ 44 hidePost: ({uri}: {uri: string}) => { 45 setStateWrapped(s => [...(s || []), uri]) 46 }, 47 unhidePost: ({uri}: {uri: string}) => { 48 setStateWrapped(s => (s || []).filter(u => u !== uri)) 49 }, 50 }), 51 [setStateWrapped], 52 ) 53 54 useEffect(() => { 55 return persisted.onUpdate('hiddenPosts', nextHiddenPosts => { 56 setState(nextHiddenPosts) 57 }) 58 }, [setStateWrapped]) 59 60 return ( 61 <stateContext.Provider value={state}> 62 <apiContext.Provider value={api}>{children}</apiContext.Provider> 63 </stateContext.Provider> 64 ) 65} 66 67export function useHiddenPosts() { 68 return useContext(stateContext) 69} 70 71export function useHiddenPostsApi() { 72 return useContext(apiContext) 73}