import { useCallback , useEffect , useState } from 'react' ; import { ensureDMConverse } from '../../helper/converse-helper' ; import { useAsync } from '../../hooks/useAsync' ; import { showErrorToasts } from '../../manager/ui' ; import { fetchConverseMessage , sendMessage , SendMessagePayload , } from '../../model/message' ; import { chatActions } from '../slices' ; import { useAppDispatch , useAppSelector } from './useAppSelector' ; import _get from 'lodash/get' ; import _isNil from 'lodash/isNil' ; import { ChatConverseState , isValidStr , t , useAsyncRequest , useChatBoxContext , } from '../..' ; import { MessageHelper } from '../../utils/message-helper' ; import { ChatConverseType } from '../../model/converse' ; function useHandleSendMessage ( context ) { const { converseId } = context ; const dispatch = useAppDispatch ( ) ; const { hasContext , replyMsg , clearReplyMsg } = useChatBoxContext ( ) ; /**
     * 发送消息
     */ const handleSendMessage = useCallback ( async ( payload ) => { payload . content = payload . content . trim ( ) ; if ( payload . content === '' ) { showErrorToasts ( t ( '无法发送空消息' ) ) ; return ; } try { if ( hasContext === true ) { const msgHelper = new MessageHelper ( payload ) ; if ( ! _isNil ( replyMsg ) ) { msgHelper . setReplyMsg ( replyMsg ) ; clearReplyMsg ( ) ; } payload = msgHelper . generatePayload ( ) ; } const message = await sendMessage ( payload ) ; dispatch ( chatActions . appendConverseMessage ( { converseId , messages : [ message ] } ) ) ; } catch ( err ) { showErrorToasts ( err ) ; } } , [ converseId , hasContext , replyMsg , clearReplyMsg ] ) ; return handleSendMessage ; } /**
 * 会话消息管理
 */ interface ConverseContext { converseId : string ; isGroup : boolean ; } export function useConverseMessage ( context ) { const { converseId , isGroup } = context ; const converse = useAppSelector < ChatConverseState | undefined > ( ( state ) => state . chat . converses [ converseId ] ) ; const hasMoreMessage = converse ?. hasMoreMessage ?? true ; const dispatch = useAppDispatch ( ) ; const messages = converse ?. messages ?? [ ] ; useEffect ( ( ) => { dispatch ( chatActions . updateCurrentConverseId ( converseId ) ) ; return ( ) => { dispatch ( chatActions . updateCurrentConverseId ( null ) ) ; } ; } , [ converseId ] ) ; const { loading , error } = useAsync ( async ( ) => { if ( ! converse ) { if ( ! isGroup ) { const converse = await ensureDMConverse ( converseId ) ; dispatch ( chatActions . setConverseInfo ( converse ) ) ; } else { dispatch ( chatActions . setConverseInfo ( { _id : converseId , name : '' , type : ChatConverseType . Group , members : [ ] } ) ) ; } const historyMessages = await fetchConverseMessage ( converseId ) ; dispatch ( chatActions . initialHistoryMessage ( { converseId , historyMessages } ) ) ; } else { if ( ! converse . hasFetchedHistory ) { const startId = _isNil ( converse . messages [ 0 ] ) ? undefined : converse . messages [ 0 ] . _id ; const messages = await fetchConverseMessage ( converseId , startId ) ; dispatch ( chatActions . initialHistoryMessage ( { converseId , historyMessages : messages } ) ) ; } } } , [ converseId ] ) ; const [ { loading : isLoadingMore } , handleFetchMoreMessage ] = useAsyncRequest ( async ( ) => { const firstMessageId = _get ( messages , [ 0 , '_id' ] ) ; if ( ! isValidStr ( firstMessageId ) ) { return ; } if ( hasMoreMessage === false ) { return ; } const olderMessages = await fetchConverseMessage ( converseId , firstMessageId ) ; dispatch ( chatActions . appendHistoryMessage ( { converseId , historyMessages : olderMessages } ) ) ; } , [ converseId , hasMoreMessage , _get ( messages , [ 0 , '_id' ] ) ] ) ; const handleSendMessage = useHandleSendMessage ( context ) ; return { messages , loading , error , isLoadingMore , hasMoreMessage , handleFetchMoreMessage , handleSendMessage } ; }