From e349f885b60b9951b49b3291ede88053de7a5f23 Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Sat, 20 Dec 2025 23:44:53 +0200 Subject: [PATCH] refactor(chat): update user message layout and styling --- .../ui/src/components/chat/ChatMessage.tsx | 60 ++++---- .../components/chat/message/MessageBody.tsx | 145 ++++++++---------- .../chat/message/parts/UserTextPart.tsx | 13 +- 3 files changed, 106 insertions(+), 112 deletions(-) diff --git a/packages/ui/src/components/chat/ChatMessage.tsx b/packages/ui/src/components/chat/ChatMessage.tsx index 9c415c4e..4fb07dda 100644 --- a/packages/ui/src/components/chat/ChatMessage.tsx +++ b/packages/ui/src/components/chat/ChatMessage.tsx @@ -706,39 +706,33 @@ const ChatMessage: React.FC = ({
{isUser ? ( -
- - +
+
+ +
) : ( diff --git a/packages/ui/src/components/chat/message/MessageBody.tsx b/packages/ui/src/components/chat/message/MessageBody.tsx index faa5fe89..d7691973 100644 --- a/packages/ui/src/components/chat/message/MessageBody.tsx +++ b/packages/ui/src/components/chat/message/MessageBody.tsx @@ -208,68 +208,60 @@ const UserMessageBody: React.FC<{ style={{ contain: 'layout', transform: 'translateZ(0)' }} onTouchStart={isTouchContext && canCopyMessage && hasCopyableText ? revealCopyHint : undefined} > - {canCopyMessage && ( - - )} -
-
- {textParts.map((part, index) => { - let mentionForPart: AgentMentionInfo | undefined; - if (agentMention && mentionToken && !mentionInjected) { - const candidateText = extractTextContent(part); - if (candidateText.includes(mentionToken)) { - mentionForPart = agentMention; - mentionInjected = true; - } - } - return ( - - - - ); - })} -
- + } + return ( + + + + ); + })}
+ + {canCopyMessage && hasCopyableText && ( +
+ + + + + Copy message + +
+ )}
); }; @@ -1075,6 +1067,21 @@ const AssistantMessageBody: React.FC> = ({ const footerButtons = ( <> + + + + + Start new session from this answer + {onCopyMessage && ( @@ -1085,8 +1092,7 @@ const AssistantMessageBody: React.FC> = ({ data-visible={copyHintVisible || isMessageCopied ? 'true' : undefined} className={cn( 'h-8 w-8 text-muted-foreground bg-transparent hover:text-foreground hover:!bg-transparent active:!bg-transparent focus-visible:!bg-transparent focus-visible:ring-2 focus-visible:ring-primary/50', - !hasCopyableText && 'opacity-50', - (copyHintVisible || isMessageCopied) && 'text-primary' + !hasCopyableText && 'opacity-50' )} disabled={!hasCopyableText} aria-label="Copy message text" @@ -1114,21 +1120,6 @@ const AssistantMessageBody: React.FC> = ({ Copy answer )} - - - - - Start new session from this answer - ); diff --git a/packages/ui/src/components/chat/message/parts/UserTextPart.tsx b/packages/ui/src/components/chat/message/parts/UserTextPart.tsx index 7fddc2d0..479dd56d 100644 --- a/packages/ui/src/components/chat/message/parts/UserTextPart.tsx +++ b/packages/ui/src/components/chat/message/parts/UserTextPart.tsx @@ -29,9 +29,18 @@ const UserTextPart: React.FC = ({ part, messageId, agentMenti React.useEffect(() => { const el = textRef.current; - if (el && !isExpanded) { + if (!el || isExpanded) return; + + const checkTruncation = () => { setIsTruncated(el.scrollHeight > el.clientHeight); - } + }; + + checkTruncation(); + + const resizeObserver = new ResizeObserver(checkTruncation); + resizeObserver.observe(el); + + return () => resizeObserver.disconnect(); }, [textContent, isExpanded]); const handleClick = React.useCallback(() => {