From 14633df88021d0df3499e9295ed16ec1deb0fbd5 Mon Sep 17 00:00:00 2001 From: balibabu <cike8899@users.noreply.github.com> Date: Thu, 29 Feb 2024 14:26:59 +0800 Subject: [PATCH] feat: let the messages I send appear immediately in the chat window and remove rewrite configuration from nginx proxy (#86) * feat: remove rewrite configuration from nginx proxy * feat: let the messages I send appear immediately in the chat window --- web/src/pages/chat/chat-container/index.tsx | 17 +- web/src/pages/chat/hooks.ts | 170 ++++++++++++-------- 2 files changed, 117 insertions(+), 70 deletions(-) diff --git a/web/src/pages/chat/chat-container/index.tsx b/web/src/pages/chat/chat-container/index.tsx index 9d33d5c..a071303 100644 --- a/web/src/pages/chat/chat-container/index.tsx +++ b/web/src/pages/chat/chat-container/index.tsx @@ -10,10 +10,8 @@ import reactStringReplace from 'react-string-replace'; import { useFetchConversationOnMount, useGetFileIcon, - useScrollToBottom, useSendMessage, } from '../hooks'; -import { IClientConversation } from '../interface'; import Image from '@/components/image'; import NewDocumentLink from '@/components/new-document-link'; @@ -187,17 +185,24 @@ const MessageItem = ({ const ChatContainer = () => { const [value, setValue] = useState(''); - const conversation: IClientConversation = useFetchConversationOnMount(); + const { + ref, + currentConversation: conversation, + addNewestConversation, + } = useFetchConversationOnMount(); const { sendMessage } = useSendMessage(); + const loading = useOneNamespaceEffectsLoading('chatModel', [ 'completeConversation', ]); - const ref = useScrollToBottom(); useGetFileIcon(); const handlePressEnter = () => { - setValue(''); - sendMessage(value); + if (!loading) { + setValue(''); + addNewestConversation(value); + sendMessage(value); + } }; const handleInputChange: ChangeEventHandler<HTMLInputElement> = (e) => { diff --git a/web/src/pages/chat/hooks.ts b/web/src/pages/chat/hooks.ts index 69859e8..97fd27b 100644 --- a/web/src/pages/chat/hooks.ts +++ b/web/src/pages/chat/hooks.ts @@ -374,32 +374,64 @@ export const useSetConversation = () => { const dispatch = useDispatch(); const { dialogId } = useGetChatSearchParams(); - const setConversation = (message: string) => { - return dispatch<any>({ - type: 'chatModel/setConversation', - payload: { - // conversation_id: '', - dialog_id: dialogId, - name: message, - message: [ - { - role: MessageType.Assistant, - content: message, - }, - ], - }, - }); - }; + const setConversation = useCallback( + (message: string) => { + return dispatch<any>({ + type: 'chatModel/setConversation', + payload: { + // conversation_id: '', + dialog_id: dialogId, + name: message, + message: [ + { + role: MessageType.Assistant, + content: message, + }, + ], + }, + }); + }, + [dispatch, dialogId], + ); return { setConversation }; }; export const useSelectCurrentConversation = () => { + const [currentConversation, setCurrentConversation] = + useState<IClientConversation>({} as IClientConversation); + const conversation: IClientConversation = useSelector( (state: any) => state.chatModel.currentConversation, ); - return conversation; + const addNewestConversation = useCallback((message: string) => { + setCurrentConversation((pre) => { + return { + ...pre, + message: [ + ...pre.message, + { + role: MessageType.User, + content: message, + id: uuid(), + } as IMessage, + ], + }; + }); + }, []); + + useEffect(() => { + console.info('useSelectCurrentConversation: 1', currentConversation); + }, [currentConversation]); + + useEffect(() => { + console.info('useSelectCurrentConversation: 2', conversation); + + setCurrentConversation(conversation); + }, [conversation]); + + return { currentConversation, addNewestConversation }; }; export const useFetchConversation = () => { @@ -421,11 +453,30 @@ export const useFetchConversation = () => { return fetchConversation; }; +export const useScrollToBottom = (currentConversation: IClientConversation) => { + const ref = useRef<HTMLDivElement>(null); + + const scrollToBottom = useCallback(() => { + console.info('useScrollToBottom'); + if (currentConversation.id) { + ref.current?.scrollIntoView({ behavior: 'instant' }); + } + }, [currentConversation]); + + useEffect(() => { + scrollToBottom(); + }, [scrollToBottom]); + + return ref; +}; + export const useFetchConversationOnMount = () => { const { conversationId } = useGetChatSearchParams(); - const conversation = useSelectCurrentConversation(); const setCurrentConversation = useSetCurrentConversation(); const fetchConversation = useFetchConversation(); + const { currentConversation, addNewestConversation } = + useSelectCurrentConversation(); + const ref = useScrollToBottom(currentConversation); const fetchConversationOnMount = useCallback(() => { if (isConversationIdExist(conversationId)) { @@ -439,68 +490,59 @@ export const useFetchConversationOnMount = () => { fetchConversationOnMount(); }, [fetchConversationOnMount]); - return conversation; + return { currentConversation, addNewestConversation, ref }; }; export const useSendMessage = () => { const dispatch = useDispatch(); const { setConversation } = useSetConversation(); const { conversationId } = useGetChatSearchParams(); - const conversation = useSelector( + const conversation: IClientConversation = useSelector( (state: any) => state.chatModel.currentConversation, ); + const { handleClickConversation } = useClickConversationCard(); - const sendMessage = (message: string, id?: string) => { - dispatch({ - type: 'chatModel/completeConversation', - payload: { - conversation_id: id ?? conversationId, - messages: [ - ...(conversation?.message ?? []).map((x: IMessage) => omit(x, 'id')), - { - role: MessageType.User, - content: message, - }, - ], - }, - }); - }; + const sendMessage = useCallback( + (message: string, id?: string) => { + dispatch({ + type: 'chatModel/completeConversation', + payload: { + conversation_id: id ?? conversationId, + messages: [ + ...(conversation?.message ?? []).map((x: IMessage) => + omit(x, 'id'), + ), + { + role: MessageType.User, + content: message, + }, + ], + }, + }); + }, + [dispatch, conversation?.message, conversationId], + ); - const handleSendMessage = async (message: string) => { - if (conversationId !== '') { - sendMessage(message); - } else { - const data = await setConversation(message); - if (data.retcode === 0) { - const id = data.data.id; - handleClickConversation(id); - sendMessage(message, id); + const handleSendMessage = useCallback( + async (message: string) => { + if (conversationId !== '') { + sendMessage(message); + } else { + const data = await setConversation(message); + if (data.retcode === 0) { + const id = data.data.id; + handleClickConversation(id); + sendMessage(message, id); + } } - } - }; + }, + [conversationId, handleClickConversation, setConversation, sendMessage], + ); return { sendMessage: handleSendMessage }; }; -export const useScrollToBottom = () => { - const ref = useRef<HTMLDivElement>(null); - let chatModel: ChatModelState = useSelector((state: any) => state.chatModel); - const { currentConversation } = chatModel; - - const scrollToBottom = useCallback(() => { - if (currentConversation.id) { - ref.current?.scrollIntoView({ behavior: 'instant' }); - } - }, [currentConversation]); - - useEffect(() => { - scrollToBottom(); - }, [scrollToBottom]); - - return ref; -}; - export const useGetFileIcon = () => { // const req = require.context('@/assets/svg/file-icon'); // const ret = req.keys().map(req); -- GitLab