From ed5ee1f86f8df754636fa31b1ab50bb653596b55 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Thu, 27 Jun 2024 10:48:41 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20refactor:=20Reduce=20Complexity?= =?UTF-8?q?=20of=20Initial=20Load=20Effect=20&=20Message=20Styling=20(#321?= =?UTF-8?q?3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * move shared conditions and early bail to reduce cognitive complexity, improve readability * refactor: make condition as close to the original as possible * chore: adjust comment in chat route * style: fix original styling of non-multi messages * refactor: separate messagerender logic from 'Message' --------- Co-authored-by: RehaS --- .../src/components/Chat/Messages/Message.tsx | 162 +----------------- .../Chat/Messages/ui/MessageRender.tsx | 154 +++++++++++++++++ .../Chat/Messages/ui/PlaceholderRow.tsx | 13 ++ client/src/routes/ChatRoute.tsx | 31 +--- 4 files changed, 179 insertions(+), 181 deletions(-) create mode 100644 client/src/components/Chat/Messages/ui/MessageRender.tsx create mode 100644 client/src/components/Chat/Messages/ui/PlaceholderRow.tsx diff --git a/client/src/components/Chat/Messages/Message.tsx b/client/src/components/Chat/Messages/Message.tsx index fc52a89584..fb8babdd34 100644 --- a/client/src/components/Chat/Messages/Message.tsx +++ b/client/src/components/Chat/Messages/Message.tsx @@ -1,16 +1,9 @@ -import React, { useCallback, useMemo } from 'react'; -import { useMessageProcess, useMessageActions } from '~/hooks'; -import type { TMessage } from 'librechat-data-provider'; +import React from 'react'; +import { useMessageProcess } from '~/hooks'; import type { TMessageProps } from '~/common'; -import Icon from '~/components/Chat/Messages/MessageIcon'; -import { Plugin } from '~/components/Messages/Content'; -import MessageContent from './Content/MessageContent'; -import SiblingSwitch from './SiblingSwitch'; +import MessageRender from './ui/MessageRender'; // eslint-disable-next-line import/no-cycle import MultiMessage from './MultiMessage'; -import HoverButtons from './HoverButtons'; -import SubRow from './SubRow'; -import { cn } from '~/utils'; const MessageContainer = React.memo( ({ handleScroll, children }: { handleScroll: () => void; children: React.ReactNode }) => { @@ -26,155 +19,6 @@ const MessageContainer = React.memo( }, ); -const PlaceholderRow = React.memo(({ isLast, isCard }: { isLast: boolean; isCard?: boolean }) => { - if (!isCard) { - return null; - } - if (!isLast) { - return null; - } - return
; -}); - -type MessageRenderProps = { - message?: TMessage; - isCard?: boolean; - isMultiMessage?: boolean; - isSubmittingFamily?: boolean; -} & Pick< - TMessageProps, - 'currentEditId' | 'setCurrentEditId' | 'siblingIdx' | 'setSiblingIdx' | 'siblingCount' ->; - -const MessageRender = React.memo( - ({ - isCard, - siblingIdx, - siblingCount, - message: msg, - setSiblingIdx, - currentEditId, - isMultiMessage, - setCurrentEditId, - isSubmittingFamily, - }: MessageRenderProps) => { - const { - ask, - edit, - index, - assistant, - enterEdit, - conversation, - messageLabel, - isSubmitting, - latestMessage, - handleContinue, - copyToClipboard, - setLatestMessage, - regenerateMessage, - } = useMessageActions({ - message: msg, - currentEditId, - isMultiMessage, - setCurrentEditId, - }); - - const handleRegenerateMessage = useCallback(() => regenerateMessage(), [regenerateMessage]); - const { isCreatedByUser, error, unfinished } = msg ?? {}; - const isLast = useMemo( - () => !msg?.children?.length && (msg?.depth === latestMessage?.depth || msg?.depth === -1), - [msg?.children, msg?.depth, latestMessage?.depth], - ); - - if (!msg) { - return null; - } - - const isLatest = isCard && !isSubmittingFamily && msg.messageId === latestMessage?.messageId; - const clickHandler = - isLast && isCard && !isSubmittingFamily && msg.messageId !== latestMessage?.messageId - ? () => setLatestMessage(msg) - : undefined; - - return ( -
- {isLatest && ( -
- )} -
-
-
-
- -
-
-
-
-
-
{messageLabel}
-
-
- {msg?.plugin && } - ({}))} - /> -
-
- {!msg?.children?.length && (isSubmittingFamily || isSubmitting) ? ( - - ) : ( - - - - - )} -
-
- ); - }, -); - export default function Message(props: TMessageProps) { const { showSibling, diff --git a/client/src/components/Chat/Messages/ui/MessageRender.tsx b/client/src/components/Chat/Messages/ui/MessageRender.tsx new file mode 100644 index 0000000000..c78066c53d --- /dev/null +++ b/client/src/components/Chat/Messages/ui/MessageRender.tsx @@ -0,0 +1,154 @@ +import React, { useCallback, useMemo } from 'react'; +import { useMessageActions } from '~/hooks'; +import type { TMessage } from 'librechat-data-provider'; +import type { TMessageProps } from '~/common'; +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 { Plugin } from '~/components/Messages/Content'; +import SubRow from '~/components/Chat/Messages/SubRow'; +import { cn } from '~/utils'; + +type MessageRenderProps = { + message?: TMessage; + isCard?: boolean; + isMultiMessage?: boolean; + isSubmittingFamily?: boolean; +} & Pick< + TMessageProps, + 'currentEditId' | 'setCurrentEditId' | 'siblingIdx' | 'setSiblingIdx' | 'siblingCount' +>; + +const MessageRender = React.memo( + ({ + isCard, + siblingIdx, + siblingCount, + message: msg, + setSiblingIdx, + currentEditId, + isMultiMessage, + setCurrentEditId, + isSubmittingFamily, + }: MessageRenderProps) => { + const { + ask, + edit, + index, + assistant, + enterEdit, + conversation, + messageLabel, + isSubmitting, + latestMessage, + handleContinue, + copyToClipboard, + setLatestMessage, + regenerateMessage, + } = useMessageActions({ + message: msg, + currentEditId, + isMultiMessage, + setCurrentEditId, + }); + + const handleRegenerateMessage = useCallback(() => regenerateMessage(), [regenerateMessage]); + const { isCreatedByUser, error, unfinished } = msg ?? {}; + const isLast = useMemo( + () => !msg?.children?.length && (msg?.depth === latestMessage?.depth || msg?.depth === -1), + [msg?.children, msg?.depth, latestMessage?.depth], + ); + + if (!msg) { + return null; + } + + const isLatestCard = + isCard && !isSubmittingFamily && msg.messageId === latestMessage?.messageId; + const clickHandler = + isLast && isCard && !isSubmittingFamily && msg.messageId !== latestMessage?.messageId + ? () => setLatestMessage(msg) + : undefined; + + return ( +
+ {isLatestCard && ( +
+ )} +
+
+
+
+ +
+
+
+
+
+
{messageLabel}
+
+
+ {msg?.plugin && } + ({}))} + /> +
+
+ {!msg?.children?.length && (isSubmittingFamily || isSubmitting) ? ( + + ) : ( + + + + + )} +
+
+ ); + }, +); + +export default MessageRender; diff --git a/client/src/components/Chat/Messages/ui/PlaceholderRow.tsx b/client/src/components/Chat/Messages/ui/PlaceholderRow.tsx new file mode 100644 index 0000000000..1c3d17de81 --- /dev/null +++ b/client/src/components/Chat/Messages/ui/PlaceholderRow.tsx @@ -0,0 +1,13 @@ +import { memo } from 'react'; + +const PlaceholderRow = memo(({ isLast, isCard }: { isLast: boolean; isCard?: boolean }) => { + if (!isCard) { + return null; + } + if (!isLast) { + return null; + } + return
; +}); + +export default PlaceholderRow; diff --git a/client/src/routes/ChatRoute.tsx b/client/src/routes/ChatRoute.tsx index 3f9e0a5024..ad933efd61 100644 --- a/client/src/routes/ChatRoute.tsx +++ b/client/src/routes/ChatRoute.tsx @@ -38,14 +38,14 @@ export default function ChatRoute() { const assistantListMap = useAssistantListMap(); useEffect(() => { - if ( - startupConfig && - conversationId === 'new' && - endpointsQuery.data && - modelsQuery.data && - !modelsQuery.data?.initial && - !hasSetConversation.current - ) { + const shouldSetConvo = + startupConfig && !hasSetConversation.current && !modelsQuery.data?.initial; + /* Early exit if startupConfig is not loaded and conversation is already set and only initial models have loaded */ + if (!shouldSetConvo) { + return; + } + + if (conversationId === 'new' && endpointsQuery.data && modelsQuery.data) { const spec = getDefaultModelSpec(startupConfig.modelSpecs?.list); newConversation({ @@ -63,14 +63,7 @@ export default function ChatRoute() { }); hasSetConversation.current = true; - } else if ( - startupConfig && - initialConvoQuery.data && - endpointsQuery.data && - modelsQuery.data && - !modelsQuery.data?.initial && - !hasSetConversation.current - ) { + } else if (initialConvoQuery.data && endpointsQuery.data && modelsQuery.data) { newConversation({ template: initialConvoQuery.data, /* this is necessary to load all existing settings */ @@ -80,9 +73,6 @@ export default function ChatRoute() { }); hasSetConversation.current = true; } else if ( - startupConfig && - !hasSetConversation.current && - !modelsQuery.data?.initial && conversationId === 'new' && assistantListMap[EModelEndpoint.assistants] && assistantListMap[EModelEndpoint.azureAssistants] @@ -103,9 +93,6 @@ export default function ChatRoute() { }); hasSetConversation.current = true; } else if ( - startupConfig && - !hasSetConversation.current && - !modelsQuery.data?.initial && assistantListMap[EModelEndpoint.assistants] && assistantListMap[EModelEndpoint.azureAssistants] ) {