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 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}