Просмотр исходного кода

improve state management while generating answer

Yuki Takei 1 год назад
Родитель
Сommit
35a6cc1ef9
1 измененных файлов с 21 добавлено и 13 удалено
  1. 21 13
      apps/app/src/features/openai/chat/components/AiChatModal/AiChatModal.tsx

+ 21 - 13
apps/app/src/features/openai/chat/components/AiChatModal/AiChatModal.tsx

@@ -43,7 +43,9 @@ const AiChatModalSubstance = (): JSX.Element => {
 
 
   const [threadId, setThreadId] = useState<string | undefined>();
   const [threadId, setThreadId] = useState<string | undefined>();
   const [messageLogs, setMessageLogs] = useState<Message[]>([]);
   const [messageLogs, setMessageLogs] = useState<Message[]>([]);
-  const [lastMessage, setLastMessage] = useState<Message>();
+  const [generatingAnswerMessage, setGeneratingAnswerMessage] = useState<Message>();
+
+  const isGenerating = generatingAnswerMessage != null;
 
 
   useEffect(() => {
   useEffect(() => {
     // do nothing when the modal is closed or threadId is already set
     // do nothing when the modal is closed or threadId is already set
@@ -68,6 +70,11 @@ const AiChatModalSubstance = (): JSX.Element => {
   }, [threadId]);
   }, [threadId]);
 
 
   const submit = useCallback(async(data: FormData) => {
   const submit = useCallback(async(data: FormData) => {
+    // do nothing when the assistant is generating an answer
+    if (isGenerating) {
+      return;
+    }
+
     const { length: logLength } = messageLogs;
     const { length: logLength } = messageLogs;
 
 
     // add user message to the logs
     // add user message to the logs
@@ -78,8 +85,8 @@ const AiChatModalSubstance = (): JSX.Element => {
     form.reset();
     form.reset();
 
 
     // add an empty assistant message
     // add an empty assistant message
-    const newAssistantMessage = { id: (logLength + 1).toString(), content: '' };
-    setLastMessage(newAssistantMessage);
+    const newAnswerMessage = { id: (logLength + 1).toString(), content: '' };
+    setGeneratingAnswerMessage(newAnswerMessage);
 
 
     // post message
     // post message
     try {
     try {
@@ -96,7 +103,7 @@ const AiChatModalSubstance = (): JSX.Element => {
           const errors = resJson.errors.map(({ message }) => message).join(', ');
           const errors = resJson.errors.map(({ message }) => message).join(', ');
           form.setError('input', { type: 'manual', message: `[${response.status}] ${errors}` });
           form.setError('input', { type: 'manual', message: `[${response.status}] ${errors}` });
         }
         }
-        setLastMessage(undefined);
+        setGeneratingAnswerMessage(undefined);
         return;
         return;
       }
       }
 
 
@@ -110,9 +117,9 @@ const AiChatModalSubstance = (): JSX.Element => {
 
 
         // add assistant message to the logs
         // add assistant message to the logs
         if (done) {
         if (done) {
-          setLastMessage((lastMessage) => {
-            if (lastMessage == null) return;
-            setMessageLogs(msgs => [...msgs, lastMessage]);
+          setGeneratingAnswerMessage((generatingAnswerMessage) => {
+            if (generatingAnswerMessage == null) return;
+            setMessageLogs(msgs => [...msgs, generatingAnswerMessage]);
             return undefined;
             return undefined;
           });
           });
           return;
           return;
@@ -130,7 +137,7 @@ const AiChatModalSubstance = (): JSX.Element => {
           });
           });
 
 
         // append text values to the assistant message
         // append text values to the assistant message
-        setLastMessage((prevMessage) => {
+        setGeneratingAnswerMessage((prevMessage) => {
           if (prevMessage == null) return;
           if (prevMessage == null) return;
           return {
           return {
             ...prevMessage,
             ...prevMessage,
@@ -147,7 +154,7 @@ const AiChatModalSubstance = (): JSX.Element => {
       form.setError('input', { type: 'manual', message: err.toString() });
       form.setError('input', { type: 'manual', message: err.toString() });
     }
     }
 
 
-  }, [form, messageLogs, threadId]);
+  }, [form, isGenerating, messageLogs, threadId]);
 
 
   const keyDownHandler = (event: KeyboardEvent<HTMLTextAreaElement>) => {
   const keyDownHandler = (event: KeyboardEvent<HTMLTextAreaElement>) => {
     if (event.key === 'Enter' && (event.ctrlKey || event.metaKey)) {
     if (event.key === 'Enter' && (event.ctrlKey || event.metaKey)) {
@@ -162,8 +169,8 @@ const AiChatModalSubstance = (): JSX.Element => {
           { messageLogs.map(message => (
           { messageLogs.map(message => (
             <MessageCard key={message.id} role={message.isUserMessage ? 'user' : 'assistant'}>{message.content}</MessageCard>
             <MessageCard key={message.id} role={message.isUserMessage ? 'user' : 'assistant'}>{message.content}</MessageCard>
           )) }
           )) }
-          { lastMessage != null && (
-            <MessageCard role="assistant">{lastMessage.content}</MessageCard>
+          { generatingAnswerMessage != null && (
+            <MessageCard role="assistant">{generatingAnswerMessage.content}</MessageCard>
           )}
           )}
           { messageLogs.length > 0 && (
           { messageLogs.length > 0 && (
             <div className="d-flex justify-content-center">
             <div className="d-flex justify-content-center">
@@ -187,15 +194,16 @@ const AiChatModalSubstance = (): JSX.Element => {
                 className="form-control textarea-ask"
                 className="form-control textarea-ask"
                 style={{ resize: 'none' }}
                 style={{ resize: 'none' }}
                 rows={1}
                 rows={1}
-                placeholder={t('modal_aichat.placeholder')}
+                placeholder={!form.formState.isSubmitting ? t('modal_aichat.placeholder') : ''}
                 onKeyDown={keyDownHandler}
                 onKeyDown={keyDownHandler}
+                disabled={form.formState.isSubmitting}
               />
               />
             )}
             )}
           />
           />
           <button
           <button
             type="submit"
             type="submit"
             className="btn btn-submit no-border"
             className="btn btn-submit no-border"
-            disabled={form.formState.isSubmitting}
+            disabled={form.formState.isSubmitting || isGenerating}
           >
           >
             <span className="material-symbols-outlined">send</span>
             <span className="material-symbols-outlined">send</span>
           </button>
           </button>