feat: Add drag and drop file upload functionality to chat input
This commit adds the drag and drop file upload functionality to the chat input component in the IOModal. It allows users to drag and drop files into the chat input area for uploading. The files are then processed and added to the chat message. Files are validated to ensure they have the correct file extensions (png, jpg, jpeg, gif, bmp, webp) before uploading. If an invalid file is dropped, an error message is displayed. This feature improves the user experience by providing a convenient way to upload files in the chat input. Fixes #2115
This commit is contained in:
parent
770dff7075
commit
719c031212
4 changed files with 50 additions and 7 deletions
|
|
@ -1,14 +1,25 @@
|
|||
import IconComponent from "../../../../../../../components/genericIconComponent";
|
||||
import { Case } from "../../../../../../../shared/components/caseComponent";
|
||||
import { FilePreviewType } from "../../../../../../../types/components";
|
||||
import { classNames } from "../../../../../../../utils/utils";
|
||||
|
||||
type ButtonSendWrapperProps = {
|
||||
send: () => void;
|
||||
lockChat: boolean;
|
||||
noInput: boolean;
|
||||
saveLoading: boolean;
|
||||
chatValue: string;
|
||||
files: FilePreviewType[];
|
||||
};
|
||||
|
||||
const ButtonSendWrapper = ({
|
||||
send,
|
||||
lockChat,
|
||||
noInput,
|
||||
saveLoading,
|
||||
chatValue,
|
||||
}) => {
|
||||
files,
|
||||
}: ButtonSendWrapperProps) => {
|
||||
return (
|
||||
<button
|
||||
className={classNames(
|
||||
|
|
@ -22,7 +33,11 @@ const ButtonSendWrapper = ({
|
|||
disabled={lockChat || saveLoading}
|
||||
onClick={(): void => send()}
|
||||
>
|
||||
<Case condition={lockChat || saveLoading}>
|
||||
<Case
|
||||
condition={
|
||||
lockChat || saveLoading || files.some((file) => file.loading)
|
||||
}
|
||||
>
|
||||
<IconComponent
|
||||
name="Lock"
|
||||
className="form-modal-lock-icon"
|
||||
|
|
@ -38,7 +53,12 @@ const ButtonSendWrapper = ({
|
|||
/>
|
||||
</Case>
|
||||
|
||||
<Case condition={!(lockChat || saveLoading) && !noInput}>
|
||||
<Case
|
||||
condition={
|
||||
!(lockChat || saveLoading || files.some((file) => file.loading)) &&
|
||||
!noInput
|
||||
}
|
||||
>
|
||||
<IconComponent
|
||||
name="LucideSend"
|
||||
className="form-modal-send-icon "
|
||||
|
|
|
|||
|
|
@ -1,7 +1,17 @@
|
|||
import ShortUniqueId from "short-unique-id";
|
||||
import useFileUpload from "./use-file-upload";
|
||||
import useAlertStore from "../../../../../../stores/alertStore";
|
||||
|
||||
const useDragAndDrop = (setIsDragging, setFiles, currentFlowId) => {
|
||||
const fsErrorText =
|
||||
"Please ensure your file has one of the following extensions:";
|
||||
const snErrorTxt = "png, jpg, jpeg, gif, bmp, webp";
|
||||
|
||||
const useDragAndDrop = (
|
||||
setIsDragging,
|
||||
setFiles,
|
||||
currentFlowId,
|
||||
setErrorData,
|
||||
) => {
|
||||
const dragOver = (e) => {
|
||||
e.preventDefault();
|
||||
if (e.dataTransfer.types.some((type) => type === "Files")) {
|
||||
|
|
@ -24,7 +34,7 @@ const useDragAndDrop = (setIsDragging, setFiles, currentFlowId) => {
|
|||
const onDrop = (e) => {
|
||||
e.preventDefault();
|
||||
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
||||
handleFiles(e.dataTransfer.files, setFiles, currentFlowId);
|
||||
handleFiles(e.dataTransfer.files, setFiles, currentFlowId, setErrorData);
|
||||
e.dataTransfer.clearData();
|
||||
}
|
||||
setIsDragging(false);
|
||||
|
|
@ -37,8 +47,19 @@ const useDragAndDrop = (setIsDragging, setFiles, currentFlowId) => {
|
|||
};
|
||||
};
|
||||
|
||||
const handleFiles = (files, setFiles, currentFlowId) => {
|
||||
const handleFiles = (files, setFiles, currentFlowId, setErrorData) => {
|
||||
if (files) {
|
||||
const allowedExtensions = ["png", "jpg", "jpeg", "gif", "bmp", "webp"];
|
||||
const file = files?.[0];
|
||||
const fileExtension = file.name.split(".").pop()?.toLowerCase();
|
||||
if (!fileExtension || !allowedExtensions.includes(fileExtension)) {
|
||||
console.log("Error uploading file");
|
||||
setErrorData({
|
||||
title: "Error uploading file",
|
||||
list: [fsErrorText, snErrorTxt],
|
||||
});
|
||||
return;
|
||||
}
|
||||
const uid = new ShortUniqueId({ length: 3 });
|
||||
const id = uid();
|
||||
const type = files[0].type.split("/")[0];
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ export default function ChatInput({
|
|||
noInput={noInput}
|
||||
saveLoading={saveLoading}
|
||||
chatValue={chatValue}
|
||||
files={files}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export default function ChatView({
|
|||
setLockChat,
|
||||
}: chatViewProps): JSX.Element {
|
||||
const { flowPool, outputs, inputs, CleanFlowPool } = useFlowStore();
|
||||
const { setNoticeData } = useAlertStore();
|
||||
const { setErrorData } = useAlertStore();
|
||||
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
|
||||
const messagesRef = useRef<HTMLDivElement | null>(null);
|
||||
const [chatHistory, setChatHistory] = useState<ChatMessageType[]>([]);
|
||||
|
|
@ -161,6 +161,7 @@ export default function ChatView({
|
|||
setIsDragging,
|
||||
setFiles,
|
||||
currentFlowId,
|
||||
setErrorData,
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue