Bluesky app fork with some witchin' additions 馃挮
at fbd1138d97dda2df66bee13ad3ca6e83d55ebc25 101 lines 2.8 kB view raw
1import React from 'react' 2import {type AppBskyFeedThreadgate} from '@atproto/api' 3 4type StateContext = { 5 uris: Set<string> 6 recentlyUnhiddenUris: Set<string> 7} 8type ApiContext = { 9 addHiddenReplyUri: (uri: string) => void 10 removeHiddenReplyUri: (uri: string) => void 11} 12 13const StateContext = React.createContext<StateContext>({ 14 uris: new Set(), 15 recentlyUnhiddenUris: new Set(), 16}) 17StateContext.displayName = 'ThreadgateHiddenRepliesStateContext' 18 19const ApiContext = React.createContext<ApiContext>({ 20 addHiddenReplyUri: () => {}, 21 removeHiddenReplyUri: () => {}, 22}) 23ApiContext.displayName = 'ThreadgateHiddenRepliesApiContext' 24 25export function Provider({children}: {children: React.ReactNode}) { 26 const [uris, setHiddenReplyUris] = React.useState<Set<string>>(new Set()) 27 const [recentlyUnhiddenUris, setRecentlyUnhiddenUris] = React.useState< 28 Set<string> 29 >(new Set()) 30 31 const stateCtx = React.useMemo( 32 () => ({ 33 uris, 34 recentlyUnhiddenUris, 35 }), 36 [uris, recentlyUnhiddenUris], 37 ) 38 39 const apiCtx = React.useMemo( 40 () => ({ 41 addHiddenReplyUri(uri: string) { 42 setHiddenReplyUris(prev => new Set(prev.add(uri))) 43 setRecentlyUnhiddenUris(prev => { 44 prev.delete(uri) 45 return new Set(prev) 46 }) 47 }, 48 removeHiddenReplyUri(uri: string) { 49 setHiddenReplyUris(prev => { 50 prev.delete(uri) 51 return new Set(prev) 52 }) 53 setRecentlyUnhiddenUris(prev => new Set(prev.add(uri))) 54 }, 55 }), 56 [setHiddenReplyUris], 57 ) 58 59 return ( 60 <ApiContext.Provider value={apiCtx}> 61 <StateContext.Provider value={stateCtx}>{children}</StateContext.Provider> 62 </ApiContext.Provider> 63 ) 64} 65 66export function useThreadgateHiddenReplyUris() { 67 return React.useContext(StateContext) 68} 69 70export function useThreadgateHiddenReplyUrisAPI() { 71 return React.useContext(ApiContext) 72} 73 74export function useMergedThreadgateHiddenReplies({ 75 threadgateRecord, 76}: { 77 threadgateRecord?: AppBskyFeedThreadgate.Record 78}) { 79 const {uris, recentlyUnhiddenUris} = useThreadgateHiddenReplyUris() 80 return React.useMemo(() => { 81 const set = new Set([...(threadgateRecord?.hiddenReplies || []), ...uris]) 82 for (const uri of recentlyUnhiddenUris) { 83 set.delete(uri) 84 } 85 return set 86 }, [uris, recentlyUnhiddenUris, threadgateRecord]) 87} 88 89export function useMergeThreadgateHiddenReplies() { 90 const {uris, recentlyUnhiddenUris} = useThreadgateHiddenReplyUris() 91 return React.useCallback( 92 (threadgate?: AppBskyFeedThreadgate.Record) => { 93 const set = new Set([...(threadgate?.hiddenReplies || []), ...uris]) 94 for (const uri of recentlyUnhiddenUris) { 95 set.delete(uri) 96 } 97 return set 98 }, 99 [uris, recentlyUnhiddenUris], 100 ) 101}