chore: prevent drag image to replace the window, and enable shortcut copy and paste image
This commit is contained in:
parent
f70449fd98
commit
e04bb86171
@ -332,6 +332,41 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => {
|
||||
}
|
||||
}
|
||||
|
||||
const handlePaste = (e: React.ClipboardEvent) => {
|
||||
const clipboardItems = e.clipboardData?.items
|
||||
if (!clipboardItems) return
|
||||
|
||||
const imageItems = Array.from(clipboardItems).filter(item =>
|
||||
item.type.startsWith('image/')
|
||||
)
|
||||
|
||||
if (imageItems.length > 0) {
|
||||
e.preventDefault()
|
||||
|
||||
const files: File[] = []
|
||||
let processedCount = 0
|
||||
|
||||
imageItems.forEach((item) => {
|
||||
const file = item.getAsFile()
|
||||
if (file) {
|
||||
files.push(file)
|
||||
processedCount++
|
||||
|
||||
// When all files are collected, process them
|
||||
if (processedCount === imageItems.length) {
|
||||
const syntheticEvent = {
|
||||
target: {
|
||||
files: files,
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>
|
||||
|
||||
handleFileChange(syntheticEvent)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<div className="relative">
|
||||
@ -359,6 +394,7 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => {
|
||||
isFocused && 'ring-1 ring-main-view-fg/10',
|
||||
isDragOver && 'ring-2 ring-accent border-accent'
|
||||
)}
|
||||
data-drop-zone="true"
|
||||
onDragEnter={handleDragEnter}
|
||||
onDragLeave={handleDragLeave}
|
||||
onDragOver={handleDragOver}
|
||||
@ -423,6 +459,7 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => {
|
||||
// When Shift+Enter is pressed, a new line is added (default behavior)
|
||||
}
|
||||
}}
|
||||
onPaste={handlePaste}
|
||||
placeholder={t('common:placeholder.chatInput')}
|
||||
autoFocus
|
||||
spellCheck={spellCheckChatInput}
|
||||
|
||||
@ -26,7 +26,7 @@ import {
|
||||
ResizablePanel,
|
||||
ResizableHandle,
|
||||
} from '@/components/ui/resizable'
|
||||
import { useCallback } from 'react'
|
||||
import { useCallback, useEffect } from 'react'
|
||||
import GlobalError from '@/containers/GlobalError'
|
||||
import { GlobalEventHandler } from '@/providers/GlobalEventHandler'
|
||||
|
||||
@ -65,6 +65,41 @@ const AppLayout = () => {
|
||||
[setLeftPanelSize, setLeftPanel]
|
||||
)
|
||||
|
||||
// Prevent default drag and drop behavior globally
|
||||
useEffect(() => {
|
||||
const preventDefaults = (e: DragEvent) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}
|
||||
|
||||
const handleGlobalDrop = (e: DragEvent) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
// Only prevent if the target is not within a chat input or other valid drop zone
|
||||
const target = e.target as Element
|
||||
const isValidDropZone = target?.closest('[data-drop-zone="true"]') ||
|
||||
target?.closest('.chat-input-drop-zone') ||
|
||||
target?.closest('[data-tauri-drag-region]')
|
||||
|
||||
if (!isValidDropZone) {
|
||||
// Prevent the file from opening in the window
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Add event listeners to prevent default drag/drop behavior
|
||||
window.addEventListener('dragenter', preventDefaults)
|
||||
window.addEventListener('dragover', preventDefaults)
|
||||
window.addEventListener('drop', handleGlobalDrop)
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('dragenter', preventDefaults)
|
||||
window.removeEventListener('dragover', preventDefaults)
|
||||
window.removeEventListener('drop', handleGlobalDrop)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<AnalyticProvider />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user