feat: convert Chat.jsx to RQ

This commit is contained in:
Daniel D Orlando 2023-04-03 16:46:35 -07:00
parent 573112de7b
commit 1cb8ef9803
6 changed files with 53 additions and 111 deletions

View file

@ -2,10 +2,6 @@ import * as t from './types';
import request from './request';
import * as endpoints from './endpoints';
export function postAICompletion(payload: t.TAICompletionRequest) {
return request.post(endpoints.getAICompletion(), payload);
}
export function getConversations(pageNumber: string): Promise<t.TGetConversationsResponse> {
return request.get(endpoints.getConversations(pageNumber));
}

View file

@ -1,6 +1,3 @@
export const openAiModels = () => {
return `/api/open-ai-models`;
};
export const getModels = () => {
return `/api/models`;

View file

@ -57,6 +57,23 @@ export const useGetConversationByIdQuery = (
);
}
//This isn't ideal because its just a query and we're using mutation, but it was the only way
//to make it work with how the Chat component is structured
export const useGetConversationByIdMutation = (
id: string,
callback: (data: t.TConversation) => void
): UseMutationResult<t.TConversation> => {
const queryClient = useQueryClient();
return useMutation(() => dataService.getConversationById(id),
{
onSuccess: (res: t.TConversation) => {
callback(res);
queryClient.invalidateQueries([QueryKeys.conversation, id]);
},
}
);
};
export const useUpdateConversationMutation = (
id: string
): UseMutationResult<

View file

@ -1,9 +1,9 @@
export type TMessage = {
messageId: string,
conversationId: string,
conversationSignature: string | null,
// conversationSignature: string | null,
clientId: string,
invocationId: string,
// invocationId: string,
parentMessageId: string,
sender: string,
text: string,
@ -11,12 +11,12 @@ export type TMessage = {
error: boolean,
createdAt: string,
updatedAt: string,
searchResult: string[],
submitting: boolean,
children?: any[] | undefined,
bgColor?: string,
model?: string,
cancelled?: boolean
// searchResult: string[],
// submitting: boolean,
// children?: any[] | undefined,
// bgColor?: string,
// model?: string,
// cancelled?: boolean
};
export type TMessageTreeNode = {}

View file

@ -1,4 +1,4 @@
import React, { useEffect } from 'react';
import { useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
@ -7,7 +7,7 @@ import Messages from '../components/Messages';
import TextChat from '../components/Input';
import store from '~/store';
import manualSWR from '~/utils/fetchers';
import { useGetMessagesByConvoId, useGetConversationByIdMutation } from '~/data-provider';
export default function Chat() {
const searchQuery = useRecoilValue(store.searchQuery);
@ -18,9 +18,9 @@ export default function Chat() {
const { conversationId } = useParams();
const navigate = useNavigate();
const { trigger: messagesTrigger } = manualSWR(`/api/messages/${conversation?.conversationId}`, 'get');
const { trigger: conversationTrigger } = manualSWR(`/api/convos/${conversationId}`, 'get');
//disabled by default, we only enable it when messagesTree is null
const messagesQuery = useGetMessagesByConvoId(conversationId, { enabled: false });
const getConversationMutation = useGetConversationByIdMutation(conversationId, setConversation);
// when conversation changed or conversationId (in url) changed
useEffect(() => {
@ -31,13 +31,7 @@ export default function Chat() {
newConversation();
} else if (conversationId) {
// fetch it from server
conversationTrigger()
.then(setConversation)
.catch(error => {
console.error('failed to fetch the conversation');
console.error(error);
newConversation();
});
getConversationMutation.mutate();
setMessages(null);
} else {
navigate(`/chat/new`);
@ -51,13 +45,30 @@ export default function Chat() {
}
}, [conversation, conversationId]);
// when messagesTree is null (<=> messages is null)
// we need to fetch message list from server
useEffect(() => {
if (messagesTree === null) {
messagesTrigger().then(setMessages);
if(getConversationMutation.isError) {
console.error('failed to fetch the conversation');
console.error(getConversationMutation.error);
newConversation();
}
}, [conversation?.conversationId]);
}, [getConversationMutation.isError, newConversation]);
useEffect(() => {
if (messagesTree === null && conversation?.conversationId) {
messagesQuery.refetch(conversation?.conversationId);
}
}, [conversation?.conversationId, messagesQuery, messagesTree]);
useEffect(() => {
if (messagesQuery.data) {
setMessages(messagesQuery.data);
} else if(messagesQuery.isError) {
console.error('failed to fetch the messages');
console.error(messagesQuery.error);
setMessages(null);
}
}, [messagesQuery.data, messagesQuery.isError, setMessages]);
// if not a conversation
if (conversation?.conversationId === 'search') return null;

View file

@ -1,79 +0,0 @@
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 ? <Landing /> : <Messages />}
<TextChat />
</>
);
}