From eebf7dcb2319a04c5600d1b25efc7822d24694e8 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Sun, 5 Jan 2025 09:01:56 -0500 Subject: [PATCH 01/11] chore: typing --- client/src/hooks/Chat/useChatHelpers.ts | 2 +- client/src/hooks/Messages/useMessageScrolling.ts | 2 +- client/src/store/families.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/hooks/Chat/useChatHelpers.ts b/client/src/hooks/Chat/useChatHelpers.ts index 2b03848bbd2..892a132194f 100644 --- a/client/src/hooks/Chat/useChatHelpers.ts +++ b/client/src/hooks/Chat/useChatHelpers.ts @@ -116,7 +116,7 @@ export default function useChatHelpers(index = 0, paramId?: string) { const handleRegenerate = (e: React.MouseEvent) => { e.preventDefault(); - const parentMessageId = latestMessage?.parentMessageId; + const parentMessageId = latestMessage?.parentMessageId ?? ''; if (!parentMessageId) { console.error('Failed to regenerate the message: parentMessageId not found.'); return; diff --git a/client/src/hooks/Messages/useMessageScrolling.ts b/client/src/hooks/Messages/useMessageScrolling.ts index ddb071ff869..1b0b98c8300 100644 --- a/client/src/hooks/Messages/useMessageScrolling.ts +++ b/client/src/hooks/Messages/useMessageScrolling.ts @@ -81,7 +81,7 @@ export default function useMessageScrolling(messagesTree?: TMessage[] | null) { } return () => { - if (abortScroll) { + if (abortScroll === true) { scrollToBottom && scrollToBottom.cancel(); } }; diff --git a/client/src/store/families.ts b/client/src/store/families.ts index 5c24b8d0fa3..bb71cd28461 100644 --- a/client/src/store/families.ts +++ b/client/src/store/families.ts @@ -141,7 +141,7 @@ const showStopButtonByIndex = atomFamily({ default: false, }); -const abortScrollFamily = atomFamily({ +const abortScrollFamily = atomFamily({ key: 'abortScrollByIndex', default: false, effects: [ From 67076a8e0cd55d4da192587ff1a234bbd4c8d4cd Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Sun, 5 Jan 2025 13:41:10 -0500 Subject: [PATCH 02/11] chore: typing --- client/src/components/Chat/Messages/MessagesView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/Chat/Messages/MessagesView.tsx b/client/src/components/Chat/Messages/MessagesView.tsx index 5f59f6d68f2..b6f863b9277 100644 --- a/client/src/components/Chat/Messages/MessagesView.tsx +++ b/client/src/components/Chat/Messages/MessagesView.tsx @@ -56,7 +56,7 @@ export default function MessagesView({ ) : ( <> - {Header && Header} + {Header != null && Header}
Date: Sun, 5 Jan 2025 13:41:45 -0500 Subject: [PATCH 03/11] fix: enhance message scrolling logic to handle empty messages tree and ref checks --- client/src/hooks/Messages/useMessageScrolling.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/client/src/hooks/Messages/useMessageScrolling.ts b/client/src/hooks/Messages/useMessageScrolling.ts index 1b0b98c8300..a9c033f2389 100644 --- a/client/src/hooks/Messages/useMessageScrolling.ts +++ b/client/src/hooks/Messages/useMessageScrolling.ts @@ -72,11 +72,15 @@ export default function useMessageScrolling(messagesTree?: TMessage[] | null) { }); useEffect(() => { - if (!messagesTree) { + if (!messagesTree || messagesTree.length === 0) { return; } - if (isSubmitting && scrollToBottom && !abortScroll) { + if (!messagesEndRef.current || !scrollableRef.current) { + return; + } + + if (isSubmitting && scrollToBottom && abortScroll !== true) { scrollToBottom(); } @@ -88,6 +92,10 @@ export default function useMessageScrolling(messagesTree?: TMessage[] | null) { }, [isSubmitting, messagesTree, scrollToBottom, abortScroll]); useEffect(() => { + if (!messagesEndRef.current || !scrollableRef.current) { + return; + } + if (scrollToBottom && autoScroll && conversationId !== Constants.NEW_CONVO) { scrollToBottom(); } From 81ef5a3c3f2c299bd3f985e87a912bb4aab6b8a3 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Sun, 5 Jan 2025 14:26:24 -0500 Subject: [PATCH 04/11] fix: optimize message selection logic with useCallback for better performance --- client/src/components/Chat/ChatView.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/client/src/components/Chat/ChatView.tsx b/client/src/components/Chat/ChatView.tsx index ecbc7909119..0ee64ef62b6 100644 --- a/client/src/components/Chat/ChatView.tsx +++ b/client/src/components/Chat/ChatView.tsx @@ -1,8 +1,9 @@ -import { memo } from 'react'; +import { memo, useCallback } from 'react'; import { useRecoilValue } from 'recoil'; import { useForm } from 'react-hook-form'; import { useParams } from 'react-router-dom'; import { useGetMessagesByConvoId } from 'librechat-data-provider/react-query'; +import type { TMessage } from 'librechat-data-provider'; import type { ChatFormValues } from '~/common'; import { ChatContext, AddedChatContext, useFileMapContext, ChatFormProvider } from '~/Providers'; import { useChatHelpers, useAddedResponse, useSSE } from '~/hooks'; @@ -24,10 +25,13 @@ function ChatView({ index = 0 }: { index?: number }) { const fileMap = useFileMapContext(); const { data: messagesTree = null, isLoading } = useGetMessagesByConvoId(conversationId ?? '', { - select: (data) => { - const dataTree = buildTree({ messages: data, fileMap }); - return dataTree?.length === 0 ? null : dataTree ?? null; - }, + select: useCallback( + (data: TMessage[]) => { + const dataTree = buildTree({ messages: data, fileMap }); + return dataTree?.length === 0 ? null : dataTree ?? null; + }, + [fileMap], + ), enabled: !!fileMap, }); From cacfb01e30b02ac4ad7b7a06746a09ba759569cb Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Sun, 5 Jan 2025 15:05:42 -0500 Subject: [PATCH 05/11] chore: typing --- client/src/components/Share/Message.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/Share/Message.tsx b/client/src/components/Share/Message.tsx index 9b72ede5aa1..85f60cbe78d 100644 --- a/client/src/components/Share/Message.tsx +++ b/client/src/components/Share/Message.tsx @@ -42,7 +42,7 @@ export default function Message(props: TMessageProps) { if (isCreatedByUser) { messageLabel = 'anonymous'; } else { - messageLabel = message.sender || ''; + messageLabel = message.sender ?? ''; } return ( From 6433f6d9cda05c5552a8d7403e9cb62565452909 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Sun, 5 Jan 2025 15:07:06 -0500 Subject: [PATCH 06/11] refactor: optimize icon rendering --- .../components/Chat/Messages/MessageIcon.tsx | 109 ++++++++---------- .../components/Chat/Messages/MessageParts.tsx | 32 +++-- .../Chat/Messages/SearchMessage.tsx | 17 ++- .../Chat/Messages/ui/MessageRender.tsx | 25 +++- .../src/components/Messages/ContentRender.tsx | 30 +++-- 5 files changed, 130 insertions(+), 83 deletions(-) diff --git a/client/src/components/Chat/Messages/MessageIcon.tsx b/client/src/components/Chat/Messages/MessageIcon.tsx index e4c06a4a1d9..1eab6d5fd09 100644 --- a/client/src/components/Chat/Messages/MessageIcon.tsx +++ b/client/src/components/Chat/Messages/MessageIcon.tsx @@ -1,84 +1,65 @@ import React, { useMemo, memo } from 'react'; import { useGetEndpointsQuery } from 'librechat-data-provider/react-query'; -import type { TMessage, TPreset, Assistant, Agent } from 'librechat-data-provider'; -import type { TMessageProps } from '~/common'; +import type { TPreset, Assistant, Agent, TMessage } from 'librechat-data-provider'; import ConvoIconURL from '~/components/Endpoints/ConvoIconURL'; import { getEndpointField, getIconEndpoint } from '~/utils'; import Icon from '~/components/Endpoints/Icon'; -const MessageIcon = memo( - ( - props: Pick & { - assistant?: Assistant; - agent?: Agent; - }, - ) => { - const { data: endpointsConfig } = useGetEndpointsQuery(); - const { message, conversation, assistant, agent } = props; +const MessageIcon = memo((props: { iconData?: TMessage; assistant?: Assistant; agent?: Agent }) => { + const { data: endpointsConfig } = useGetEndpointsQuery(); + const { iconData, assistant, agent } = props; - const assistantName = useMemo(() => assistant?.name ?? '', [assistant]); - const assistantAvatar = useMemo(() => assistant?.metadata?.avatar ?? '', [assistant]); - const agentName = useMemo(() => props.agent?.name ?? '', [props.agent]); - const agentAvatar = useMemo(() => props.agent?.avatar?.filepath ?? '', [props.agent]); - const isCreatedByUser = useMemo(() => message?.isCreatedByUser ?? false, [message]); + const assistantName = useMemo(() => assistant?.name ?? '', [assistant]); + const assistantAvatar = useMemo(() => assistant?.metadata?.avatar ?? '', [assistant]); + const agentName = useMemo(() => props.agent?.name ?? '', [props.agent]); + const agentAvatar = useMemo(() => props.agent?.avatar?.filepath ?? '', [props.agent]); + const isCreatedByUser = useMemo(() => iconData?.isCreatedByUser ?? false, [iconData]); - let avatarURL = ''; + let avatarURL = ''; - if (assistant) { - avatarURL = assistantAvatar; - } else if (agent) { - avatarURL = agentAvatar; - } + if (assistant) { + avatarURL = assistantAvatar; + } else if (agent) { + avatarURL = agentAvatar; + } - const messageSettings = useMemo( - () => ({ - ...(conversation ?? {}), - ...({ - ...(message ?? {}), - iconURL: message?.iconURL ?? '', - } as TMessage), - }), - [conversation, message], - ); - - const iconURL = messageSettings.iconURL; - const endpoint = useMemo( - () => getIconEndpoint({ endpointsConfig, iconURL, endpoint: messageSettings.endpoint }), - [endpointsConfig, iconURL, messageSettings.endpoint], - ); + const iconURL = iconData?.iconURL; + const endpoint = useMemo( + () => getIconEndpoint({ endpointsConfig, iconURL, endpoint: iconData?.endpoint }), + [endpointsConfig, iconURL, iconData?.endpoint], + ); - const endpointIconURL = useMemo( - () => getEndpointField(endpointsConfig, endpoint, 'iconURL'), - [endpointsConfig, endpoint], - ); - - if (isCreatedByUser !== true && iconURL != null && iconURL.includes('http')) { - return ( - - ); - } + const endpointIconURL = useMemo( + () => getEndpointField(endpointsConfig, endpoint, 'iconURL'), + [endpointsConfig, endpoint], + ); + if (isCreatedByUser !== true && iconURL != null && iconURL.includes('http')) { return ( - ); - }, -); + } + + return ( + + ); +}); MessageIcon.displayName = 'MessageIcon'; diff --git a/client/src/components/Chat/Messages/MessageParts.tsx b/client/src/components/Chat/Messages/MessageParts.tsx index 0e9d7cc40a9..48687ea1675 100644 --- a/client/src/components/Chat/Messages/MessageParts.tsx +++ b/client/src/components/Chat/Messages/MessageParts.tsx @@ -1,7 +1,8 @@ +import React, { useMemo } from 'react'; import { useRecoilValue } from 'recoil'; -import type { TMessageContentParts } from 'librechat-data-provider'; +import type { TMessage, TMessageContentParts } from 'librechat-data-provider'; import type { TMessageProps } from '~/common'; -import Icon from '~/components/Chat/Messages/MessageIcon'; +import MessageIcon from '~/components/Chat/Messages/MessageIcon'; import { useMessageHelpers, useLocalize } from '~/hooks'; import ContentParts from './Content/ContentParts'; import SiblingSwitch from './SiblingSwitch'; @@ -35,6 +36,26 @@ export default function Message(props: TMessageProps) { const fontSize = useRecoilValue(store.fontSize); const { children, messageId = null, isCreatedByUser } = message ?? {}; + const iconData = useMemo( + () => + ({ + endpoint: conversation?.endpoint, + model: conversation?.model ?? message?.model, + iconURL: conversation?.iconURL ?? message?.iconURL ?? '', + modelLabel: conversation?.chatGptLabel ?? conversation?.modelLabel, + isCreatedByUser: message?.isCreatedByUser, + } as TMessage & { modelLabel?: string }), + [ + conversation?.chatGptLabel, + conversation?.modelLabel, + conversation?.endpoint, + conversation?.iconURL, + conversation?.model, + message?.model, + message?.iconURL, + message?.isCreatedByUser, + ], + ); if (!message) { return null; } @@ -62,12 +83,7 @@ export default function Message(props: TMessageProps) {
- +
diff --git a/client/src/components/Chat/Messages/SearchMessage.tsx b/client/src/components/Chat/Messages/SearchMessage.tsx index c26d3bd07a3..b8714c9528c 100644 --- a/client/src/components/Chat/Messages/SearchMessage.tsx +++ b/client/src/components/Chat/Messages/SearchMessage.tsx @@ -1,5 +1,7 @@ +import { useMemo } from 'react'; import { useRecoilValue } from 'recoil'; import { useAuthContext, useLocalize } from '~/hooks'; +import type { TMessage } from 'librechat-data-provider'; import type { TMessageProps } from '~/common'; import MinimalHoverButtons from '~/components/Chat/Messages/MinimalHoverButtons'; import Icon from '~/components/Chat/Messages/MessageIcon'; @@ -15,6 +17,17 @@ export default function Message({ message }: Pick) { const { user } = useAuthContext(); const localize = useLocalize(); + const iconData = useMemo( + () => + ({ + endpoint: message?.endpoint, + model: message?.model, + iconURL: message?.iconURL ?? '', + isCreatedByUser: message?.isCreatedByUser, + } as TMessage & { modelLabel?: string }), + [message?.model, message?.iconURL, message?.endpoint, message?.isCreatedByUser], + ); + if (!message) { return null; } @@ -27,7 +40,7 @@ export default function Message({ message }: Pick) { ? (user?.name ?? '') || (user?.username ?? '') : localize('com_user_message'); } else { - messageLabel = message.sender || ''; + messageLabel = message.sender ?? ''; } return ( @@ -39,7 +52,7 @@ export default function Message({ message }: Pick) {
- +
diff --git a/client/src/components/Chat/Messages/ui/MessageRender.tsx b/client/src/components/Chat/Messages/ui/MessageRender.tsx index 85da9f9c6ce..532fe07f63f 100644 --- a/client/src/components/Chat/Messages/ui/MessageRender.tsx +++ b/client/src/components/Chat/Messages/ui/MessageRender.tsx @@ -6,7 +6,7 @@ import MessageContent from '~/components/Chat/Messages/Content/MessageContent'; import PlaceholderRow from '~/components/Chat/Messages/ui/PlaceholderRow'; import SiblingSwitch from '~/components/Chat/Messages/SiblingSwitch'; import HoverButtons from '~/components/Chat/Messages/HoverButtons'; -import Icon from '~/components/Chat/Messages/MessageIcon'; +import MessageIcon from '~/components/Chat/Messages/MessageIcon'; import { Plugin } from '~/components/Messages/Content'; import SubRow from '~/components/Chat/Messages/SubRow'; import { MessageContext } from '~/Providers'; @@ -66,6 +66,27 @@ const MessageRender = memo( [hasNoChildren, msg?.depth, latestMessage?.depth], ); + const iconData = useMemo( + () => + ({ + endpoint: conversation?.endpoint, + model: conversation?.model ?? msg?.model, + iconURL: conversation?.iconURL ?? msg?.iconURL ?? '', + modelLabel: conversation?.chatGptLabel ?? conversation?.modelLabel, + isCreatedByUser: msg?.isCreatedByUser, + } as TMessage & { modelLabel?: string }), + [ + conversation?.chatGptLabel, + conversation?.modelLabel, + conversation?.endpoint, + conversation?.iconURL, + conversation?.model, + msg?.model, + msg?.iconURL, + msg?.isCreatedByUser, + ], + ); + if (!msg) { return null; } @@ -125,7 +146,7 @@ const MessageRender = memo(
- +
diff --git a/client/src/components/Messages/ContentRender.tsx b/client/src/components/Messages/ContentRender.tsx index 5033b9a291f..923b66ab16d 100644 --- a/client/src/components/Messages/ContentRender.tsx +++ b/client/src/components/Messages/ContentRender.tsx @@ -6,7 +6,7 @@ import ContentParts from '~/components/Chat/Messages/Content/ContentParts'; import PlaceholderRow from '~/components/Chat/Messages/ui/PlaceholderRow'; import SiblingSwitch from '~/components/Chat/Messages/SiblingSwitch'; import HoverButtons from '~/components/Chat/Messages/HoverButtons'; -import Icon from '~/components/Chat/Messages/MessageIcon'; +import MessageIcon from '~/components/Chat/Messages/MessageIcon'; import SubRow from '~/components/Chat/Messages/SubRow'; import { useMessageActions } from '~/hooks'; import { cn, logger } from '~/utils'; @@ -65,6 +65,27 @@ const ContentRender = memo( [msg?.children, msg?.depth, latestMessage?.depth], ); + const iconData = useMemo( + () => + ({ + endpoint: conversation?.endpoint, + model: conversation?.model ?? msg?.model, + iconURL: conversation?.iconURL ?? msg?.iconURL ?? '', + modelLabel: conversation?.chatGptLabel ?? conversation?.modelLabel, + isCreatedByUser: msg?.isCreatedByUser, + } as TMessage & { modelLabel?: string }), + [ + conversation?.chatGptLabel, + conversation?.modelLabel, + conversation?.endpoint, + conversation?.iconURL, + conversation?.model, + msg?.model, + msg?.iconURL, + msg?.isCreatedByUser, + ], + ); + if (!msg) { return null; } @@ -109,12 +130,7 @@ const ContentRender = memo(
- +
From 81be3ef4eaf64dcaeb21c79872d2ba36a36427d6 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Sun, 5 Jan 2025 15:14:03 -0500 Subject: [PATCH 07/11] refactor: further optimize chat props --- .../components/Chat/Messages/MessageIcon.tsx | 97 ++++++++++--------- client/src/components/Endpoints/ConvoIcon.tsx | 3 +- .../src/components/Endpoints/ConvoIconURL.tsx | 10 +- .../src/components/Endpoints/EndpointIcon.tsx | 6 +- client/src/components/Nav/NewChat.tsx | 7 +- client/src/components/Share/MessageIcon.tsx | 13 +-- 6 files changed, 74 insertions(+), 62 deletions(-) diff --git a/client/src/components/Chat/Messages/MessageIcon.tsx b/client/src/components/Chat/Messages/MessageIcon.tsx index 1eab6d5fd09..6ab92af737a 100644 --- a/client/src/components/Chat/Messages/MessageIcon.tsx +++ b/client/src/components/Chat/Messages/MessageIcon.tsx @@ -1,65 +1,72 @@ import React, { useMemo, memo } from 'react'; import { useGetEndpointsQuery } from 'librechat-data-provider/react-query'; -import type { TPreset, Assistant, Agent, TMessage } from 'librechat-data-provider'; +import type { Assistant, Agent, TMessage } from 'librechat-data-provider'; import ConvoIconURL from '~/components/Endpoints/ConvoIconURL'; import { getEndpointField, getIconEndpoint } from '~/utils'; import Icon from '~/components/Endpoints/Icon'; -const MessageIcon = memo((props: { iconData?: TMessage; assistant?: Assistant; agent?: Agent }) => { - const { data: endpointsConfig } = useGetEndpointsQuery(); - const { iconData, assistant, agent } = props; +const MessageIcon = memo( + (props: { + iconData?: TMessage & { modelLabel?: string }; + assistant?: Assistant; + agent?: Agent; + }) => { + const { data: endpointsConfig } = useGetEndpointsQuery(); + const { iconData, assistant, agent } = props; - const assistantName = useMemo(() => assistant?.name ?? '', [assistant]); - const assistantAvatar = useMemo(() => assistant?.metadata?.avatar ?? '', [assistant]); - const agentName = useMemo(() => props.agent?.name ?? '', [props.agent]); - const agentAvatar = useMemo(() => props.agent?.avatar?.filepath ?? '', [props.agent]); - const isCreatedByUser = useMemo(() => iconData?.isCreatedByUser ?? false, [iconData]); + const assistantName = useMemo(() => assistant?.name ?? '', [assistant]); + const assistantAvatar = useMemo(() => assistant?.metadata?.avatar ?? '', [assistant]); + const agentName = useMemo(() => props.agent?.name ?? '', [props.agent]); + const agentAvatar = useMemo(() => props.agent?.avatar?.filepath ?? '', [props.agent]); + const isCreatedByUser = useMemo(() => iconData?.isCreatedByUser ?? false, [iconData]); - let avatarURL = ''; + let avatarURL = ''; - if (assistant) { - avatarURL = assistantAvatar; - } else if (agent) { - avatarURL = agentAvatar; - } + if (assistant) { + avatarURL = assistantAvatar; + } else if (agent) { + avatarURL = agentAvatar; + } - const iconURL = iconData?.iconURL; - const endpoint = useMemo( - () => getIconEndpoint({ endpointsConfig, iconURL, endpoint: iconData?.endpoint }), - [endpointsConfig, iconURL, iconData?.endpoint], - ); + const iconURL = iconData?.iconURL; + const endpoint = useMemo( + () => getIconEndpoint({ endpointsConfig, iconURL, endpoint: iconData?.endpoint }), + [endpointsConfig, iconURL, iconData?.endpoint], + ); + + const endpointIconURL = useMemo( + () => getEndpointField(endpointsConfig, endpoint, 'iconURL'), + [endpointsConfig, endpoint], + ); - const endpointIconURL = useMemo( - () => getEndpointField(endpointsConfig, endpoint, 'iconURL'), - [endpointsConfig, endpoint], - ); + if (isCreatedByUser !== true && iconURL != null && iconURL.includes('http')) { + return ( + + ); + } - if (isCreatedByUser !== true && iconURL != null && iconURL.includes('http')) { return ( - ); - } - - return ( - - ); -}); + }, +); MessageIcon.displayName = 'MessageIcon'; diff --git a/client/src/components/Endpoints/ConvoIcon.tsx b/client/src/components/Endpoints/ConvoIcon.tsx index 7e35a99ea62..9ecd7be39e1 100644 --- a/client/src/components/Endpoints/ConvoIcon.tsx +++ b/client/src/components/Endpoints/ConvoIcon.tsx @@ -52,7 +52,8 @@ export default function ConvoIcon({ <> {iconURL && iconURL.includes('http') ? ( = ({ - preset, + iconURL = '', + modelLabel = '', endpointIconURL, assistantAvatar, assistantName, @@ -37,7 +38,6 @@ const ConvoIconURL: React.FC = ({ agentName, context, }) => { - const { iconURL = '' } = preset ?? {}; let Icon: ( props: IconMapProps & { context?: string; @@ -57,7 +57,7 @@ const ConvoIconURL: React.FC = ({ > {preset?.chatGptLabel diff --git a/client/src/components/Endpoints/EndpointIcon.tsx b/client/src/components/Endpoints/EndpointIcon.tsx index caa6fe6ede2..b727b28bf8b 100644 --- a/client/src/components/Endpoints/EndpointIcon.tsx +++ b/client/src/components/Endpoints/EndpointIcon.tsx @@ -42,10 +42,8 @@ export default function EndpointIcon({ if (iconURL && (iconURL.includes('http') || iconURL.startsWith('/images/'))) { return ( {iconURL && iconURL.includes('http') ? ( - + ) : (
{endpoint && Icon != null && ( diff --git a/client/src/components/Share/MessageIcon.tsx b/client/src/components/Share/MessageIcon.tsx index e4c1b9dca86..66bb7b74f9c 100644 --- a/client/src/components/Share/MessageIcon.tsx +++ b/client/src/components/Share/MessageIcon.tsx @@ -30,14 +30,15 @@ export default function MessageIcon( [conversation, message], ); - const iconURL = messageSettings?.iconURL; - let endpoint = messageSettings?.endpoint; + const iconURL = messageSettings.iconURL ?? ''; + let endpoint = messageSettings.endpoint; endpoint = getIconEndpoint({ endpointsConfig: undefined, iconURL, endpoint }); - if (!message?.isCreatedByUser && iconURL && iconURL.includes('http')) { + if (message?.isCreatedByUser !== true && iconURL && iconURL.includes('http')) { return ( Date: Sun, 5 Jan 2025 15:26:49 -0500 Subject: [PATCH 08/11] fix: remove unnecessary console log in useQueryParams cleanup --- client/src/hooks/Input/useQueryParams.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/hooks/Input/useQueryParams.ts b/client/src/hooks/Input/useQueryParams.ts index ecca0ec8f28..072a5b74e92 100644 --- a/client/src/hooks/Input/useQueryParams.ts +++ b/client/src/hooks/Input/useQueryParams.ts @@ -207,7 +207,6 @@ export default function useQueryParams({ return () => { clearInterval(intervalId); - console.log('Cleanup: `useQueryParams` interval cleared'); }; }, [searchParams, methods, textAreaRef, newQueryConvo, newConversation]); } From 91b4a90afcaadb5522912c9b902b56d2596c2e84 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Sun, 5 Jan 2025 15:29:42 -0500 Subject: [PATCH 09/11] refactor: add queryClient to reset message data on new conversation initiation --- client/src/components/Nav/NewChat.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/client/src/components/Nav/NewChat.tsx b/client/src/components/Nav/NewChat.tsx index d9dd50a9c77..470a9726375 100644 --- a/client/src/components/Nav/NewChat.tsx +++ b/client/src/components/Nav/NewChat.tsx @@ -1,8 +1,10 @@ import { Search } from 'lucide-react'; import { useRecoilValue } from 'recoil'; import { useNavigate } from 'react-router-dom'; +import { useQueryClient } from '@tanstack/react-query'; +import { QueryKeys, Constants } from 'librechat-data-provider'; import { useGetEndpointsQuery } from 'librechat-data-provider/react-query'; -import type { TConversation } from 'librechat-data-provider'; +import type { TConversation, TMessage } from 'librechat-data-provider'; import { getEndpointField, getIconEndpoint, getIconKey } from '~/utils'; import { icons } from '~/components/Chat/Menus/Endpoints/Icons'; import ConvoIconURL from '~/components/Endpoints/ConvoIconURL'; @@ -70,6 +72,7 @@ export default function NewChat({ subHeaders?: React.ReactNode; isSmallScreen: boolean; }) { + const queryClient = useQueryClient(); /** Note: this component needs an explicit index passed if using more than one */ const { newConversation: newConvo } = useNewConvo(index); const navigate = useNavigate(); @@ -80,6 +83,10 @@ export default function NewChat({ const clickHandler = (event: React.MouseEvent) => { if (event.button === 0 && !(event.ctrlKey || event.metaKey)) { event.preventDefault(); + queryClient.setQueryData( + [QueryKeys.messages, conversation?.conversationId ?? Constants.NEW_CONVO], + [], + ); newConvo(); navigate('/c/new'); toggleNav(); From 43a93015490f4470ad81480911facfa26265448d Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Sun, 5 Jan 2025 16:34:38 -0500 Subject: [PATCH 10/11] refactor: update data-testid attributes for consistency and improve code readability --- client/src/components/Chat/Menus/HeaderNewChat.tsx | 4 ++-- client/src/components/Chat/Messages/MessageIcon.tsx | 5 ++--- client/src/components/Nav/NewChat.tsx | 2 +- e2e/specs/messages.spec.ts | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/client/src/components/Chat/Menus/HeaderNewChat.tsx b/client/src/components/Chat/Menus/HeaderNewChat.tsx index 5a9fc403a7d..200e73d17e4 100644 --- a/client/src/components/Chat/Menus/HeaderNewChat.tsx +++ b/client/src/components/Chat/Menus/HeaderNewChat.tsx @@ -12,9 +12,9 @@ export default function HeaderNewChat() { return (

- {title || localize('com_ui_new_chat')} + {title ?? localize('com_ui_new_chat')}