✨ (chatInput): add drag-and-drop file upload functionality
♻️ (chatInput): refactor file upload logic into a reusable hook
This commit is contained in:
parent
69f5d93bde
commit
5638e2909c
3 changed files with 87 additions and 27 deletions
|
|
@ -0,0 +1,55 @@
|
||||||
|
import ShortUniqueId from "short-unique-id";
|
||||||
|
import useFileUpload from "./use-file-upload";
|
||||||
|
|
||||||
|
const useDragAndDrop = (setIsDragging, setFiles, currentFlowId) => {
|
||||||
|
const dragOver = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (e.dataTransfer.types.some((type) => type === "Files")) {
|
||||||
|
setIsDragging(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const dragEnter = (e) => {
|
||||||
|
if (e.dataTransfer.types.some((type) => type === "Files")) {
|
||||||
|
setIsDragging(true);
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
|
const dragLeave = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setIsDragging(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDrop = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
||||||
|
handleFiles(e.dataTransfer.files, setFiles, currentFlowId);
|
||||||
|
e.dataTransfer.clearData();
|
||||||
|
}
|
||||||
|
setIsDragging(false);
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
dragOver,
|
||||||
|
dragEnter,
|
||||||
|
dragLeave,
|
||||||
|
onDrop,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFiles = (files, setFiles, currentFlowId) => {
|
||||||
|
if (files) {
|
||||||
|
const uid = new ShortUniqueId({ length: 3 });
|
||||||
|
const id = uid();
|
||||||
|
const type = files[0].type.split("/")[0];
|
||||||
|
const blob = files[0];
|
||||||
|
|
||||||
|
setFiles((prevFiles) => [
|
||||||
|
...prevFiles,
|
||||||
|
{ file: blob, loading: true, error: false, id, type },
|
||||||
|
]);
|
||||||
|
|
||||||
|
useFileUpload(blob, currentFlowId, setFiles, id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export default useDragAndDrop;
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { uploadFile } from "../../../../../../controllers/API";
|
||||||
|
|
||||||
|
const useFileUpload = (blob, currentFlowId, setFiles, id) => {
|
||||||
|
uploadFile(blob, currentFlowId)
|
||||||
|
.then((res) => {
|
||||||
|
setFiles((prev) => {
|
||||||
|
const newFiles = [...prev];
|
||||||
|
const updatedIndex = newFiles.findIndex((file) => file.id === id);
|
||||||
|
newFiles[updatedIndex].loading = false;
|
||||||
|
newFiles[updatedIndex].path = res.data.file_path;
|
||||||
|
return newFiles;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setFiles((prev) => {
|
||||||
|
const newFiles = [...prev];
|
||||||
|
const updatedIndex = newFiles.findIndex((file) => file.id === id);
|
||||||
|
newFiles[updatedIndex].loading = false;
|
||||||
|
newFiles[updatedIndex].error = true;
|
||||||
|
return newFiles;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useFileUpload;
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { uploadFile } from "../../../../../../controllers/API";
|
import ShortUniqueId from "short-unique-id";
|
||||||
|
import useFileUpload from "./use-file-upload";
|
||||||
|
|
||||||
const useUpload = (uploadFile, currentFlowId, setFiles, uid) => {
|
const useUpload = (uploadFile, currentFlowId, setFiles) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handlePaste = (event: ClipboardEvent): void => {
|
const handlePaste = (event: ClipboardEvent): void => {
|
||||||
const items = event.clipboardData?.items;
|
const items = event.clipboardData?.items;
|
||||||
if (items) {
|
if (items) {
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
const type = items[0].type.split("/")[0];
|
const type = items[0].type.split("/")[0];
|
||||||
|
const uid = new ShortUniqueId({ length: 3 });
|
||||||
const blob = items[i].getAsFile();
|
const blob = items[i].getAsFile();
|
||||||
if (blob) {
|
if (blob) {
|
||||||
const id = uid();
|
const id = uid();
|
||||||
|
|
@ -16,8 +17,7 @@ const useUpload = (uploadFile, currentFlowId, setFiles, uid) => {
|
||||||
...prevFiles,
|
...prevFiles,
|
||||||
{ file: blob, loading: true, error: false, id, type },
|
{ file: blob, loading: true, error: false, id, type },
|
||||||
]);
|
]);
|
||||||
|
useFileUpload(blob, currentFlowId, setFiles, id);
|
||||||
uploadFiles(blob, currentFlowId, setFiles, id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -32,26 +32,4 @@ const useUpload = (uploadFile, currentFlowId, setFiles, uid) => {
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const uploadFiles = (blob, currentFlowId, setFiles, id) => {
|
|
||||||
uploadFile(blob, currentFlowId)
|
|
||||||
.then((res) => {
|
|
||||||
setFiles((prev) => {
|
|
||||||
const newFiles = [...prev];
|
|
||||||
const updatedIndex = newFiles.findIndex((file) => file.id === id);
|
|
||||||
newFiles[updatedIndex].loading = false;
|
|
||||||
newFiles[updatedIndex].path = res.data.file_path;
|
|
||||||
return newFiles;
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
setFiles((prev) => {
|
|
||||||
const newFiles = [...prev];
|
|
||||||
const updatedIndex = newFiles.findIndex((file) => file.id === id);
|
|
||||||
newFiles[updatedIndex].loading = false;
|
|
||||||
newFiles[updatedIndex].error = true;
|
|
||||||
return newFiles;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useUpload;
|
export default useUpload;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue