Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 75 lines 2.3 kB view raw
1import { MAX_IMAGE_UPLOAD } from "@hey/data/constants"; 2import { defineDOMEventHandler, type Editor, union } from "prosekit/core"; 3import { useExtension } from "prosekit/react"; 4import { useCallback, useEffect, useMemo, useRef } from "react"; 5import { toast } from "sonner"; 6import type { EditorExtension } from "@/helpers/prosekit/extension"; 7import useUploadAttachments from "@/hooks/useUploadAttachments"; 8import { usePostAttachmentStore } from "@/store/non-persisted/post/usePostAttachmentStore"; 9 10const handleFiles = ( 11 event: Event, 12 files: FileList | null | undefined, 13 onPaste: (files: FileList) => void 14): boolean => { 15 if (files?.length) { 16 event.preventDefault(); 17 onPaste(files); 18 return true; 19 } 20 return false; 21}; 22 23const definePasteDropExtension = (onPaste: (files: FileList) => void) => { 24 const dropExtension = defineDOMEventHandler("drop", (_view, event): boolean => 25 handleFiles(event, event?.dataTransfer?.files, onPaste) 26 ); 27 28 const pasteExtension = defineDOMEventHandler( 29 "paste", 30 (_view, event): boolean => { 31 if (event?.clipboardData?.getData("Text")) { 32 return false; // Ignore text pastes 33 } 34 return handleFiles(event, event?.clipboardData?.files, onPaste); 35 } 36 ); 37 38 return union([dropExtension, pasteExtension]); 39}; 40 41export const usePaste = (editor: Editor<EditorExtension>) => { 42 const { attachments } = usePostAttachmentStore(); 43 const { handleUploadAttachments } = useUploadAttachments(); 44 45 const handlePaste = useCallback( 46 async (pastedFiles: FileList) => { 47 const totalAttachments = attachments.length + pastedFiles.length; 48 if ( 49 attachments.length === MAX_IMAGE_UPLOAD || 50 totalAttachments > MAX_IMAGE_UPLOAD 51 ) { 52 return toast.error( 53 `Please choose either 1 video or up to ${MAX_IMAGE_UPLOAD} photos.` 54 ); 55 } 56 57 if (pastedFiles) { 58 await handleUploadAttachments(pastedFiles); 59 } 60 }, 61 [handleUploadAttachments, attachments.length] 62 ); 63 64 const handlePasteRef = useRef(handlePaste); 65 66 useEffect(() => { 67 handlePasteRef.current = handlePaste; 68 }, [handlePaste]); 69 70 const extension = useMemo(() => { 71 return definePasteDropExtension((files) => handlePasteRef.current(files)); 72 }, []); 73 74 useExtension(extension, { editor }); 75};