diff --git a/src/components/comment/CommentForm/index.tsx b/src/components/comment/CommentForm/index.tsx index 6fbdea56..d1a9337e 100644 --- a/src/components/comment/CommentForm/index.tsx +++ b/src/components/comment/CommentForm/index.tsx @@ -14,7 +14,7 @@ import { EMPTY_COMMENT } from '~/redux/node/constants'; import { CommentFormDropzone } from '~/components/comment/CommentFormDropzone'; import styles from './styles.module.scss'; import { ERROR_LITERAL } from '~/constants/errors'; -import { Group } from '~/components/containers/Group'; +import { useInputPasteUpload } from '~/utils/hooks/useInputPasteUpload'; interface IProps { comment?: IComment; @@ -47,6 +47,7 @@ const CommentForm: FC<IProps> = ({ comment, nodeId, onCancelEdit }) => { }, [formik]); const error = formik.status || formik.errors.text; + useInputPasteUpload(textarea, uploader.uploadFiles); return ( <CommentFormDropzone onUpload={uploader.uploadFiles}> diff --git a/src/utils/hooks/useInputPasteUpload.ts b/src/utils/hooks/useInputPasteUpload.ts new file mode 100644 index 00000000..dff574a1 --- /dev/null +++ b/src/utils/hooks/useInputPasteUpload.ts @@ -0,0 +1,24 @@ +import { useCallback, useEffect } from 'react'; +import { getImageFromPaste } from '~/utils/uploader'; + +// useInputPasteUpload attaches event listener to input, that calls onUpload if user pasted any image +export const useInputPasteUpload = ( + input: HTMLTextAreaElement | HTMLInputElement | undefined, + onUpload: (files: File[]) => void +) => { + const onPaste = useCallback(async event => { + const image = await getImageFromPaste(event); + + if (!image) return; + + onUpload([image]); + }, []); + + useEffect(() => { + if (!input) return; + + input.addEventListener('paste', onPaste); + + return () => input.removeEventListener('paste', onPaste); + }, [input, onPaste]); +}; diff --git a/src/utils/uploader.ts b/src/utils/uploader.ts index c1ad5941..3ade4cf8 100644 --- a/src/utils/uploader.ts +++ b/src/utils/uploader.ts @@ -74,3 +74,37 @@ export const fakeUploader = ({ export const getFileType = (file: File): keyof typeof UPLOAD_TYPES | undefined => (file.type && Object.keys(FILE_MIMES).find(mime => FILE_MIMES[mime].includes(file.type))) || undefined; + +// getImageFromPaste returns any images from paste event +export const getImageFromPaste = (event: ClipboardEvent): Promise<File | undefined> => { + const items = event.clipboardData?.items; + + return new Promise(resolve => { + for (let index in items) { + const item = items[index]; + + if (item.kind === 'file' && item.type.match(/^image\//)) { + const blob = item.getAsFile(); + const reader = new FileReader(); + const type = item.type; + + reader.onload = function(e) { + if (!e.target?.result) { + return; + } + + resolve( + new File([e.target?.result], 'paste.png', { + type, + lastModified: new Date().getTime(), + }) + ); + }; + + reader.readAsArrayBuffer(blob); + } + } + + // resolve(undefined); + }); +};