diff --git a/client/src/components/Conversations/Conversation.jsx b/client/src/components/Conversations/Conversation.jsx index c95c9d1f4b..1ce42c85fd 100644 --- a/client/src/components/Conversations/Conversation.jsx +++ b/client/src/components/Conversations/Conversation.jsx @@ -1,6 +1,6 @@ -import React, { useState, useRef } from 'react'; +import { useState, useRef, useEffect} from 'react'; import { useRecoilState, useSetRecoilState } from 'recoil'; - +import { useUpdateConversationMutation } from '~/data-provider'; import RenameButton from './RenameButton'; import DeleteButton from './DeleteButton'; import ConvoIcon from '../svg/ConvoIcon'; @@ -15,6 +15,8 @@ export default function Conversation({ conversation, retainView }) { const { refreshConversations } = store.useConversations(); const { switchToConversation } = store.useConversation(); + const updateConvoMutation = useUpdateConversationMutation(currentConversation?.conversationId); + const [renaming, setRenaming] = useState(false); const inputRef = useRef(null); @@ -22,7 +24,7 @@ export default function Conversation({ conversation, retainView }) { const [titleInput, setTitleInput] = useState(title); - const rename = manualSWR(`/api/convos/update`, 'post'); + const rename = manualSWR(`/api/convos/update`, 'post'); const clickHandler = async () => { if (currentConversation?.conversationId === conversationId) { @@ -59,16 +61,31 @@ export default function Conversation({ conversation, retainView }) { if (titleInput === title) { return; } - rename.trigger({ conversationId, title: titleInput }).then(() => { - refreshConversations(); - if (conversationId == currentConversation?.conversationId) - setCurrentConversation(prevState => ({ - ...prevState, - title: titleInput - })); - }); + updateConvoMutation.mutate({ arg: { conversationId, title: titleInput }}); + + // rename.trigger({ conversationId, title: titleInput }).then(() => { + // refreshConversations(); + // if (conversationId == currentConversation?.conversationId) + // setCurrentConversation(prevState => ({ + // ...prevState, + // title: titleInput + // })); + // }); }; + useEffect(() => { + if (updateConvoMutation.isSuccess) { + // debugger; + refreshConversations(); + if (conversationId == currentConversation?.conversationId) + + setCurrentConversation(prevState => ({ + ...prevState, + title: titleInput + })); + } +}, [updateConvoMutation.isSuccess]); + const handleKeyDown = e => { if (e.key === 'Enter') { onRename(e); diff --git a/client/src/data-provider/react-query-service.ts b/client/src/data-provider/react-query-service.ts index fa7b99c3d8..cd1186c6c2 100644 --- a/client/src/data-provider/react-query-service.ts +++ b/client/src/data-provider/react-query-service.ts @@ -8,6 +8,8 @@ import { } from "@tanstack/react-query"; import * as t from "./types"; import * as dataService from "./data-service"; +import { useRecoilState, useResetRecoilState, useSetRecoilState } from 'recoil'; +import store from '~/store'; export enum QueryKeys { messages = "messsages", @@ -66,13 +68,17 @@ export const useUpdateConversationMutation = ( t.TUpdateConversationRequest, unknown > => { + const [conversation, setConversation] = useRecoilState(store.conversation); const queryClient = useQueryClient(); return useMutation( (payload: t.TUpdateConversationRequest) => dataService.updateConversation(payload), { - onSuccess: () => { + onSuccess: (res) => { + console.log('res', res); + setConversation(res); queryClient.invalidateQueries([QueryKeys.conversation, id]); + queryClient.invalidateQueries([QueryKeys.allConversations, id]); }, } ); diff --git a/client/src/routes/ChatRQTemp.jsx b/client/src/routes/ChatRQTemp.jsx new file mode 100644 index 0000000000..f2a88c2483 --- /dev/null +++ b/client/src/routes/ChatRQTemp.jsx @@ -0,0 +1,79 @@ +import React, { useEffect } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; + +import Landing from '../components/ui/Landing'; +import Messages from '../components/Messages'; +import TextChat from '../components/Input'; + +import store from '~/store'; +import { useGetMessagesByConvoId, useGetConversationByIdQuery } from '~/data-provider'; + +export default function Chat() { + const searchQuery = useRecoilValue(store.searchQuery); + const [conversation, setConversation] = useRecoilState(store.conversation); + const setMessages = useSetRecoilState(store.messages); + const messagesTree = useRecoilValue(store.messagesTree); + const { newConversation } = store.useConversation(); + const { conversationId } = useParams(); + const navigate = useNavigate(); + + //disabled by default, we only enable it when messagesTree is null + const messagesQuery = useGetMessagesByConvoId(conversation?.conversationId, { enabled: false }); + + const conversationQuery = useGetConversationByIdQuery( + conversation?.conversationId, { + enabled: !!conversation?.conversationId && + conversation?.conversationId !== 'search' && + conversation?.conversationId !== 'new' + }); + + // when conversation changed or conversationId (in url) changed + useEffect(() => { + if (conversation === null) { + // no current conversation, we need to do something + if (conversationId === 'new') { + // create new + newConversation(); + } else if (conversationQuery.data) { + // fetch it from server + setConversation(conversationQuery.data); + setMessages(null); + } else if (conversationQuery.isError) { + console.error('failed to fetch the conversation'); + console.error(conversationQuery.error); + newConversation(); + } else { + navigate(`/chat/new`); + } + } else if (conversation?.conversationId === 'search') { + // jump to search page + navigate(`/search/${searchQuery}`); + } else if (conversation?.conversationId !== conversationId) { + // conversationId (in url) should always follow conversation?.conversationId, unless conversation is null + navigate(`/chat/${conversation?.conversationId}`); + } + }, [conversation, conversationId, newConversation, navigate, searchQuery, setMessages, conversationQuery]); + + // when messagesTree is null (<=> messages is null) + // we need to fetch message list from server + useEffect(() => { + if (messagesTree === null) { + messagesQuery.refetch(conversation?.conversationId); + } + }, [conversation?.conversationId, messagesQuery, messagesTree]); + + // if not a conversation + if (conversation?.conversationId === 'search') return null; + // if conversationId not match + if (conversation?.conversationId !== conversationId) return null; + // if conversationId is null + if (!conversationId) return null; + + return ( + <> + {conversationId === 'new' && !messagesTree?.length ? : } + + + ); +}