mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-20 12:26:01 +00:00
87 lines
2.4 KiB
TypeScript
87 lines
2.4 KiB
TypeScript
import _ from 'lodash';
|
|
import { isFileDragActive } from '../stores';
|
|
import { fromEvent } from 'file-selector';
|
|
import uploadFiles from './uploadFiles';
|
|
|
|
function isEvtWithFiles(event) {
|
|
if (!event.dataTransfer) {
|
|
return !!event.target && !!event.target.files;
|
|
}
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/types
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#file
|
|
return Array.prototype.some.call(
|
|
event.dataTransfer.types,
|
|
type => type === 'Files' || type === 'application/x-moz-file'
|
|
);
|
|
}
|
|
export default function dragDropFileTarget(node, items) {
|
|
let dragTargetsRef = [];
|
|
|
|
function handleDragEnter(event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
dragTargetsRef = [...dragTargetsRef, event.target];
|
|
|
|
if (isEvtWithFiles(event)) {
|
|
isFileDragActive.set(true);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
function handleDragOver(event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
if (event.dataTransfer) {
|
|
try {
|
|
event.dataTransfer.dropEffect = 'copy';
|
|
} catch {}
|
|
}
|
|
}
|
|
function handleDragLeave(event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
// Only deactivate once the dropzone and all children have been left
|
|
const targets = dragTargetsRef.filter(target => node && node.contains(target));
|
|
// Make sure to remove a target present multiple times only once
|
|
// (Firefox may fire dragenter/dragleave multiple times on the same element)
|
|
const targetIdx = targets.indexOf(event.target);
|
|
if (targetIdx !== -1) {
|
|
targets.splice(targetIdx, 1);
|
|
}
|
|
dragTargetsRef = targets;
|
|
if (targets.length > 0) {
|
|
return;
|
|
}
|
|
|
|
isFileDragActive.set(false);
|
|
}
|
|
async function handleDrop(event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
isFileDragActive.set(false);
|
|
|
|
if (isEvtWithFiles(event)) {
|
|
const files = await fromEvent(event);
|
|
uploadFiles(files);
|
|
}
|
|
}
|
|
|
|
node.addEventListener('dragenter', handleDragEnter);
|
|
node.addEventListener('dragover', handleDragOver);
|
|
node.addEventListener('dragleave', handleDragLeave);
|
|
node.addEventListener('drop', handleDrop);
|
|
|
|
return {
|
|
destroy() {
|
|
node.removeEventListener('dragenter', handleDragEnter);
|
|
node.removeEventListener('dragover', handleDragOver);
|
|
node.removeEventListener('dragleave', handleDragLeave);
|
|
node.removeEventListener('drop', handleDrop);
|
|
},
|
|
};
|
|
}
|