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 91 lines 2.2 kB view raw
1import { 2 createContext, 3 useContext, 4 useEffect, 5 useMemo, 6 useReducer, 7 useRef, 8} from 'react' 9 10import {useCurrentConvoId} from './current-convo-id' 11 12const MessageDraftsContext = createContext<{ 13 state: State 14 dispatch: React.Dispatch<Actions> 15} | null>(null) 16MessageDraftsContext.displayName = 'MessageDraftsContext' 17 18function useMessageDraftsContext() { 19 const ctx = useContext(MessageDraftsContext) 20 if (!ctx) { 21 throw new Error( 22 'useMessageDrafts must be used within a MessageDraftsContext', 23 ) 24 } 25 return ctx 26} 27 28export function useMessageDraft() { 29 const {currentConvoId} = useCurrentConvoId() 30 const {state, dispatch} = useMessageDraftsContext() 31 return useMemo( 32 () => ({ 33 getDraft: () => (currentConvoId && state[currentConvoId]) || '', 34 clearDraft: () => { 35 if (currentConvoId) { 36 dispatch({type: 'clear', convoId: currentConvoId}) 37 } 38 }, 39 }), 40 [state, dispatch, currentConvoId], 41 ) 42} 43 44export function useSaveMessageDraft(message: string) { 45 const {currentConvoId} = useCurrentConvoId() 46 const {dispatch} = useMessageDraftsContext() 47 const messageRef = useRef(message) 48 messageRef.current = message 49 50 useEffect(() => { 51 return () => { 52 if (currentConvoId) { 53 dispatch({ 54 type: 'set', 55 convoId: currentConvoId, 56 draft: messageRef.current, 57 }) 58 } 59 } 60 }, [currentConvoId, dispatch]) 61} 62 63type State = {[convoId: string]: string} 64type Actions = 65 | {type: 'set'; convoId: string; draft: string} 66 | {type: 'clear'; convoId: string} 67 68function reducer(state: State, action: Actions): State { 69 switch (action.type) { 70 case 'set': 71 return {...state, [action.convoId]: action.draft} 72 case 'clear': 73 return {...state, [action.convoId]: ''} 74 default: 75 return state 76 } 77} 78 79export function MessageDraftsProvider({children}: {children: React.ReactNode}) { 80 const [state, dispatch] = useReducer(reducer, {}) 81 82 const ctx = useMemo(() => { 83 return {state, dispatch} 84 }, [state]) 85 86 return ( 87 <MessageDraftsContext.Provider value={ctx}> 88 {children} 89 </MessageDraftsContext.Provider> 90 ) 91}