import React, { useCallback, useMemo } from 'react'; import { useMessageProcess, useMessageActions } from '~/hooks'; import type { TMessage } from 'librechat-data-provider'; 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'; // 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 }) => { return (
{children}
); }, ); 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, conversation, handleScroll, siblingMessage, latestMultiMessage, isSubmittingFamily, } = useMessageProcess({ message: props.message }); const { message, currentEditId, setCurrentEditId } = props; if (!message) { return null; } const { children, messageId = null } = message ?? {}; return ( <> {showSibling ? (
) : (
)}
); }