mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-02-26 12:24:10 +01:00
fix(Chat.jsx): Improve Message Creation UX by Eliminating Screen Flicker (#577)
* fix(Chat.jsx): conversation no longer navigates upon message creation, which would cause re-render/flicker * chore(.gitignore): ignore storageState.json in all directories chore(storageState.json): delete e2e/storageState.json file * test(e2e): fix old tests with new playwright setup & add helper script for codegen * fix(Conversation.jsx): add data-testid attribute to <a> element test(messages.spec.js): add test for expected navigation after receiving message test(messages.spec.js): add test for page navigations * chore(Plugin.jsx): import Spinner from '~/components' instead of '../svg/Spinner' chore(index.jsx): import Spinner from '~/components' instead of '../svg/Spinner' chore(Spinner.jsx): change classProp prop to className prop in Spinner component feat(index.ts): export Spinner component from './Spinner'
This commit is contained in:
parent
6b843429c5
commit
88683b9cc5
13 changed files with 108 additions and 67 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
|
||||
|
|
@ -14,10 +14,12 @@ import {
|
|||
} from '~/data-provider';
|
||||
|
||||
export default function Chat() {
|
||||
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();
|
||||
|
|
@ -27,36 +29,58 @@ export default function Chat() {
|
|||
const getConversationMutation = useGetConversationByIdMutation(conversationId);
|
||||
const { data: config } = useGetStartupConfig();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isSubmitting && !shouldNavigate) {
|
||||
setShouldNavigate(true);
|
||||
}
|
||||
}, [shouldNavigate, isSubmitting]);
|
||||
|
||||
// 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 (conversationId) {
|
||||
// fetch it from server
|
||||
getConversationMutation.mutate(conversationId, {
|
||||
onSuccess: (data) => {
|
||||
setConversation(data);
|
||||
},
|
||||
onError: (error) => {
|
||||
console.error('failed to fetch the conversation');
|
||||
console.error(error);
|
||||
navigate(`/chat/new`);
|
||||
newConversation();
|
||||
}
|
||||
});
|
||||
setMessages(null);
|
||||
} else {
|
||||
navigate(`/chat/new`);
|
||||
}
|
||||
} else if (conversation?.conversationId === 'search') {
|
||||
// jump to search page
|
||||
// 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}`);
|
||||
} else if (conversation?.conversationId !== conversationId) {
|
||||
// conversationId (in url) should always follow conversation?.conversationId, unless conversation is null
|
||||
navigate(`/chat/${conversation?.conversationId}`);
|
||||
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]);
|
||||
|
|
@ -80,10 +104,19 @@ export default function Chat() {
|
|||
// if not a conversation
|
||||
if (conversation?.conversationId === 'search') return null;
|
||||
// if conversationId not match
|
||||
if (conversation?.conversationId !== conversationId) return null;
|
||||
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 />}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue