feat: add delete button next to copy button for AI messages

- Added delete button in Markdown component alongside copy button
- Buttons appear on hover with same styling as copy button
- Pass messageTs prop through ChatRow to enable deletion
- Follows existing UI pattern for user message deletion

Addresses #9035
This commit is contained in:
Roo Code 2025-11-06 04:51:18 +00:00
parent 7320d79c08
commit 61f7cecf2e
2 changed files with 44 additions and 5 deletions

View file

@ -1061,7 +1061,7 @@ export const ChatRowContent = ({
<span style={{ fontWeight: "bold" }}>{t("chat:text.rooSaid")}</span>
</div>
<div className="pl-6">
<Markdown markdown={message.text} partial={message.partial} />
<Markdown markdown={message.text} partial={message.partial} messageTs={message.ts} />
{message.images && message.images.length > 0 && (
<div style={{ marginTop: "10px" }}>
{message.images.map((image, index) => (
@ -1170,7 +1170,7 @@ export const ChatRowContent = ({
{title}
</div>
<div className="border-l border-green-600/30 ml-2 pl-4 pb-1">
<Markdown markdown={message.text} />
<Markdown markdown={message.text} messageTs={message.ts} />
</div>
</>
)
@ -1324,7 +1324,7 @@ export const ChatRowContent = ({
</div>
)}
<div style={{ paddingTop: 10 }}>
<Markdown markdown={message.text} partial={message.partial} />
<Markdown markdown={message.text} partial={message.partial} messageTs={message.ts} />
</div>
</>
)
@ -1410,7 +1410,11 @@ export const ChatRowContent = ({
{title}
</div>
<div style={{ color: "var(--vscode-charts-green)", paddingTop: 10 }}>
<Markdown markdown={message.text} partial={message.partial} />
<Markdown
markdown={message.text}
partial={message.partial}
messageTs={message.ts}
/>
</div>
</div>
)
@ -1429,6 +1433,7 @@ export const ChatRowContent = ({
<div className="flex flex-col gap-2 ml-6">
<Markdown
markdown={message.partial === true ? message?.text : followUpData?.question}
messageTs={message.ts}
/>
<FollowUpSuggest
suggestions={followUpData?.suggest}

View file

@ -3,15 +3,31 @@ import { VSCodeButton } from "@vscode/webview-ui-toolkit/react"
import { useCopyToClipboard } from "@src/utils/clipboard"
import { StandardTooltip } from "@src/components/ui"
import { vscode } from "@src/utils/vscode"
import MarkdownBlock from "../common/MarkdownBlock"
export const Markdown = memo(({ markdown, partial }: { markdown?: string; partial?: boolean }) => {
interface MarkdownProps {
markdown?: string
partial?: boolean
messageTs?: number
onDeleteMessage?: () => void
}
export const Markdown = memo(({ markdown, partial, messageTs, onDeleteMessage }: MarkdownProps) => {
const [isHovering, setIsHovering] = useState(false)
// Shorter feedback duration for copy button flash.
const { copyWithFeedback } = useCopyToClipboard(200)
const handleDelete = () => {
if (onDeleteMessage) {
onDeleteMessage()
} else if (messageTs) {
vscode.postMessage({ type: "deleteMessage", value: messageTs })
}
}
if (!markdown || markdown.length === 0) {
return null
}
@ -33,6 +49,8 @@ export const Markdown = memo(({ markdown, partial }: { markdown?: string; partia
opacity: 0,
animation: "fadeIn 0.2s ease-in-out forwards",
borderRadius: "4px",
display: "flex",
gap: "4px",
}}>
<style>{`@keyframes fadeIn { from { opacity: 0; } to { opacity: 1.0; } }`}</style>
<StandardTooltip content="Copy as markdown">
@ -60,6 +78,22 @@ export const Markdown = memo(({ markdown, partial }: { markdown?: string; partia
<span className="codicon codicon-copy" />
</VSCodeButton>
</StandardTooltip>
{(messageTs || onDeleteMessage) && (
<StandardTooltip content="Delete message">
<VSCodeButton
className="delete-button"
appearance="icon"
style={{
height: "24px",
border: "none",
background: "var(--vscode-editor-background)",
transition: "background 0.2s ease-in-out",
}}
onClick={handleDelete}>
<span className="codicon codicon-trash" />
</VSCodeButton>
</StandardTooltip>
)}
</div>
)}
</div>