Forráskód Böngészése

Fix issue #4830: [Bug]: Copy-paste into the "What do you want to build?" bar doesn't work (#4832)

Co-authored-by: Graham Neubig <neubig@gmail.com>
OpenHands 1 éve
szülő
commit
f5003a7449

+ 43 - 1
frontend/__tests__/components/chat/chat-input.test.tsx

@@ -1,5 +1,5 @@
 import userEvent from "@testing-library/user-event";
-import { render, screen } from "@testing-library/react";
+import { fireEvent, render, screen } from "@testing-library/react";
 import { describe, afterEach, vi, it, expect } from "vitest";
 import { ChatInput } from "#/components/chat-input";
 
@@ -158,4 +158,46 @@ describe("ChatInput", () => {
     await user.tab();
     expect(onBlurMock).toHaveBeenCalledOnce();
   });
+
+  it("should handle text paste correctly", () => {
+    const onSubmit = vi.fn();
+    const onChange = vi.fn();
+
+    render(<ChatInput onSubmit={onSubmit} onChange={onChange} />);
+
+    const input = screen.getByTestId("chat-input").querySelector("textarea");
+    expect(input).toBeTruthy();
+
+    // Fire paste event with text data
+    fireEvent.paste(input!, {
+      clipboardData: {
+        getData: (type: string) => type === 'text/plain' ? 'test paste' : '',
+        files: []
+      }
+    });
+  });
+
+  it("should handle image paste correctly", () => {
+    const onSubmit = vi.fn();
+    const onImagePaste = vi.fn();
+
+    render(<ChatInput onSubmit={onSubmit} onImagePaste={onImagePaste} />);
+
+    const input = screen.getByTestId("chat-input").querySelector("textarea");
+    expect(input).toBeTruthy();
+
+    // Create a paste event with an image file
+    const file = new File(["dummy content"], "image.png", { type: "image/png" });
+
+    // Fire paste event with image data
+    fireEvent.paste(input!, {
+      clipboardData: {
+        getData: () => '',
+        files: [file]
+      }
+    });
+
+    // Verify image paste was handled
+    expect(onImagePaste).toHaveBeenCalledWith([file]);
+  });
 });

+ 7 - 2
frontend/src/components/chat-input.tsx

@@ -40,13 +40,18 @@ export function ChatInput({
   const [isDraggingOver, setIsDraggingOver] = React.useState(false);
 
   const handlePaste = (event: React.ClipboardEvent<HTMLTextAreaElement>) => {
-    event.preventDefault();
+    // Only handle paste if we have an image paste handler and there are files
     if (onImagePaste && event.clipboardData.files.length > 0) {
       const files = Array.from(event.clipboardData.files).filter((file) =>
         file.type.startsWith("image/"),
       );
-      if (files.length > 0) onImagePaste(files);
+      // Only prevent default if we found image files to handle
+      if (files.length > 0) {
+        event.preventDefault();
+        onImagePaste(files);
+      }
     }
+    // For text paste, let the default behavior handle it
   };
 
   const handleDragOver = (event: React.DragEvent<HTMLTextAreaElement>) => {