Skip to content

Commit

Permalink
improve hook for dropzone monitoring, make it more stable by removing…
Browse files Browse the repository at this point in the history
… processing of unnecessary event calls
  • Loading branch information
haschek committed Dec 12, 2024
1 parent 9c33568 commit efff26d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ This is a major release, and it might be not compatible with your current usage
- toggling on/off the `<HandleTools/>` was corrected, they kept displayed after re-entering with the cursor
- `<Pagination/>`
- change text overflow for selectors to `clip` because Firefox rendered `ellipsis` a bit too early
- `<ApplicationContainer />`:
- `useDropzoneMonitor` helper hook process was improved so that less events are processed and the dropzone monitoring is more stable

### Changed

Expand Down
32 changes: 30 additions & 2 deletions src/components/Application/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
};

Expand Down

0 comments on commit efff26d

Please sign in to comment.