import { MessageType } from '@/constants/chat'; import { useFetchFlow } from '@/hooks/flow-hooks'; import { useHandleMessageInputChange, useScrollToBottom, useSendMessageWithSse, } from '@/hooks/logic-hooks'; import { IAnswer } from '@/interfaces/database/chat'; import { IMessage } from '@/pages/chat/interface'; import api from '@/utils/api'; import { message } from 'antd'; import { useCallback, useEffect, useState } from 'react'; import { useParams } from 'umi'; import { v4 as uuid } from 'uuid'; import { receiveMessageError } from '../utils'; const antMessage = message; export const useSelectCurrentMessages = () => { const { id: id } = useParams(); const [currentMessages, setCurrentMessages] = useState([]); const { data: flowDetail, loading } = useFetchFlow(); const messages = flowDetail.dsl.messages; const reference = flowDetail.dsl.reference; const ref = useScrollToBottom(currentMessages); const addNewestQuestion = useCallback( (message: string, answer: string = '') => { setCurrentMessages((pre) => { return [ ...pre, { role: MessageType.User, content: message, id: uuid(), }, { role: MessageType.Assistant, content: answer, id: uuid(), }, ]; }); }, [], ); const addNewestAnswer = useCallback((answer: IAnswer) => { setCurrentMessages((pre) => { return [ ...pre.slice(0, -1), { id: uuid(), role: MessageType.Assistant, content: answer.answer, reference: answer.reference, }, ]; }); }, []); const removeLatestMessage = useCallback(() => { setCurrentMessages((pre) => { const nextMessages = pre?.slice(0, -2) ?? []; return nextMessages; return [...pre, ...nextMessages]; }); }, []); useEffect(() => { if (id) { const nextMessages = messages.map((x) => ({ ...x, id: uuid() })); setCurrentMessages(nextMessages); } }, [messages, id]); return { currentMessages, reference, addNewestQuestion, removeLatestMessage, addNewestAnswer, ref, loading, }; }; export const useSendMessage = ( addNewestQuestion: (message: string, answer?: string) => void, removeLatestMessage: () => void, addNewestAnswer: (answer: IAnswer) => void, ) => { const { id: flowId } = useParams(); const { handleInputChange, value, setValue } = useHandleMessageInputChange(); const { refetch } = useFetchFlow(); const { send, answer, done } = useSendMessageWithSse(api.runCanvas); const sendMessage = useCallback( async (message: string) => { const params: Record = { id: flowId, }; if (message) { params.message = message; } const res = await send(params); if (receiveMessageError(res)) { antMessage.error(res?.data?.retmsg); // cancel loading setValue(message); removeLatestMessage(); } else { refetch(); // pull the message list after sending the message successfully } }, [flowId, removeLatestMessage, setValue, send, refetch], ); const handleSendMessage = useCallback( async (message: string) => { sendMessage(message); }, [sendMessage], ); useEffect(() => { if (answer.answer) { addNewestAnswer(answer); } }, [answer, addNewestAnswer]); const handlePressEnter = useCallback(() => { if (done) { setValue(''); handleSendMessage(value.trim()); } addNewestQuestion(value); }, [addNewestQuestion, handleSendMessage, done, setValue, value]); return { handlePressEnter, handleInputChange, value, loading: !done, }; };