mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 17:00:15 +01:00
feat: convert Chat.jsx to RQ
This commit is contained in:
parent
573112de7b
commit
1cb8ef9803
6 changed files with 53 additions and 111 deletions
|
|
@ -2,10 +2,6 @@ import * as t from './types';
|
||||||
import request from './request';
|
import request from './request';
|
||||||
import * as endpoints from './endpoints';
|
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> {
|
export function getConversations(pageNumber: string): Promise<t.TGetConversationsResponse> {
|
||||||
return request.get(endpoints.getConversations(pageNumber));
|
return request.get(endpoints.getConversations(pageNumber));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
export const openAiModels = () => {
|
|
||||||
return `/api/open-ai-models`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getModels = () => {
|
export const getModels = () => {
|
||||||
return `/api/models`;
|
return `/api/models`;
|
||||||
|
|
|
||||||
|
|
@ -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 = (
|
export const useUpdateConversationMutation = (
|
||||||
id: string
|
id: string
|
||||||
): UseMutationResult<
|
): UseMutationResult<
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
export type TMessage = {
|
export type TMessage = {
|
||||||
messageId: string,
|
messageId: string,
|
||||||
conversationId: string,
|
conversationId: string,
|
||||||
conversationSignature: string | null,
|
// conversationSignature: string | null,
|
||||||
clientId: string,
|
clientId: string,
|
||||||
invocationId: string,
|
// invocationId: string,
|
||||||
parentMessageId: string,
|
parentMessageId: string,
|
||||||
sender: string,
|
sender: string,
|
||||||
text: string,
|
text: string,
|
||||||
|
|
@ -11,12 +11,12 @@ export type TMessage = {
|
||||||
error: boolean,
|
error: boolean,
|
||||||
createdAt: string,
|
createdAt: string,
|
||||||
updatedAt: string,
|
updatedAt: string,
|
||||||
searchResult: string[],
|
// searchResult: string[],
|
||||||
submitting: boolean,
|
// submitting: boolean,
|
||||||
children?: any[] | undefined,
|
// children?: any[] | undefined,
|
||||||
bgColor?: string,
|
// bgColor?: string,
|
||||||
model?: string,
|
// model?: string,
|
||||||
cancelled?: boolean
|
// cancelled?: boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TMessageTreeNode = {}
|
export type TMessageTreeNode = {}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
|
@ -7,7 +7,7 @@ import Messages from '../components/Messages';
|
||||||
import TextChat from '../components/Input';
|
import TextChat from '../components/Input';
|
||||||
|
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
import manualSWR from '~/utils/fetchers';
|
import { useGetMessagesByConvoId, useGetConversationByIdMutation } from '~/data-provider';
|
||||||
|
|
||||||
export default function Chat() {
|
export default function Chat() {
|
||||||
const searchQuery = useRecoilValue(store.searchQuery);
|
const searchQuery = useRecoilValue(store.searchQuery);
|
||||||
|
|
@ -18,9 +18,9 @@ export default function Chat() {
|
||||||
const { conversationId } = useParams();
|
const { conversationId } = useParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const { trigger: messagesTrigger } = manualSWR(`/api/messages/${conversation?.conversationId}`, 'get');
|
//disabled by default, we only enable it when messagesTree is null
|
||||||
|
const messagesQuery = useGetMessagesByConvoId(conversationId, { enabled: false });
|
||||||
const { trigger: conversationTrigger } = manualSWR(`/api/convos/${conversationId}`, 'get');
|
const getConversationMutation = useGetConversationByIdMutation(conversationId, setConversation);
|
||||||
|
|
||||||
// when conversation changed or conversationId (in url) changed
|
// when conversation changed or conversationId (in url) changed
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -31,13 +31,7 @@ export default function Chat() {
|
||||||
newConversation();
|
newConversation();
|
||||||
} else if (conversationId) {
|
} else if (conversationId) {
|
||||||
// fetch it from server
|
// fetch it from server
|
||||||
conversationTrigger()
|
getConversationMutation.mutate();
|
||||||
.then(setConversation)
|
|
||||||
.catch(error => {
|
|
||||||
console.error('failed to fetch the conversation');
|
|
||||||
console.error(error);
|
|
||||||
newConversation();
|
|
||||||
});
|
|
||||||
setMessages(null);
|
setMessages(null);
|
||||||
} else {
|
} else {
|
||||||
navigate(`/chat/new`);
|
navigate(`/chat/new`);
|
||||||
|
|
@ -51,13 +45,30 @@ export default function Chat() {
|
||||||
}
|
}
|
||||||
}, [conversation, conversationId]);
|
}, [conversation, conversationId]);
|
||||||
|
|
||||||
// when messagesTree is null (<=> messages is null)
|
|
||||||
// we need to fetch message list from server
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (messagesTree === null) {
|
if(getConversationMutation.isError) {
|
||||||
messagesTrigger().then(setMessages);
|
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 not a conversation
|
||||||
if (conversation?.conversationId === 'search') return null;
|
if (conversation?.conversationId === 'search') return null;
|
||||||
|
|
|
||||||
|
|
@ -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 />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue