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