import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/constants'; import { WebApplication } from '@/ui_models/application'; import { AppState } from '@/ui_models/app_state'; import { StreamingFileReader } from '@standardnotes/filepicker'; import { SNNote } from '@standardnotes/snjs'; import { FunctionComponent } from 'preact'; import { useCallback, useEffect, useRef, useState } from 'preact/hooks'; import { AttachedFilesPopover } from './AttachedFilesPopover'; import { PopoverFileItemAction, PopoverFileItemActionType, } from './PopoverFileItemAction'; export enum PopoverTabs { AttachedFiles, AllFiles, } export type PopoverWrapperProps = { application: WebApplication; appState: AppState; note: SNNote; fileActionHandler: (action: PopoverFileItemAction) => Promise; }; export const PopoverDragNDropWrapper: FunctionComponent< PopoverWrapperProps > = ({ fileActionHandler, appState, application, note }) => { const dropzoneRef = useRef(null); const [isDragging, setIsDragging] = useState(false); const [currentTab, setCurrentTab] = useState(PopoverTabs.AttachedFiles); const dragCounter = useRef(0); const handleDrag = (event: DragEvent) => { event.preventDefault(); event.stopPropagation(); }; const handleDragIn = (event: DragEvent) => { event.preventDefault(); event.stopPropagation(); dragCounter.current = dragCounter.current + 1; if (event.dataTransfer?.items.length) { setIsDragging(true); } }; const handleDragOut = (event: DragEvent) => { event.preventDefault(); event.stopPropagation(); dragCounter.current = dragCounter.current - 1; if (dragCounter.current > 0) { return; } setIsDragging(false); }; const handleDrop = useCallback( (event: DragEvent) => { event.preventDefault(); event.stopPropagation(); setIsDragging(false); if (event.dataTransfer?.items.length) { Array.from(event.dataTransfer.items).forEach(async (item) => { let fileOrHandle; if (StreamingFileReader.available()) { fileOrHandle = (await item.getAsFileSystemHandle()) as FileSystemFileHandle; } else { fileOrHandle = item.getAsFile(); } if (fileOrHandle) { const uploadedFiles = await appState.files.uploadNewFile( fileOrHandle ); if (!uploadedFiles) { return; } if (currentTab === PopoverTabs.AttachedFiles) { uploadedFiles.forEach((file) => { fileActionHandler({ type: PopoverFileItemActionType.AttachFileToNote, payload: file, }); }); } } }); event.dataTransfer.clearData(); dragCounter.current = 0; } }, [appState.files, currentTab, fileActionHandler] ); useEffect(() => { const dropzoneElement = dropzoneRef.current; if (dropzoneElement) { dropzoneElement.addEventListener('dragenter', handleDragIn); dropzoneElement.addEventListener('dragleave', handleDragOut); dropzoneElement.addEventListener('dragover', handleDrag); dropzoneElement.addEventListener('drop', handleDrop); } return () => { dropzoneElement?.removeEventListener('dragenter', handleDragIn); dropzoneElement?.removeEventListener('dragleave', handleDragOut); dropzoneElement?.removeEventListener('dragover', handleDrag); dropzoneElement?.removeEventListener('drop', handleDrop); }; }, [handleDrop]); return (
); };