refactor(chat): add footer buttons and adjust summary display
This commit is contained in:
@@ -327,6 +327,7 @@ const AssistantMessageBody: React.FC<Omit<MessageBodyProps, 'isUser'>> = ({
|
|||||||
return parts.some((part) => part.type === 'step-finish' && (part as { reason?: string | null | undefined }).reason === 'stop');
|
return parts.some((part) => part.type === 'step-finish' && (part as { reason?: string | null | undefined }).reason === 'stop');
|
||||||
}, [parts]);
|
}, [parts]);
|
||||||
|
|
||||||
|
|
||||||
const hasTools = toolParts.length > 0;
|
const hasTools = toolParts.length > 0;
|
||||||
|
|
||||||
const hasPendingTools = React.useMemo(() => {
|
const hasPendingTools = React.useMemo(() => {
|
||||||
@@ -961,39 +962,15 @@ const AssistantMessageBody: React.FC<Omit<MessageBodyProps, 'isUser'>> = ({
|
|||||||
const summaryBody = summaryBodyRef.current;
|
const summaryBody = summaryBodyRef.current;
|
||||||
|
|
||||||
const showSummaryBody =
|
const showSummaryBody =
|
||||||
turnGroupingContext?.isFirstAssistantInTurn &&
|
turnGroupingContext?.isLastAssistantInTurn &&
|
||||||
summaryBody &&
|
summaryBody &&
|
||||||
summaryBody.trim().length > 0;
|
summaryBody.trim().length > 0;
|
||||||
|
|
||||||
const shouldShowFooter = hasTextContent && assistantTextParts.length > 0 && hasStopFinish && isLastAssistantInTurn;
|
const shouldShowFooter = hasTextContent && assistantTextParts.length > 0 && hasStopFinish && isLastAssistantInTurn;
|
||||||
|
const [isSummaryHovered, setIsSummaryHovered] = React.useState(false);
|
||||||
|
|
||||||
return (
|
const footerButtons = (
|
||||||
<div
|
<>
|
||||||
className={cn(
|
|
||||||
'relative w-full group/message'
|
|
||||||
)}
|
|
||||||
style={{
|
|
||||||
contain: 'layout',
|
|
||||||
transform: 'translateZ(0)',
|
|
||||||
}}
|
|
||||||
onTouchStart={isTouchContext && canCopyMessage && hasCopyableText ? revealCopyHint : undefined}
|
|
||||||
>
|
|
||||||
<div className="px-3">
|
|
||||||
<div className="leading-normal overflow-hidden text-foreground/90 [&_p:last-child]:mb-0 [&_ul:last-child]:mb-0 [&_ol:last-child]:mb-0">
|
|
||||||
{renderedParts}
|
|
||||||
{showSummaryBody && (
|
|
||||||
<FadeInOnReveal key="summary-body">
|
|
||||||
<div className="group/assistant-text relative break-words">
|
|
||||||
<SimpleMarkdownRenderer
|
|
||||||
content={summaryBody}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</FadeInOnReveal>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<MessageFilesDisplay files={parts} onShowPopup={onShowPopup} />
|
|
||||||
{shouldShowFooter && (
|
|
||||||
<div className="mt-2 mb-1 flex items-center justify-end gap-2">
|
|
||||||
{onCopyMessage && (
|
{onCopyMessage && (
|
||||||
<Tooltip delayDuration={1000}>
|
<Tooltip delayDuration={1000}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
@@ -1048,9 +1025,58 @@ const AssistantMessageBody: React.FC<Omit<MessageBodyProps, 'isUser'>> = ({
|
|||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={6}>Start new session from this answer</TooltipContent>
|
<TooltipContent sideOffset={6}>Start new session from this answer</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'relative w-full group/message'
|
||||||
|
)}
|
||||||
|
style={{
|
||||||
|
contain: 'layout',
|
||||||
|
transform: 'translateZ(0)',
|
||||||
|
}}
|
||||||
|
onTouchStart={isTouchContext && canCopyMessage && hasCopyableText ? revealCopyHint : undefined}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="px-3"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="leading-normal overflow-hidden text-foreground/90 [&_p:last-child]:mb-0 [&_ul:last-child]:mb-0 [&_ol:last-child]:mb-0"
|
||||||
|
>
|
||||||
|
{renderedParts}
|
||||||
|
{showSummaryBody && (
|
||||||
|
<FadeInOnReveal key="summary-body">
|
||||||
|
<div
|
||||||
|
className="group/assistant-text relative break-words"
|
||||||
|
onMouseEnter={() => setIsSummaryHovered(true)}
|
||||||
|
onMouseLeave={() => setIsSummaryHovered(false)}
|
||||||
|
>
|
||||||
|
<SimpleMarkdownRenderer content={summaryBody} />
|
||||||
|
{shouldShowFooter && (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"mt-2 mb-1 flex items-center justify-end gap-2 opacity-0 pointer-events-none transition-opacity duration-150 focus-within:opacity-100 focus-within:pointer-events-auto",
|
||||||
|
isSummaryHovered && "opacity-100 pointer-events-auto",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{footerButtons}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
</FadeInOnReveal>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<MessageFilesDisplay files={parts} onShowPopup={onShowPopup} />
|
||||||
|
{!showSummaryBody && shouldShowFooter && (
|
||||||
|
<div className="mt-2 mb-1 flex items-center justify-end gap-2 opacity-0 pointer-events-none transition-opacity duration-150 group-hover/message:opacity-100 group-hover/message:pointer-events-auto focus-within:opacity-100 focus-within:pointer-events-auto">
|
||||||
|
{footerButtons}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user