import { memo, useCallback } from 'react';
import { useRecoilValue } from 'recoil';
import { useForm } from 'react-hook-form';
import { Spinner } from '@librechat/client';
import { useParams } from 'react-router-dom';
import { Constants, buildTree } from 'librechat-data-provider';
import type { TMessage } from 'librechat-data-provider';
import type { ChatFormValues } from '~/common';
import { ChatContext, AddedChatContext, useFileMapContext, ChatFormProvider } from '~/Providers';
import { useChatHelpers, useAddedResponse, useAdaptiveSSE, useResumeOnLoad } from '~/hooks';
import ConversationStarters from './Input/ConversationStarters';
import { useGetMessagesByConvoId } from '~/data-provider';
import MessagesView from './Messages/MessagesView';
import Presentation from './Presentation';
import ChatForm from './Input/ChatForm';
import Landing from './Landing';
import Header from './Header';
import Footer from './Footer';
import { cn } from '~/utils';
import store from '~/store';
function LoadingSpinner() {
return (
);
}
function ChatView({ index = 0 }: { index?: number }) {
const { conversationId } = useParams();
const rootSubmission = useRecoilValue(store.submissionByIndex(index));
const addedSubmission = useRecoilValue(store.submissionByIndex(index + 1));
const centerFormOnLanding = useRecoilValue(store.centerFormOnLanding);
const fileMap = useFileMapContext();
const { data: messagesTree = null, isLoading } = useGetMessagesByConvoId(conversationId ?? '', {
select: useCallback(
(data: TMessage[]) => {
const dataTree = buildTree({ messages: data, fileMap });
return dataTree?.length === 0 ? null : (dataTree ?? null);
},
[fileMap],
),
enabled: !!fileMap,
});
const chatHelpers = useChatHelpers(index, conversationId);
const addedChatHelpers = useAddedResponse({ rootIndex: index });
useAdaptiveSSE(rootSubmission, chatHelpers, false, index);
useAdaptiveSSE(addedSubmission, addedChatHelpers, true, index + 1);
// Auto-resume if navigating back to conversation with active job
useResumeOnLoad(conversationId, chatHelpers.getMessages, index);
const methods = useForm({
defaultValues: { text: '' },
});
let content: JSX.Element | null | undefined;
const isLandingPage =
(!messagesTree || messagesTree.length === 0) &&
(conversationId === Constants.NEW_CONVO || !conversationId);
const isNavigating = (!messagesTree || messagesTree.length === 0) && conversationId != null;
if (isLoading && conversationId !== Constants.NEW_CONVO) {
content = ;
} else if ((isLoading || isNavigating) && !isLandingPage) {
content = ;
} else if (!isLandingPage) {
content = ;
} else {
content = ;
}
return (
{!isLoading &&
}
<>
{content}
{isLandingPage ? : }
{isLandingPage &&
}
>
);
}
export default memo(ChatView);