소스 검색

WIP: refreshing thread title

Yuki Takei 11 달 전
부모
커밋
9b8c5419ca

+ 16 - 1
apps/app/src/features/openai/client/components/AiAssistant/AiAssistantSidebar/AiAssistantSidebar.tsx

@@ -29,6 +29,7 @@ import {
   type FormData as FormDataForKnowledgeAssistant,
 } from '../../../services/knowledge-assistant';
 import { useAiAssistantSidebar } from '../../../stores/ai-assistant';
+// import { useSWRxThreads } from '../../../stores/thread'; // 削除
 
 import { MessageCard, type MessageCardRole } from './MessageCard';
 import { ResizableTextarea } from './ResizableTextArea';
@@ -66,6 +67,8 @@ const AiAssistantSidebarSubstance: React.FC<AiAssistantSidebarSubstanceProps> =
   // Hooks
   const { t } = useTranslation();
   const { data: growiCloudUri } = useGrowiCloudUri();
+  // const { data: threads, isLoading: isLoadingThreads } = useSWRxThreads(aiAssistantData?._id); // 削除
+  const { data: aiAssistantSidebarData, refreshCurrentThreadData } = useAiAssistantSidebar(); // refreshCurrentThreadData を追加
 
   const {
     createThread: createThreadForKnowledgeAssistant,
@@ -226,6 +229,7 @@ const AiAssistantSidebarSubstance: React.FC<AiAssistantSidebarSubstanceProps> =
             setMessageLogs(msgs => [...msgs, generatingAnswerMessage]);
             return undefined;
           });
+          refreshCurrentThreadData(); // メッセージ送信成功後に呼び出し
           return;
         }
 
@@ -318,11 +322,22 @@ const AiAssistantSidebarSubstance: React.FC<AiAssistantSidebarSubstanceProps> =
       : headerIconForKnowledgeAssistant;
   }, [headerIconForEditorAssistant, headerIconForKnowledgeAssistant, isEditorAssistant]);
 
+  // const currentThreadTitleFromSWR = useMemo(() => { // 削除
+  //   if (isLoadingThreads || threads == null || currentThreadId == null) { // 削除
+  //     return undefined; // 削除
+  //   } // 削除
+  //   const foundThread = threads.find(t => t.threadId === currentThreadId); // 削除
+  //   return foundThread?.title; // 削除
+  // }, [threads, currentThreadId, isLoadingThreads]); // 削除
+
   const headerText = useMemo(() => {
+    if (aiAssistantSidebarData?.threadData?.title) { // useAiAssistantSidebar から取得した title を使用
+      return aiAssistantSidebarData.threadData.title;
+    }
     return isEditorAssistant
       ? headerTextForEditorAssistant
       : headerTextForKnowledgeAssistant;
-  }, [isEditorAssistant, headerTextForEditorAssistant, headerTextForKnowledgeAssistant]);
+  }, [isEditorAssistant, headerTextForEditorAssistant, headerTextForKnowledgeAssistant, aiAssistantSidebarData?.threadData?.title]); // 依存配列を更新
 
   const placeHolder = useMemo(() => {
     if (form.formState.isSubmitting) {

+ 33 - 3
apps/app/src/features/openai/client/stores/ai-assistant.tsx

@@ -1,13 +1,15 @@
 import { useCallback } from 'react';
 
 import { useSWRStatic } from '@growi/core/dist/swr';
-import { type SWRResponse } from 'swr';
+import { type SWRResponse, mutate, useSWRConfig } from 'swr';
 import useSWRImmutable from 'swr/immutable';
 
 import { apiv3Get } from '~/client/util/apiv3-client';
 
 import { type AccessibleAiAssistantsHasId, type AiAssistantHasId } from '../../interfaces/ai-assistant';
-import type { IThreadRelationHasId } from '../../interfaces/thread-relation';
+import type { IThreadRelationHasId } from '../../interfaces/thread-relation'; // IThreadHasId を削除
+
+import { useSWRxThreads } from './thread';
 
 export const AiAssistantManagementModalPageMode = {
   HOME: 'home',
@@ -72,6 +74,7 @@ type AiAssistantSidebarUtils = {
   ): void
   openEditor(): void
   close(): void
+  refreshCurrentThreadData(): Promise<void>
 }
 
 export const useAiAssistantSidebar = (
@@ -79,11 +82,37 @@ export const useAiAssistantSidebar = (
 ): SWRResponse<AiAssistantSidebarStatus, Error> & AiAssistantSidebarUtils => {
   const initialStatus = { isOpened: false };
   const swrResponse = useSWRStatic<AiAssistantSidebarStatus, Error>('AiAssistantSidebar', status, { fallbackData: initialStatus });
+  const { cache } = useSWRConfig();
+
+  const refreshCurrentThreadData = useCallback(async() => {
+    const { aiAssistantData, threadData } = swrResponse.data ?? {};
+
+    if (aiAssistantData?._id == null || threadData?._id == null) {
+      return;
+    }
+
+    const threadsCacheKey = ['threads', aiAssistantData._id];
+    await mutate(threadsCacheKey);
+
+    // useSWRxThreads を直接呼び出す代わりに cache を使用
+    // cache.get のキーは文字列である必要があるため、配列を結合
+    const threadsData = cache.get(threadsCacheKey.join(','))?.data as IThreadRelationHasId[] | undefined; // IThread を IThreadRelationHasId に変更
+
+    if (threadsData == null) {
+      return;
+    }
+
+    const newThreadDataFromServer = threadsData.find(t => t._id === threadData._id);
+
+    if (newThreadDataFromServer != null && swrResponse.data != null) { // swrResponse.data の存在を確認
+      swrResponse.mutate({ ...swrResponse.data, threadData: newThreadDataFromServer });
+    }
+  }, [swrResponse, cache]);
 
   return {
     ...swrResponse,
     openChat: useCallback(
-      (aiAssistantData: AiAssistantHasId, threadData: IThreadRelationHasId) => {
+      (aiAssistantData: AiAssistantHasId, threadData?: IThreadRelationHasId) => {
         swrResponse.mutate({ isOpened: true, aiAssistantData, threadData });
       }, [swrResponse],
     ),
@@ -99,5 +128,6 @@ export const useAiAssistantSidebar = (
         isOpened: false, isEditorAssistant: false, aiAssistantData: undefined, threadData: undefined,
       }), [swrResponse],
     ),
+    refreshCurrentThreadData,
   };
 };

+ 1 - 0
apps/app/src/features/openai/client/stores/thread.tsx

@@ -22,5 +22,6 @@ export const useSWRMUTxThreads = (aiAssistantId?: string): SWRMutationResponse<I
   return useSWRMutation(
     key,
     ([endpoint]) => apiv3Get(endpoint).then(response => response.data.threads),
+    { revalidate: true },
   );
 };