mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
working functionality
This commit is contained in:
parent
05040414c2
commit
3fe0b46353
4 changed files with 131 additions and 16 deletions
|
|
@ -1087,6 +1087,54 @@ export const webviewMessageHandler = async (
|
|||
}
|
||||
break
|
||||
}
|
||||
case "submitEditedMessage": {
|
||||
if (
|
||||
provider.getCurrentCline() &&
|
||||
typeof message.value === "number" &&
|
||||
message.value &&
|
||||
message.editedMessageContent
|
||||
) {
|
||||
const timeCutoff = message.value - 1000 // 1 second buffer before the message to edit
|
||||
|
||||
const messageIndex = provider
|
||||
.getCurrentCline()!
|
||||
.clineMessages.findIndex((msg) => msg.ts && msg.ts >= timeCutoff)
|
||||
|
||||
const apiConversationHistoryIndex = provider
|
||||
.getCurrentCline()
|
||||
?.apiConversationHistory.findIndex((msg) => msg.ts && msg.ts >= timeCutoff)
|
||||
|
||||
if (messageIndex !== -1) {
|
||||
try {
|
||||
const currentCline = provider.getCurrentCline()!
|
||||
|
||||
// Delete the original message and all subsequent messages
|
||||
await currentCline.overwriteClineMessages(currentCline.clineMessages.slice(0, messageIndex))
|
||||
|
||||
// Delete the original message and all subsequent messages in API history
|
||||
if (apiConversationHistoryIndex !== undefined && apiConversationHistoryIndex !== -1) {
|
||||
await currentCline.overwriteApiConversationHistory(
|
||||
currentCline.apiConversationHistory.slice(0, apiConversationHistoryIndex),
|
||||
)
|
||||
}
|
||||
|
||||
// Process the edited message as a regular user message
|
||||
// This will add it to the conversation and trigger an AI response
|
||||
webviewMessageHandler(provider, {
|
||||
type: "askResponse",
|
||||
askResponse: "messageResponse",
|
||||
text: message.editedMessageContent,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error("Error in submitEditedMessage:", error)
|
||||
vscode.window.showErrorMessage(
|
||||
`Error editing message: ${error instanceof Error ? error.message : String(error)}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
case "screenshotQuality":
|
||||
await updateGlobalState("screenshotQuality", message.value)
|
||||
await provider.postStateToWebview()
|
||||
|
|
|
|||
|
|
@ -107,6 +107,11 @@
|
|||
"remove": "Remove",
|
||||
"keep": "Keep"
|
||||
},
|
||||
"buttons": {
|
||||
"save": "Save",
|
||||
"cancel": "Cancel",
|
||||
"edit": "Edit"
|
||||
},
|
||||
"tasks": {
|
||||
"canceled": "Task error: It was stopped and canceled by the user.",
|
||||
"deleted": "Task failure: It was stopped and deleted by the user.",
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ export interface WebviewMessage {
|
|||
| "enhancedPrompt"
|
||||
| "draggedImages"
|
||||
| "deleteMessage"
|
||||
| "submitEditedMessage"
|
||||
| "terminalOutputLineLimit"
|
||||
| "terminalShellIntegrationTimeout"
|
||||
| "terminalShellIntegrationDisabled"
|
||||
|
|
@ -184,6 +185,7 @@ export interface WebviewMessage {
|
|||
| "checkRulesDirectory"
|
||||
| "checkRulesDirectoryResult"
|
||||
text?: string
|
||||
editedMessageContent?: string
|
||||
tab?: "settings" | "history" | "mcp" | "modes" | "chat" | "marketplace" | "account"
|
||||
disabled?: boolean
|
||||
dataUri?: string
|
||||
|
|
|
|||
|
|
@ -108,6 +108,8 @@ export const ChatRowContent = ({
|
|||
const [reasoningCollapsed, setReasoningCollapsed] = useState(true)
|
||||
const [isDiffErrorExpanded, setIsDiffErrorExpanded] = useState(false)
|
||||
const [showCopySuccess, setShowCopySuccess] = useState(false)
|
||||
const [isEditing, setIsEditing] = useState(false)
|
||||
const [editedContent, setEditedContent] = useState("")
|
||||
const { copyWithFeedback } = useCopyToClipboard()
|
||||
|
||||
// Memoized callback to prevent re-renders caused by inline arrow functions
|
||||
|
|
@ -115,6 +117,31 @@ export const ChatRowContent = ({
|
|||
onToggleExpand(message.ts)
|
||||
}, [onToggleExpand, message.ts])
|
||||
|
||||
// Handle edit button click
|
||||
const handleEditClick = useCallback(() => {
|
||||
setIsEditing(true)
|
||||
setEditedContent(message.text || "")
|
||||
// Edit mode is now handled entirely in the frontend
|
||||
// No need to notify the backend
|
||||
}, [message.text])
|
||||
|
||||
// Handle cancel edit
|
||||
const handleCancelEdit = useCallback(() => {
|
||||
setIsEditing(false)
|
||||
setEditedContent(message.text || "")
|
||||
}, [message.text])
|
||||
|
||||
// Handle save edit
|
||||
const handleSaveEdit = useCallback(() => {
|
||||
setIsEditing(false)
|
||||
// Send edited message to backend
|
||||
vscode.postMessage({
|
||||
type: "submitEditedMessage",
|
||||
value: message.ts,
|
||||
editedMessageContent: editedContent,
|
||||
})
|
||||
}, [message.ts, editedContent])
|
||||
|
||||
const [cost, apiReqCancelReason, apiReqStreamingFailedMessage] = useMemo(() => {
|
||||
if (message.text !== null && message.text !== undefined && message.say === "api_req_started") {
|
||||
const info = safeJsonParse<ClineApiReqInfo>(message.text)
|
||||
|
|
@ -983,23 +1010,56 @@ export const ChatRowContent = ({
|
|||
case "user_feedback":
|
||||
return (
|
||||
<div className="bg-vscode-editor-background border rounded-xs p-1 overflow-hidden whitespace-pre-wrap">
|
||||
<div className="flex justify-between">
|
||||
<div className="flex-grow px-2 py-1 wrap-anywhere">
|
||||
<Mention text={message.text} withShadow />
|
||||
{isEditing ? (
|
||||
<div className="flex flex-col gap-2 p-2">
|
||||
<textarea
|
||||
className="w-full p-2 bg-vscode-input-background text-vscode-input-foreground border border-vscode-input-border rounded-xs"
|
||||
value={editedContent}
|
||||
onChange={(e) => setEditedContent(e.target.value)}
|
||||
rows={5}
|
||||
autoFocus
|
||||
/>
|
||||
<div className="flex justify-end gap-2">
|
||||
<Button variant="secondary" size="sm" onClick={handleCancelEdit}>
|
||||
{t("chat:cancel.title")}
|
||||
</Button>
|
||||
<Button variant="default" size="sm" onClick={handleSaveEdit}>
|
||||
{t("chat:save.title")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="shrink-0"
|
||||
disabled={isStreaming}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
vscode.postMessage({ type: "deleteMessage", value: message.ts })
|
||||
}}>
|
||||
<span className="codicon codicon-trash" />
|
||||
</Button>
|
||||
</div>
|
||||
{message.images && message.images.length > 0 && (
|
||||
) : (
|
||||
<div className="flex justify-between">
|
||||
<div className="flex-grow px-2 py-1 wrap-anywhere">
|
||||
<Mention text={message.text} withShadow />
|
||||
</div>
|
||||
<div className="flex">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="shrink-0"
|
||||
disabled={isStreaming}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
handleEditClick()
|
||||
}}>
|
||||
<span className="codicon codicon-edit" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="shrink-0"
|
||||
disabled={isStreaming}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
vscode.postMessage({ type: "deleteMessage", value: message.ts })
|
||||
}}>
|
||||
<span className="codicon codicon-trash" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!isEditing && message.images && message.images.length > 0 && (
|
||||
<Thumbnails images={message.images} style={{ marginTop: "8px" }} />
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue