Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions packages/app/src/components/prompt-input/attachments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { uuid } from "@/utils/uuid"
import { getCursorPosition } from "./editor-dom"
import { attachmentMime } from "./files"
import { normalizePaste, pasteMode } from "./paste"
import { getDroppedPromptData } from "./drop"

function dataUrl(file: File, mime: string) {
return new Promise<string>((resolve) => {
Expand Down Expand Up @@ -165,19 +166,17 @@ export function createPromptAttachments(input: PromptAttachmentsInput) {
event.preventDefault()
input.setDraggingType(null)

const plainText = event.dataTransfer?.getData("text/plain")
const filePrefix = "file:"
if (plainText?.startsWith(filePrefix)) {
const filePath = plainText.slice(filePrefix.length)
input.focusEditor()
input.addPart({ type: "file", path: filePath, content: "@" + filePath, start: 0, end: 0 })
const dropped = getDroppedPromptData(event.dataTransfer)
if (dropped.files.length > 0) {
await addAttachments(dropped.files)
return
}

const dropped = event.dataTransfer?.files
if (!dropped) return

await addAttachments(Array.from(dropped))
if (dropped.filePath) {
input.focusEditor()
input.addPart({ type: "file", path: dropped.filePath, content: "@" + dropped.filePath, start: 0, end: 0 })
return
}
}

onMount(() => {
Expand Down
28 changes: 28 additions & 0 deletions packages/app/src/components/prompt-input/drop.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { describe, expect, test } from "bun:test"
import { getDroppedPromptData } from "./drop"

describe("getDroppedPromptData", () => {
test("prefers dropped files over file uri text", () => {
const file = new File(["png"], "drop.png", { type: "image/png" })
const dataTransfer = {
files: [file] as unknown as FileList,
getData: () => "file:/tmp/drop.png",
}

const result = getDroppedPromptData(dataTransfer)
expect(result.files).toEqual([file])
expect(result.filePath).toBeUndefined()
})

test("falls back to file uri text when no files are present", () => {
const dataTransfer = {
files: [] as unknown as FileList,
getData: () => "file:/tmp/drop.png",
}

expect(getDroppedPromptData(dataTransfer)).toEqual({
files: [],
filePath: "/tmp/drop.png",
})
})
})
17 changes: 17 additions & 0 deletions packages/app/src/components/prompt-input/drop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
type DropDataTransfer = Pick<DataTransfer, "files" | "getData">

export function getDroppedPromptData(dataTransfer: DropDataTransfer | null | undefined): {
files: File[]
filePath?: string
} {
const files = Array.from(dataTransfer?.files ?? [])
if (files.length > 0) return { files }

const plainText = dataTransfer?.getData("text/plain")
const filePrefix = "file:"
if (plainText?.startsWith(filePrefix)) {
return { files: [], filePath: plainText.slice(filePrefix.length) }
}

return { files: [] }
}
Loading