UNPKG

io3fix

Version:

toolkit for interior apps

135 lines (118 loc) 4.92 kB
import Promise from 'bluebird' import runtime from '../../core/runtime.js' import configs from '../../core/configs.js' import putToStore from '../../storage/put.js' import getFilesFromDragAndDropEvent from './create-file-drop-ui/get-files-from-drag-and-drop-event.js' // main export default function createFileDropUi (args) { runtime.assertBrowser() // API // html var elementId = args.elementId var onInput = args.onInput var dragOverCssClass = args.dragOverCssClass // drag events var onDragEnter = args.onDragEnter var onDragLeave = args.onDragLeave // upload related var upload = args.upload !== undefined ? args.upload : true var onUploadProgress = args.onUploadProgress var uploadProgressBarCss = args.uploadProgressBarCss || 'background: rgba(0,0,0,0.2);' // DOM // get reference to main DOM element var mainEl = document.getElementById(elementId) if (!mainEl) { console.error('file drop ui could not be created, element not found:', elementId) return } // input allows selecting files on click var fileInputEl = document.createElement('input') fileInputEl.setAttribute('type', 'file') fileInputEl.setAttribute('multiple', true) fileInputEl.setAttribute('style', 'cursor:pointer; position:absolute; top:0; left:0; height:100%; width:100%; opacity:0;') mainEl.appendChild(fileInputEl) // progress bar var progressBarEl = document.createElement('div') progressBarEl.setAttribute('style', 'position:absolute; top:0; left:0; bottom:0; width:0; transition: width 1s linear;'+uploadProgressBarCss) if(mainEl.style.position === null) mainEl.style.position = 'relative' mainEl.appendChild(progressBarEl) // events function dragEnter (event) { if (dragOverCssClass) mainEl.classList.add(dragOverCssClass) if (onDragEnter) onDragEnter(event) preventBrowserDefaults(event) } function dragLeave (event) { if (dragOverCssClass) mainEl.classList.remove(dragOverCssClass) if (onDragLeave) onDragLeave(event) preventBrowserDefaults(event) } function dropFiles (event) { if (dragOverCssClass) mainEl.classList.remove(dragOverCssClass) preventBrowserDefaults(event) getFilesFromDragAndDropEvent(event, { checkExtension: upload ? true : false // check extension only when uploading files }).then(function (files) { handleFileInput(files, event) }).catch(console.error) } function selectFiles (event) { // convert FileList into array // https://developer.mozilla.org/en/docs/Web/API/FileList var files = [], fileList = event.target.files for (var i = 0; i < fileList.length; i++) files[i] = fileList[i] handleFileInput(files, event) } function handleFileInput(files, event) { // uploading files is optional (upload ? uploadFiles(files) : Promise.resolve()).then(function(storageIds){ // create convenient collection with file info including storageIds if available var fileCollection = files.map(function(file, i){ var item = { file: file, name: file.name, size: file.size, type: file.type } if (storageIds) { item.storageId = storageIds[i] item.url = 'https://' + configs.storageDomain + storageIds[i] } return item }) onInput(fileCollection, event) }) } function uploadFiles (files) { progressBarEl.style.width = '0' progressBarEl.style.display = 'block' return putToStore(files, { onProgress: function onProgress(uploaded, total) { progressBarEl.style.width = Math.min(100, Math.round(100 * (uploaded / total))) + '%' if (onUploadProgress) onUploadProgress(uploaded, total) } }).then(function (storageIds) { progressBarEl.style.display = 'none' progressBarEl.style.width = '0' return storageIds }) } // events fired on the draggable target // document.addEventListener("drag", function( event ) {}, false) // document.addEventListener("dragstart", function( event ) {}, false) // document.addEventListener("dragend", function( event ) {}, false) // prevent events on window drop window.addEventListener('dragover', preventBrowserDefaults, false) window.addEventListener('drop', preventBrowserDefaults, false) // events fired on the drop targets fileInputEl.addEventListener('dragover', function (event) { preventBrowserDefaults(event) event.dataTransfer.dropEffect = 'copy' // // adds a little "+" to mouse cursor }, false) fileInputEl.addEventListener('dragenter', dragEnter, false) fileInputEl.addEventListener('dragleave', dragLeave, false) fileInputEl.addEventListener('dragend', dragLeave, false) fileInputEl.addEventListener('drop', dropFiles, false) // events from input element fileInputEl.addEventListener('change', selectFiles, false) } // helpers function preventBrowserDefaults (event) { event.stopPropagation() event.preventDefault() }