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

Configure Feed

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

at main 104 lines 2.6 kB view raw
1import { 2 createContext, 3 useCallback, 4 useContext, 5 useEffect, 6 useState, 7} from 'react' 8 9import * as persisted from '#/state/persisted' 10import {useAgent, useSession} from '../session' 11 12type StateContext = Map<string, boolean> 13type SetStateContext = (uri: string, value: boolean) => void 14 15const stateContext = createContext<StateContext>(new Map()) 16stateContext.displayName = 'ThreadMutesStateContext' 17const setStateContext = createContext<SetStateContext>((_: string) => false) 18setStateContext.displayName = 'ThreadMutesSetStateContext' 19 20export function Provider({children}: React.PropsWithChildren<{}>) { 21 const [state, setState] = useState<StateContext>(() => new Map()) 22 23 const setThreadMute = useCallback( 24 (uri: string, value: boolean) => { 25 setState(prev => { 26 const next = new Map(prev) 27 next.set(uri, value) 28 return next 29 }) 30 }, 31 [setState], 32 ) 33 34 useMigrateMutes(setThreadMute) 35 36 return ( 37 <stateContext.Provider value={state}> 38 <setStateContext.Provider value={setThreadMute}> 39 {children} 40 </setStateContext.Provider> 41 </stateContext.Provider> 42 ) 43} 44 45export function useMutedThreads() { 46 return useContext(stateContext) 47} 48 49export function useIsThreadMuted(uri: string, defaultValue = false) { 50 const state = useContext(stateContext) 51 return state.get(uri) ?? defaultValue 52} 53 54export function useSetThreadMute() { 55 return useContext(setStateContext) 56} 57 58function useMigrateMutes(setThreadMute: SetStateContext) { 59 const agent = useAgent() 60 const {currentAccount} = useSession() 61 62 useEffect(() => { 63 if (currentAccount) { 64 if ( 65 !persisted 66 .get('mutedThreads') 67 .some(uri => uri.includes(currentAccount.did)) 68 ) { 69 return 70 } 71 72 let cancelled = false 73 74 const migrate = async () => { 75 while (!cancelled) { 76 const threads = persisted.get('mutedThreads') 77 78 // @ts-ignore findLast is polyfilled - esb 79 const root = threads.findLast(uri => uri.includes(currentAccount.did)) 80 81 if (!root) break 82 83 persisted.write( 84 'mutedThreads', 85 threads.filter(uri => uri !== root), 86 ) 87 88 setThreadMute(root, true) 89 90 await agent.api.app.bsky.graph 91 .muteThread({root}) 92 // not a big deal if this fails, since the post might have been deleted 93 .catch(console.error) 94 } 95 } 96 97 migrate() 98 99 return () => { 100 cancelled = true 101 } 102 } 103 }, [agent, currentAccount, setThreadMute]) 104}