(chatInput): add drag-and-drop file upload functionality

♻️ (chatInput): refactor file upload logic into a reusable hook
This commit is contained in:
cristhianzl 2024-05-29 10:46:51 -03:00
commit 5638e2909c
3 changed files with 87 additions and 27 deletions

View file

@ -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;

View file

@ -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;

View file

@ -1,14 +1,15 @@
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(() => {
const handlePaste = (event: ClipboardEvent): void => {
const items = event.clipboardData?.items;
if (items) {
for (let i = 0; i < items.length; i++) {
const type = items[0].type.split("/")[0];
const uid = new ShortUniqueId({ length: 3 });
const blob = items[i].getAsFile();
if (blob) {
const id = uid();
@ -16,8 +17,7 @@ const useUpload = (uploadFile, currentFlowId, setFiles, uid) => {
...prevFiles,
{ file: blob, loading: true, error: false, id, type },
]);
uploadFiles(blob, currentFlowId, setFiles, id);
useFileUpload(blob, currentFlowId, setFiles, id);
}
}
}
@ -32,26 +32,4 @@ const useUpload = (uploadFile, currentFlowId, setFiles, uid) => {
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;