From 3cf4f32e8b512d636b4e31d33c9098ef591e9e18 Mon Sep 17 00:00:00 2001 From: xiang Date: Tue, 19 Nov 2024 19:04:05 -0500 Subject: [PATCH] feat(chat): Add drag-and-drop file upload functionality to ChatEditor Added drag-and-drop file upload capability in ChatEditor to improve user experience. - Users can now directly drag files into the ChatEditor for upload. - Simplified the process of adding files, reducing the need for additional clicks. - Improved efficiency for frequent file uploads. --- agenthub/components/chat/editor/Editor.tsx | 86 ++++++++++++---------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/agenthub/components/chat/editor/Editor.tsx b/agenthub/components/chat/editor/Editor.tsx index 4770bac54..17704b715 100644 --- a/agenthub/components/chat/editor/Editor.tsx +++ b/agenthub/components/chat/editor/Editor.tsx @@ -24,11 +24,11 @@ export interface ChatEditorProps { export const ChatEditor: React.FC = ({ onSend, darkMode }) => { const [attachments, setAttachments] = useState([]); - const [previews, setPreviews] = useState([]); const [hoverIndex, setHoverIndex] = useState(null); const fileInputRef = useRef(null); const theme = useMantineTheme(); const [agents, setAgents] = useState([]); + const [isDragging, setIsDragging] = useState(false); useEffect(() => { @@ -106,7 +106,6 @@ export const ChatEditor: React.FC = ({ onSend, darkMode }) => { onSend(content, attachments); editor.commands.setContent(''); setAttachments([]); - setPreviews([]); } } }, [editor, attachments, onSend]); @@ -116,24 +115,11 @@ export const ChatEditor: React.FC = ({ onSend, darkMode }) => { if (files) { const newAttachments = Array.from(files); setAttachments(prev => [...prev, ...newAttachments]); - - newAttachments.forEach(file => { - if (file.type.startsWith('image/')) { - const reader = new FileReader(); - reader.onload = (e) => { - setPreviews(prev => [...prev, e.target?.result as string]); - }; - reader.readAsDataURL(file); - } else { - setPreviews(prev => [...prev, '']); - } - }); } }, []); const removeAttachment = useCallback((index: number) => { setAttachments(prev => prev.filter((_, i) => i !== index)); - setPreviews(prev => prev.filter((_, i) => i !== index)); setHoverIndex(null); // Reset hover state after removal }, []); @@ -156,14 +142,50 @@ export const ChatEditor: React.FC = ({ onSend, darkMode }) => { fileInputRef.current?.click(); }; + const handleDragOver = useCallback((e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + setIsDragging(true); + }, []); + + const handleDragLeave = useCallback((e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + setIsDragging(false); + }, []); + + const handleDrop = useCallback((e: React.DragEvent) => { + e.preventDefault(); + e.stopPropagation(); + setIsDragging(false); + + const files = Array.from(e.dataTransfer.files); + if (files.length > 0) { + setAttachments(prev => [...prev, ...files]); + } + }, []); + return ( + {isDragging && ( +
+
+ Drop files here to upload +
+
+ )} {attachments.length > 0 && ( @@ -179,25 +201,14 @@ export const ChatEditor: React.FC = ({ onSend, darkMode }) => { onMouseEnter={() => setHoverIndex(index)} onMouseLeave={() => setHoverIndex(null)} > - {previews[index] ? ( - {file.name} - ) : ( -
- - - {file.name} - -
- )} +
+ + + {file.name} + +
{hoverIndex === index && ( = ({ onSend, darkMode }) => { color="red" className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2" onClick={(e) => { - console.log('hi') - e.stopPropagation(); // Prevent event bubbling + e.stopPropagation(); removeAttachment(index); }} >