mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-02-26 12:24:10 +01:00
* chore(eslint): add ignore pattern for packages/data-provider/types
chore(data-provider): fix import formatting in index.ts
chore(data-provider): add types/index.d.ts to tsconfig include
* fix(Auth): fix "skip login" bug, where UI would render in an unauthenticated state
fix(Login.tsx): replace navigate('/chat/new') with navigate('/chat/new', { replace: true })
fix(AuthContext.tsx): replace navigate(redirect) with navigate(redirect, { replace: true })
fix(AuthContext.tsx): replace navigate('/login') with navigate('/login', { replace: true })
fix(AuthContext.tsx): replace navigate('/login') with navigate('/login', { replace: true })
fix(routes/Chat.jsx): add check for isAuthenticated: navigate to '/login' and render null if not authenticated
fix(routes/index.jsx): add check for isAuthenticated: navigate to '/login' and render null if not authenticated
* refactor(SubmitButton.jsx): create a set of endpoints to hide set tokens
fix(SubmitButton.jsx): fix condition to check if token is provided for certain endpoints
144 lines
4.6 KiB
JavaScript
144 lines
4.6 KiB
JavaScript
import { useState, useEffect } from 'react';
|
|
import { useAuthContext } from '~/hooks/AuthContext';
|
|
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,
|
|
useGetConversationByIdMutation,
|
|
useGetStartupConfig
|
|
} from '@librechat/data-provider';
|
|
|
|
export default function Chat() {
|
|
const { isAuthenticated } = useAuthContext();
|
|
const [shouldNavigate, setShouldNavigate] = useState(true);
|
|
const searchQuery = useRecoilValue(store.searchQuery);
|
|
const [conversation, setConversation] = useRecoilState(store.conversation);
|
|
const setMessages = useSetRecoilState(store.messages);
|
|
const messagesTree = useRecoilValue(store.messagesTree);
|
|
const isSubmitting = useRecoilValue(store.isSubmitting);
|
|
const { newConversation } = store.useConversation();
|
|
const { conversationId } = useParams();
|
|
const navigate = useNavigate();
|
|
|
|
//disabled by default, we only enable it when messagesTree is null
|
|
const messagesQuery = useGetMessagesByConvoId(conversationId, { enabled: false });
|
|
const getConversationMutation = useGetConversationByIdMutation(conversationId);
|
|
const { data: config } = useGetStartupConfig();
|
|
|
|
useEffect(() => {
|
|
let timeout = setTimeout(() => {
|
|
if (!isAuthenticated) {
|
|
navigate('/login', { replace: true });
|
|
}
|
|
}, 300)
|
|
|
|
return () => {
|
|
clearTimeout(timeout);
|
|
}
|
|
}, [isAuthenticated, navigate]);
|
|
|
|
useEffect(() => {
|
|
if (!isSubmitting && !shouldNavigate) {
|
|
setShouldNavigate(true);
|
|
}
|
|
}, [shouldNavigate, isSubmitting]);
|
|
|
|
// when conversation changed or conversationId (in url) changed
|
|
useEffect(() => {
|
|
// No current conversation and conversationId is 'new'
|
|
if (conversation === null && conversationId === 'new') {
|
|
newConversation();
|
|
setShouldNavigate(true);
|
|
}
|
|
// No current conversation and conversationId exists
|
|
else if (conversation === null && conversationId) {
|
|
getConversationMutation.mutate(conversationId, {
|
|
onSuccess: (data) => {
|
|
console.log('Conversation fetched successfully');
|
|
setConversation(data);
|
|
setShouldNavigate(true);
|
|
},
|
|
onError: (error) => {
|
|
console.error('Failed to fetch the conversation');
|
|
console.error(error);
|
|
navigate('/chat/new');
|
|
newConversation();
|
|
setShouldNavigate(true);
|
|
}
|
|
});
|
|
setMessages(null);
|
|
}
|
|
// No current conversation and no conversationId
|
|
else if (conversation === null) {
|
|
navigate('/chat/new');
|
|
setShouldNavigate(true);
|
|
}
|
|
// Current conversationId is 'search'
|
|
else if (conversation?.conversationId === 'search') {
|
|
navigate(`/search/${searchQuery}`);
|
|
setShouldNavigate(true);
|
|
}
|
|
// Conversation change and isSubmitting
|
|
else if (conversation?.conversationId !== conversationId && isSubmitting) {
|
|
setShouldNavigate(false);
|
|
}
|
|
// conversationId (in url) should always follow conversation?.conversationId, unless conversation is null
|
|
else if (conversation?.conversationId !== conversationId) {
|
|
if (shouldNavigate) {
|
|
navigate(`/chat/${conversation?.conversationId}`);
|
|
} else {
|
|
setShouldNavigate(true);
|
|
}
|
|
}
|
|
document.title = conversation?.title || config?.appTitle || 'Chat';
|
|
}, [conversation, conversationId, config]);
|
|
|
|
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 (!isAuthenticated) {
|
|
return null;
|
|
}
|
|
|
|
// if not a conversation
|
|
if (conversation?.conversationId === 'search') return null;
|
|
// if conversationId not match
|
|
if (conversation?.conversationId !== conversationId && !conversation) return null;
|
|
// if conversationId is null
|
|
if (!conversationId) return null;
|
|
|
|
if (conversationId && !messagesTree) {
|
|
return (
|
|
<>
|
|
<Messages />
|
|
<TextChat />
|
|
</>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<>
|
|
{conversationId === 'new' && !messagesTree?.length ? <Landing /> : <Messages />}
|
|
<TextChat />
|
|
</>
|
|
);
|
|
}
|