diff --git a/webview-ui/src/App.tsx b/webview-ui/src/App.tsx index 3782242707c..7e863cf9bf6 100644 --- a/webview-ui/src/App.tsx +++ b/webview-ui/src/App.tsx @@ -93,6 +93,13 @@ const App = () => { messageTs: 0, }) + /** + * Tracks whether the user has seen the edit warning dialog during the current session. + * Uses a ref to persist the value across renders without triggering re-renders. + * Resets when the VS Code window is reloaded. + */ + const hasSeenEditWarningInSessionRef = useRef(false) + const [editMessageDialogState, setEditMessageDialogState] = useState({ isOpen: false, messageTs: 0, @@ -125,6 +132,32 @@ const App = () => { const [currentSection, setCurrentSection] = useState(undefined) const [currentMarketplaceTab, setCurrentMarketplaceTab] = useState(undefined) + /** + * Handles the edit message dialog logic, determining whether to show the warning + * or proceed directly to editing based on session state. + */ + const handleEditMessageDialog = useCallback((message: ExtensionMessage) => { + if (!message.messageTs || !message.text) return + + // If the user has already seen the warning in this session, skip the dialog + if (hasSeenEditWarningInSessionRef.current) { + vscode.postMessage({ + type: "editMessageConfirm", + messageTs: message.messageTs, + text: message.text, + images: message.images || [], + }) + } else { + // Show the warning dialog for the first time in this session + setEditMessageDialogState({ + isOpen: true, + messageTs: message.messageTs, + text: message.text, + images: message.images || [], + }) + } + }, []) + const onMessage = useCallback( (e: MessageEvent) => { const message: ExtensionMessage = e.data @@ -160,19 +193,14 @@ const App = () => { } if (message.type === "showEditMessageDialog" && message.messageTs && message.text) { - setEditMessageDialogState({ - isOpen: true, - messageTs: message.messageTs, - text: message.text, - images: message.images || [], - }) + handleEditMessageDialog(message) } if (message.type === "acceptInput") { chatViewRef.current?.acceptInput() } }, - [switchTab], + [switchTab, handleEditMessageDialog], ) useEvent("message", onMessage) @@ -283,6 +311,8 @@ const App = () => { open={editMessageDialogState.isOpen} onOpenChange={(open) => setEditMessageDialogState((prev) => ({ ...prev, isOpen: open }))} onConfirm={() => { + // Mark that the user has seen the edit warning in this session + hasSeenEditWarningInSessionRef.current = true vscode.postMessage({ type: "editMessageConfirm", messageTs: editMessageDialogState.messageTs, diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index 4fa921f4435..37bc543dd7d 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -177,6 +177,16 @@ export const ChatRowContent = ({ vscode.postMessage({ type: "selectImages", context: "edit", messageTs: message.ts }) }, [message.ts]) + // Simple double-click handler + const handleDoubleClick = useCallback( + (e: React.MouseEvent) => { + e.stopPropagation() + e.preventDefault() + handleEditClick() + }, + [handleEditClick], + ) + const [cost, apiReqCancelReason, apiReqStreamingFailedMessage] = useMemo(() => { if (message.text !== null && message.text !== undefined && message.say === "api_req_started") { const info = safeJsonParse(message.text) @@ -1059,6 +1069,7 @@ export const ChatRowContent = ({ ) case "user_feedback": + // For user feedback messages, always allow editing return (
{isEditing ? ( @@ -1083,15 +1094,19 @@ export const ChatRowContent = ({
) : (
-
+