feat(chat): show revert button on all user messages

Remove restriction preventing revert on first user message
Simplify message props by removing isFirstMessage flag
This commit is contained in:
Bohdan Triapitsyn
2026-01-02 19:54:16 +02:00
parent ad0439da39
commit dca8be01ca
3 changed files with 16 additions and 29 deletions
@@ -66,7 +66,6 @@ interface ChatMessageProps {
scrollToBottom?: (options?: { instant?: boolean; force?: boolean }) => void; scrollToBottom?: (options?: { instant?: boolean; force?: boolean }) => void;
isPendingAnchor?: boolean; isPendingAnchor?: boolean;
turnGroupingContext?: TurnGroupingContext; turnGroupingContext?: TurnGroupingContext;
isFirstMessage?: boolean;
} }
const ChatMessage: React.FC<ChatMessageProps> = ({ const ChatMessage: React.FC<ChatMessageProps> = ({
@@ -77,7 +76,6 @@ const ChatMessage: React.FC<ChatMessageProps> = ({
animationHandlers, animationHandlers,
isPendingAnchor = false, isPendingAnchor = false,
turnGroupingContext, turnGroupingContext,
isFirstMessage = false,
}) => { }) => {
const { isMobile, hasTouchInput } = useDeviceInfo(); const { isMobile, hasTouchInput } = useDeviceInfo();
const { currentTheme } = useThemeSystem(); const { currentTheme } = useThemeSystem();
@@ -790,7 +788,6 @@ const ChatMessage: React.FC<ChatMessageProps> = ({
onAuxiliaryContentComplete={handleAuxiliaryContentComplete} onAuxiliaryContentComplete={handleAuxiliaryContentComplete}
agentMention={agentMention} agentMention={agentMention}
onRevert={handleRevert} onRevert={handleRevert}
isFirstMessage={isFirstMessage}
errorMessage={assistantErrorText} errorMessage={assistantErrorText}
/> />
</div> </div>
+13 -20
View File
@@ -80,26 +80,19 @@ const MessageList: React.FC<MessageListProps> = ({
)} )}
<div className="flex flex-col"> <div className="flex flex-col">
{displayMessages.map((message, index) => { {displayMessages.map((message, index) => (
// Check if this is the first user message <ChatMessage
const isFirstUserMessage = message.info.role === 'user' && key={message.info.id}
!displayMessages.slice(0, index).some((m) => m.info.role === 'user'); message={message}
previousMessage={index > 0 ? displayMessages[index - 1] : undefined}
return ( nextMessage={index < displayMessages.length - 1 ? displayMessages[index + 1] : undefined}
<ChatMessage onContentChange={onMessageContentChange}
key={message.info.id} animationHandlers={getAnimationHandlers(message.info.id)}
message={message} scrollToBottom={scrollToBottom}
previousMessage={index > 0 ? displayMessages[index - 1] : undefined} isPendingAnchor={pendingAnchorId === message.info.id}
nextMessage={index < displayMessages.length - 1 ? displayMessages[index + 1] : undefined} turnGroupingContext={getContextForMessage(message.info.id)}
onContentChange={onMessageContentChange} />
animationHandlers={getAnimationHandlers(message.info.id)} ))}
scrollToBottom={scrollToBottom}
isPendingAnchor={pendingAnchorId === message.info.id}
turnGroupingContext={getContextForMessage(message.info.id)}
isFirstMessage={isFirstUserMessage}
/>
);
})}
</div> </div>
@@ -133,7 +133,6 @@ interface MessageBodyProps {
agentMention?: AgentMentionInfo; agentMention?: AgentMentionInfo;
turnGroupingContext?: TurnGroupingContext; turnGroupingContext?: TurnGroupingContext;
onRevert?: () => void; onRevert?: () => void;
isFirstMessage?: boolean;
errorMessage?: string; errorMessage?: string;
} }
@@ -148,8 +147,7 @@ const UserMessageBody: React.FC<{
onShowPopup: (content: ToolPopupContent) => void; onShowPopup: (content: ToolPopupContent) => void;
agentMention?: AgentMentionInfo; agentMention?: AgentMentionInfo;
onRevert?: () => void; onRevert?: () => void;
isFirstMessage?: boolean; }> = ({ messageId, parts, isMobile, hasTouchInput, hasTextContent, onCopyMessage, copiedMessage, onShowPopup, agentMention, onRevert }) => {
}> = ({ messageId, parts, isMobile, hasTouchInput, hasTextContent, onCopyMessage, copiedMessage, onShowPopup, agentMention, onRevert, isFirstMessage }) => {
const [copyHintVisible, setCopyHintVisible] = React.useState(false); const [copyHintVisible, setCopyHintVisible] = React.useState(false);
const copyHintTimeoutRef = React.useRef<number | null>(null); const copyHintTimeoutRef = React.useRef<number | null>(null);
@@ -241,12 +239,12 @@ const UserMessageBody: React.FC<{
})} })}
</div> </div>
<MessageFilesDisplay files={parts} onShowPopup={onShowPopup} /> <MessageFilesDisplay files={parts} onShowPopup={onShowPopup} />
{(canCopyMessage && hasCopyableText) || (onRevert && !isFirstMessage) ? ( {(canCopyMessage && hasCopyableText) || onRevert ? (
<div className={cn( <div className={cn(
"mt-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", "mt-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",
copyHintVisible && "opacity-100 pointer-events-auto" copyHintVisible && "opacity-100 pointer-events-auto"
)}> )}>
{onRevert && !isFirstMessage && ( {onRevert && (
<Tooltip delayDuration={1000}> <Tooltip delayDuration={1000}>
<TooltipTrigger asChild> <TooltipTrigger asChild>
<Button <Button
@@ -1228,7 +1226,6 @@ const MessageBody: React.FC<MessageBodyProps> = ({ isUser, ...props }) => {
onShowPopup={props.onShowPopup} onShowPopup={props.onShowPopup}
agentMention={props.agentMention} agentMention={props.agentMention}
onRevert={props.onRevert} onRevert={props.onRevert}
isFirstMessage={props.isFirstMessage}
/> />
); );
} }