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