@droppii-org/chat-sdk
Version:
Droppii React Chat SDK
116 lines (115 loc) • 5.07 kB
JavaScript
"use client";
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
import { useEffect } from "react";
import { COMMAND_PRIORITY_HIGH, PASTE_COMMAND, DROP_COMMAND } from "lexical";
import { useMessageFooterContext } from ".";
import { useTranslation } from "react-i18next";
import { processAndValidateFiles, ACCEPTED_IMAGE_TYPES } from "../../../utils/fileValidation";
const PasteAndDropPlugin = ({ onFilesAdded }) => {
const [editor] = useLexicalComposerContext();
const { setListUploadFiles } = useMessageFooterContext();
const { t } = useTranslation();
useEffect(() => {
// Handle paste event
const unregisterPaste = editor.registerCommand(PASTE_COMMAND, (event) => {
try {
const clipboardData = event.clipboardData;
if (!clipboardData)
return false;
const items = Array.from(clipboardData.items);
const imageItems = items.filter((item) => item.type.startsWith("image/"));
if (imageItems.length > 0) {
event.preventDefault();
const files = [];
imageItems.forEach((item) => {
const file = item.getAsFile();
if (file) {
files.push(file);
}
});
if (files.length > 0) {
setListUploadFiles((prev) => {
const validFiles = processAndValidateFiles(files, {
t,
currentUploadedFiles: prev,
});
if (validFiles.length > 0) {
onFilesAdded === null || onFilesAdded === void 0 ? void 0 : onFilesAdded(files);
return [...prev, ...validFiles];
}
return prev;
});
}
return true;
}
return false;
}
catch (error) {
console.error("Error handling paste:", error);
return false;
}
}, COMMAND_PRIORITY_HIGH);
// Handle drop event
const unregisterDrop = editor.registerCommand(DROP_COMMAND, (event) => {
try {
const dataTransfer = event.dataTransfer;
if (!dataTransfer)
return false;
const files = Array.from(dataTransfer.files);
const imageOrVideoFiles = files.filter((file) => ACCEPTED_IMAGE_TYPES.includes(file.type) ||
file.type.startsWith("video/"));
if (imageOrVideoFiles.length > 0) {
event.preventDefault();
setListUploadFiles((prev) => {
const validFiles = processAndValidateFiles(imageOrVideoFiles, {
t,
currentUploadedFiles: prev,
});
if (validFiles.length > 0) {
onFilesAdded === null || onFilesAdded === void 0 ? void 0 : onFilesAdded(imageOrVideoFiles);
return [...prev, ...validFiles];
}
return prev;
});
return true;
}
return false;
}
catch (error) {
console.error("Error handling drop:", error);
return false;
}
}, COMMAND_PRIORITY_HIGH);
return () => {
unregisterPaste();
unregisterDrop();
};
}, [editor, setListUploadFiles, t, onFilesAdded]);
// Add visual feedback for drag over
useEffect(() => {
const editorElement = editor.getRootElement();
if (!editorElement)
return;
const handleDragOverVisual = (e) => {
e.preventDefault();
editorElement.classList.add("border-blue-500", "bg-blue-50");
};
const handleDragLeaveVisual = (e) => {
e.preventDefault();
editorElement.classList.remove("border-blue-500", "bg-blue-50");
};
const handleDropVisual = () => {
editorElement.classList.remove("border-blue-500", "bg-blue-50");
};
editorElement.addEventListener("dragover", handleDragOverVisual);
editorElement.addEventListener("dragleave", handleDragLeaveVisual);
editorElement.addEventListener("drop", handleDropVisual);
return () => {
editorElement.removeEventListener("dragover", handleDragOverVisual);
editorElement.removeEventListener("dragleave", handleDragLeaveVisual);
editorElement.removeEventListener("drop", handleDropVisual);
};
}, [editor]);
return null;
};
export default PasteAndDropPlugin;