diff --git a/CHANGELOG.md b/CHANGELOG.md index 650b3597..a9aec7e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,8 @@ This is a major release, and it might be not compatible with your current usage - toggling on/off the `` was corrected, they kept displayed after re-entering with the cursor - `` - change text overflow for selectors to `clip` because Firefox rendered `ellipsis` a bit too early +- ``: + - `useDropzoneMonitor` helper hook process was improved so that less events are processed and the dropzone monitoring is more stable ### Changed diff --git a/src/components/Application/helper.ts b/src/components/Application/helper.ts index d449c9de..e3907da9 100644 --- a/src/components/Application/helper.ts +++ b/src/components/Application/helper.ts @@ -28,20 +28,48 @@ export const useApplicationHeaderOverModals = (elevate: boolean, className: stri export const useDropzoneMonitor = (enabledTypes: string[]) => { React.useEffect(() => { const monitor = window.document.body; + let timestampMonitorEnabled = 0; + let processDragleave: any; const addMonitor = (event: DragEvent) => { + // stop default, so that also no files cannot executed by browser without demand + event.preventDefault(); + + if (processDragleave) { + // stop removeMonitor process if it happend shortly before + clearTimeout(processDragleave); + } + + // only process if monitor is not already enabled + if (timestampMonitorEnabled > 0) { + return; + } + + // stop the event here to prevent double execution + event.stopImmediatePropagation(); + + // enable monitoring only for supported types of dragged elements const types = event.dataTransfer?.types || []; const monitorTypes = [...new Set(types.filter((type) => enabledTypes.includes(type)))]; if (monitorTypes.length > 0 && !monitor.dataset.monitorDropzone) { monitor.dataset.monitorDropzone = monitorTypes.join(" "); } - event.preventDefault(); + + timestampMonitorEnabled = Date.now(); }; const removeMonitor = (event: DragEvent) => { - if (event.type === "drop" || monitor === event.target) { + const removeAction = () => { delete monitor.dataset.monitorDropzone; event.preventDefault(); + timestampMonitorEnabled = 0; + }; + + if (event.type === "dragleave") { + // use timeout function for dragleave to prevent useless removeMonitor actions + processDragleave = setTimeout(removeAction, 250); + } else { + removeAction(); } };