From 123330213536b6f7ab0cd13b7ff8146e0d29bbff Mon Sep 17 00:00:00 2001 From: Ammar Date: Mon, 27 Oct 2025 14:22:48 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20Fix=20UI=20freeze=20when=20sendi?= =?UTF-8?q?ng=20message=20in=20SSH=20workspaces?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The UI froze for ~1s when sending messages in SSH workspaces because the frontend awaited the entire IPC call, including remote temp directory creation. Changed ChatInput to clear input/images immediately before the IPC call instead of after it succeeds. This makes the UI responsive while the backend handles SSH operations asynchronously. On error, the previous state is restored so users can retry. _Generated with `cmux`_ --- src/components/ChatInput.tsx | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/components/ChatInput.tsx b/src/components/ChatInput.tsx index 9f076d6c8..274291caa 100644 --- a/src/components/ChatInput.tsx +++ b/src/components/ChatInput.tsx @@ -528,6 +528,9 @@ export const ChatInput: React.FC = ({ // Regular message - send directly via API setIsSending(true); + // Save current state for restoration on error + const previousImageAttachments = [...imageAttachments]; + try { // Prepare image parts if any const imageParts = imageAttachments.map((img, index) => { @@ -583,6 +586,15 @@ export const ChatInput: React.FC = ({ } } + // Clear input and images immediately for responsive UI + // These will be restored if the send operation fails + setInput(""); + setImageAttachments([]); + // Reset textarea height + if (inputRef.current) { + inputRef.current.style.height = "36px"; + } + const result = await window.api.workspace.sendMessage(workspaceId, actualMessageText, { ...sendMessageOptions, ...compactionOptions, @@ -596,19 +608,13 @@ export const ChatInput: React.FC = ({ console.error("Failed to send message:", result.error); // Show error using enhanced toast setToast(createErrorToast(result.error)); - // Restore input on error so user can try again + // Restore input and images on error so user can try again setInput(messageText); + setImageAttachments(previousImageAttachments); } else { // Track telemetry for successful message send telemetry.messageSent(sendMessageOptions.model, mode, actualMessageText.length); - // Success - clear input and images - setInput(""); - setImageAttachments([]); - // Reset textarea height - if (inputRef.current) { - inputRef.current.style.height = "36px"; - } // Exit editing mode if we were editing if (editingMessage && onCancelEdit) { onCancelEdit(); @@ -625,6 +631,7 @@ export const ChatInput: React.FC = ({ }) ); setInput(messageText); + setImageAttachments(previousImageAttachments); } finally { setIsSending(false); }