diff --git a/package.json b/package.json index 593d84459a5..0506158786e 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,8 @@ "nanoid": "3.3.8", "esbuild": "0.25.0", "@babel/helpers": "7.26.10", - "@babel/runtime": "7.26.10" + "@babel/runtime": "7.26.10", + "chokidar": "3.6.0" }, "packageManager": "yarn@1.22.22" } diff --git a/packages/editor/src/core/extensions/custom-image/components/image-block.tsx b/packages/editor/src/core/extensions/custom-image/components/image-block.tsx index 0cc38f5a43a..5dfbad01294 100644 --- a/packages/editor/src/core/extensions/custom-image/components/image-block.tsx +++ b/packages/editor/src/core/extensions/custom-image/components/image-block.tsx @@ -3,7 +3,7 @@ import React, { useRef, useState, useCallback, useLayoutEffect, useEffect } from // plane utils import { cn } from "@plane/utils"; // extensions -import { CustoBaseImageNodeViewProps, ImageToolbarRoot } from "@/extensions/custom-image"; +import { CustomBaseImageNodeViewProps, ImageToolbarRoot } from "@/extensions/custom-image"; import { ImageUploadStatus } from "./upload-status"; const MIN_SIZE = 100; @@ -38,7 +38,7 @@ const ensurePixelString = (value: Pixel | TDefault | number | undefin return value; }; -type CustomImageBlockProps = CustoBaseImageNodeViewProps & { +type CustomImageBlockProps = CustomBaseImageNodeViewProps & { imageFromFileSystem: string | undefined; setFailedToLoadImage: (isError: boolean) => void; editorContainer: HTMLDivElement | null; diff --git a/packages/editor/src/core/extensions/custom-image/components/image-node.tsx b/packages/editor/src/core/extensions/custom-image/components/image-node.tsx index f8bfcf4a1f4..8dfe6974b75 100644 --- a/packages/editor/src/core/extensions/custom-image/components/image-node.tsx +++ b/packages/editor/src/core/extensions/custom-image/components/image-node.tsx @@ -7,7 +7,7 @@ import { CustomImageBlock, CustomImageUploader, ImageAttributes } from "@/extens // helpers import { getExtensionStorage } from "@/helpers/get-extension-storage"; -export type CustoBaseImageNodeViewProps = { +export type CustomBaseImageNodeViewProps = { getPos: () => number; editor: Editor; node: NodeViewProps["node"] & { @@ -17,7 +17,7 @@ export type CustoBaseImageNodeViewProps = { selected: boolean; }; -export type CustomImageNodeProps = NodeViewProps & CustoBaseImageNodeViewProps; +export type CustomImageNodeProps = NodeViewProps & CustomBaseImageNodeViewProps; export const CustomImageNode = (props: CustomImageNodeProps) => { const { getPos, editor, node, updateAttributes, selected } = props; diff --git a/packages/editor/src/core/extensions/custom-image/components/image-uploader.tsx b/packages/editor/src/core/extensions/custom-image/components/image-uploader.tsx index 5af4f556d72..7a7f71f00de 100644 --- a/packages/editor/src/core/extensions/custom-image/components/image-uploader.tsx +++ b/packages/editor/src/core/extensions/custom-image/components/image-uploader.tsx @@ -6,12 +6,14 @@ import { cn } from "@plane/utils"; import { ACCEPTED_IMAGE_MIME_TYPES } from "@/constants/config"; import { CORE_EXTENSIONS } from "@/constants/extension"; // extensions -import { CustoBaseImageNodeViewProps, getImageComponentImageFileMap } from "@/extensions/custom-image"; +import { CustomBaseImageNodeViewProps, getImageComponentImageFileMap } from "@/extensions/custom-image"; +// helpers +import { EFileError } from "@/helpers/file"; +import { getExtensionStorage } from "@/helpers/get-extension-storage"; // hooks import { useUploader, useDropZone, uploadFirstFileAndInsertRemaining } from "@/hooks/use-file-upload"; -import { getExtensionStorage } from "@/helpers/get-extension-storage"; -type CustomImageUploaderProps = CustoBaseImageNodeViewProps & { +type CustomImageUploaderProps = CustomBaseImageNodeViewProps & { maxFileSize: number; loadImageFromFileSystem: (file: string) => void; failedToLoadImage: boolean; @@ -71,23 +73,39 @@ export const CustomImageUploader = (props: CustomImageUploaderProps) => { }, [imageComponentImageFileMap, imageEntityId, updateAttributes, getPos] ); + + const uploadImageEditorCommand = useCallback( + async (file: File) => await editor?.commands.uploadImage(imageEntityId ?? "", file), + [editor, imageEntityId] + ); + + const handleProgressStatus = useCallback( + (isUploading: boolean) => { + getExtensionStorage(editor, CORE_EXTENSIONS.UTILITY).uploadInProgress = isUploading; + }, + [editor] + ); + // hooks const { isUploading: isImageBeingUploaded, uploadFile } = useUploader({ acceptedMimeTypes: ACCEPTED_IMAGE_MIME_TYPES, // @ts-expect-error - TODO: fix typings, and don't remove await from here for now - editorCommand: async (file) => await editor?.commands.uploadImage(imageEntityId, file), - handleProgressStatus: (isUploading) => { - getExtensionStorage(editor, CORE_EXTENSIONS.UTILITY).uploadInProgress = isUploading; - }, + editorCommand: uploadImageEditorCommand, + handleProgressStatus, loadFileFromFileSystem: loadImageFromFileSystem, maxFileSize, onUpload, }); + + const handleInvalidFile = useCallback((_error: EFileError, message: string) => { + alert(message); + }, []); + const { draggedInside, onDrop, onDragEnter, onDragLeave } = useDropZone({ acceptedMimeTypes: ACCEPTED_IMAGE_MIME_TYPES, editor, maxFileSize, - onInvalidFile: (_error, message) => alert(message), + onInvalidFile: handleInvalidFile, pos: getPos(), type: "image", uploader: uploadFile, diff --git a/packages/editor/src/core/hooks/use-file-upload.ts b/packages/editor/src/core/hooks/use-file-upload.ts index e40c1591341..51116fe52bd 100644 --- a/packages/editor/src/core/hooks/use-file-upload.ts +++ b/packages/editor/src/core/hooks/use-file-upload.ts @@ -74,7 +74,15 @@ export const useUploader = (args: TUploaderArgs) => { setIsUploading(false); } }, - [acceptedMimeTypes, editorCommand, handleProgressStatus, loadFileFromFileSystem, maxFileSize, onUpload] + [ + acceptedMimeTypes, + editorCommand, + handleProgressStatus, + loadFileFromFileSystem, + maxFileSize, + onInvalidFile, + onUpload, + ] ); return { isUploading, uploadFile };