import { createContext, useCallback, useContext, useEffect, useMemo, useState, } from 'react' import * as persisted from '#/state/persisted' type SetStateCb = ( s: persisted.Schema['hiddenPosts'], ) => persisted.Schema['hiddenPosts'] type StateContext = persisted.Schema['hiddenPosts'] type ApiContext = { hidePost: ({uri}: {uri: string}) => void unhidePost: ({uri}: {uri: string}) => void } const stateContext = createContext(persisted.defaults.hiddenPosts) stateContext.displayName = 'HiddenPostsStateContext' const apiContext = createContext({ hidePost: () => {}, unhidePost: () => {}, }) apiContext.displayName = 'HiddenPostsApiContext' export function Provider({children}: React.PropsWithChildren<{}>) { const [state, setState] = useState(persisted.get('hiddenPosts')) const setStateWrapped = useCallback( (fn: SetStateCb) => { const s = fn(persisted.get('hiddenPosts')) setState(s) persisted.write('hiddenPosts', s) }, [setState], ) const api = useMemo( () => ({ hidePost: ({uri}: {uri: string}) => { setStateWrapped(s => [...(s || []), uri]) }, unhidePost: ({uri}: {uri: string}) => { setStateWrapped(s => (s || []).filter(u => u !== uri)) }, }), [setStateWrapped], ) useEffect(() => { return persisted.onUpdate('hiddenPosts', nextHiddenPosts => { setState(nextHiddenPosts) }) }, [setStateWrapped]) return ( {children} ) } export function useHiddenPosts() { return useContext(stateContext) } export function useHiddenPostsApi() { return useContext(apiContext) }