Support drag-and-drop file publishing #4170
2 changed files with 98 additions and 1 deletions
|
@ -1218,4 +1218,4 @@
|
|||
"Check your rewards page to see if you qualify for paid content reimbursement. Only content in this section qualifies.": "Check your rewards page to see if you qualify for paid content reimbursement. Only content in this section qualifies.",
|
||||
"blocked channels": "blocked channels",
|
||||
"%count% %channels%. ": "%count% %channels%. "
|
||||
}
|
||||
}
|
||||
|
|
97
ui/effects/use-drag-drop.js
Normal file
97
ui/effects/use-drag-drop.js
Normal file
|
@ -0,0 +1,97 @@
|
|||
import React from 'react';
|
||||
|
||||
const LISTENER = {
|
||||
ADD: 'add',
|
||||
REMOVE: 'remove',
|
||||
};
|
||||
|
||||
const DRAG_TYPES = {
|
||||
END: 'dragend',
|
||||
START: 'dragstart',
|
||||
ENTER: 'dragenter',
|
||||
LEAVE: 'dragleave',
|
||||
};
|
||||
|
||||
const DRAG_SCORE = {
|
||||
[DRAG_TYPES.ENTER]: 1,
|
||||
[DRAG_TYPES.LEAVE]: -1,
|
||||
};
|
||||
|
||||
const DRAG_STATE = {
|
||||
[DRAG_TYPES.END]: false,
|
||||
[DRAG_TYPES.START]: true,
|
||||
};
|
||||
|
||||
// Returns simple detection for global drag-drop
|
||||
export default function useFetched() {
|
||||
const [drag, setDrag] = React.useState(false);
|
||||
const [drop, setDrop] = React.useState(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
let dragCount = 0;
|
||||
let draggingElement = false;
|
||||
|
||||
// Handle file drop
|
||||
const handleDropEvent = event => {
|
||||
// Ignore non file types ( html elements / text )
|
||||
if (!draggingElement) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
// Get files
|
||||
const files = event.dataTransfer.files;
|
||||
// Store files in state
|
||||
if (files.length && files.length > 0) {
|
||||
setDrop(files);
|
||||
}
|
||||
}
|
||||
// Reset state ( hide drop zone )
|
||||
dragCount = 0;
|
||||
setDrag(false);
|
||||
};
|
||||
|
||||
// Drag event for non files type ( html elements / text )
|
||||
const handleDragElementEvent = event => {
|
||||
draggingElement = DRAG_STATE[event.type];
|
||||
};
|
||||
|
||||
// Drag events
|
||||
const handleDragEvent = event => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
// Prevent multiple drop areas
|
||||
dragCount += DRAG_SCORE[event.type];
|
||||
// Dragged file enters the drop area
|
||||
if (dragCount === 1 && !draggingElement && event.type === DRAG_TYPES.ENTER) {
|
||||
setDrag(true);
|
||||
}
|
||||
// Dragged file leaves the drop area
|
||||
if (dragCount === 0 && event.type === DRAG_TYPES.LEAVE) {
|
||||
setDrag(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Register / Unregister listeners
|
||||
const handleEventListeners = event => {
|
||||
const action = `${event}EventListener`;
|
||||
// Handle drop event
|
||||
document[action]('drop', handleDropEvent);
|
||||
// Handle drag events
|
||||
document[action](DRAG_TYPES.ENTER, handleDragEvent);
|
||||
document[action](DRAG_TYPES.LEAVE, handleDragEvent);
|
||||
// Handle non files drag events
|
||||
document[action](DRAG_TYPES.END, handleDragElementEvent);
|
||||
document[action](DRAG_TYPES.START, handleDragElementEvent);
|
||||
};
|
||||
// On component mounted:
|
||||
// Register event listeners
|
||||
handleEventListeners(LISTENER.ADD);
|
||||
|
||||
// On component unmounted:
|
||||
return () => {
|
||||
// Unregister event listeners
|
||||
handleEventListeners(LISTENER.REMOVE);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return { drag, drop };
|
||||
}
|
Loading…
Add table
Reference in a new issue