mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Merge pull request #1401 from brownrw8/drag-n-drop-alternative
Drag/Drop Images (1 file change solution)
This commit is contained in:
commit
f40826c1eb
1 changed files with 90 additions and 1 deletions
|
|
@ -746,6 +746,93 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||
}
|
||||
}, [showModelSelector])
|
||||
|
||||
/**
|
||||
* Handles the drag over event to allow dropping.
|
||||
* Prevents the default behavior to enable drop.
|
||||
*
|
||||
* @param {React.DragEvent} e - The drag event.
|
||||
*/
|
||||
const onDragOver = (e: React.DragEvent) => {
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the drop event for files and text.
|
||||
* Processes dropped images and text, updating the state accordingly.
|
||||
*
|
||||
* @param {React.DragEvent} e - The drop event.
|
||||
*/
|
||||
const onDrop = async (e: React.DragEvent) => {
|
||||
e.preventDefault()
|
||||
|
||||
const files = Array.from(e.dataTransfer.files)
|
||||
const text = e.dataTransfer.getData("text")
|
||||
|
||||
if (text) {
|
||||
handleTextDrop(text)
|
||||
return
|
||||
}
|
||||
|
||||
const acceptedTypes = ["png", "jpeg", "webp"]
|
||||
const imageFiles = files.filter((file) => {
|
||||
const [type, subtype] = file.type.split("/")
|
||||
return type === "image" && acceptedTypes.includes(subtype)
|
||||
})
|
||||
|
||||
if (shouldDisableImages || imageFiles.length === 0) return
|
||||
|
||||
const imageDataArray = await readImageFiles(imageFiles)
|
||||
const dataUrls = imageDataArray.filter((dataUrl): dataUrl is string => dataUrl !== null)
|
||||
|
||||
if (dataUrls.length > 0) {
|
||||
setSelectedImages((prevImages) => [...prevImages, ...dataUrls].slice(0, MAX_IMAGES_PER_MESSAGE))
|
||||
} else {
|
||||
console.warn("No valid images were processed")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the drop event for text.
|
||||
* Inserts the dropped text at the current cursor position.
|
||||
*
|
||||
* @param {string} text - The dropped text.
|
||||
*/
|
||||
const handleTextDrop = (text: string) => {
|
||||
const newValue = inputValue.slice(0, cursorPosition) + text + inputValue.slice(cursorPosition)
|
||||
setInputValue(newValue)
|
||||
const newCursorPosition = cursorPosition + text.length
|
||||
setCursorPosition(newCursorPosition)
|
||||
setIntendedCursorPosition(newCursorPosition)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads image files and returns their data URLs.
|
||||
* Uses FileReader to read the files as data URLs.
|
||||
*
|
||||
* @param {File[]} imageFiles - The image files to read.
|
||||
* @returns {Promise<(string | null)[]>} - A promise that resolves to an array of data URLs or null values.
|
||||
*/
|
||||
const readImageFiles = (imageFiles: File[]): Promise<(string | null)[]> => {
|
||||
return Promise.all(
|
||||
imageFiles.map(
|
||||
(file) =>
|
||||
new Promise<string | null>((resolve) => {
|
||||
const reader = new FileReader()
|
||||
reader.onloadend = () => {
|
||||
if (reader.error) {
|
||||
console.error("Error reading file:", reader.error)
|
||||
resolve(null)
|
||||
} else {
|
||||
const result = reader.result
|
||||
resolve(typeof result === "string" ? result : null)
|
||||
}
|
||||
}
|
||||
reader.readAsDataURL(file)
|
||||
}),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
|
|
@ -754,7 +841,9 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||
opacity: textAreaDisabled ? 0.5 : 1,
|
||||
position: "relative",
|
||||
display: "flex",
|
||||
}}>
|
||||
}}
|
||||
onDrop={onDrop}
|
||||
onDragOver={onDragOver}>
|
||||
{showContextMenu && (
|
||||
<div ref={contextMenuContainerRef}>
|
||||
<ContextMenu
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue