From 7224c837608d9776e5bb78eb3b8090b83e6350c1 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 23 Dec 2021 11:43:26 +0100 Subject: [PATCH] Fix folder upload using drag&drop in the drive --- www/common/drive-ui.js | 202 +++++++++++++++++++------------ www/common/sframe-common-file.js | 5 +- 2 files changed, 127 insertions(+), 80 deletions(-) diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index fcbc6fcf6..303b97b76 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -1857,6 +1857,103 @@ define([ APP.FM.onFileDrop(file, ev); }; + + var traverseFileTree = function (item, path, w, files) { + path = path || ""; + if (item.isFile) { + // Get file + item.file(w(function(file) { + file.fix_path = path + file.name; + files.push(file); + })); + } else if (item.isDirectory) { + // Get folder contents + var dirReader = item.createReader(); + dirReader.readEntries(w(function(entries) { + for (var i=0; i= uploadSteps.length) { return; } + nThen(function (waitFor) { + // add folders + uploadSteps[i].folders.forEach(function (folder) { + var folderPath = folder.split("/"); + var parentFolder = currentFolder.concat(folderPath.slice(0, -1)); + var folderName = folderPath.slice(-1); + manager.addFolder(parentFolder, folderName, waitFor(refresh)); + }); + // upload files + uploadSteps[i].files.forEach(function (file) { + var ev = { + target: $content[0], + path: currentFolder.concat(file.path.slice(0, -1)), + }; + APP.FM.handleFile(file.file, ev, folderUploadOptions); + }); + }).nThen(function () { + stepByStep(uploadSteps, i + 1); + }); + }; + + stepByStep(uploadSteps, 0); + }); + }; + var onDrop = function (ev) { ev.preventDefault(); $('.cp-app-drive-element-droppable').removeClass('cp-app-drive-element-droppable'); @@ -1869,9 +1966,32 @@ define([ return void UI.warn(Messages.fm_forbidden); } - // Don't use the normal drop handler for file upload - var fileDrop = ev.dataTransfer.files; - if (fileDrop.length) { return void onFileDrop(fileDrop, ev); } + var fileDrop = ev.dataTransfer.items; + if (fileDrop.length) { + // Filter out all the folders and use the correct function to upload them + fileDrop = Array.prototype.slice.call(fileDrop).map(function (file) { + if (file.kind !== "file") { return; } + var f = file.getAsFile(); + if (!f.type && f.size % 4096 === 0) { + // It's a folder! + if (0 && file.webkitGetAsEntry) { // IE and Opera don't support it + f = file.webkitGetAsEntry(); + var files = []; + nThen(function (w) { + traverseFileTree(f, "", w, files); + }).nThen(function () { + uploadFolder(files); + }); + return; + } else { + // Folder drop not supported by the browser + } + } + return f; + }).filter(Boolean); + // Continue only with the files + return void onFileDrop(fileDrop, ev); + } var oldPaths = JSON.parse(data).path; if (!oldPaths) { return; } @@ -2680,82 +2800,6 @@ define([ $input.click(); }; - // create the folder structure before to upload files from folder - var uploadFolder = function (fileList) { - var currentFolder = currentPath; - // create an array of all the files relative path - var files = Array.prototype.map.call(fileList, function (file) { - return { - file: file, - path: file.webkitRelativePath.split("/"), - }; - }); - // if folder name already exist in drive, rename it - var uploadedFolderName = files[0].path[0]; - var availableName = manager.user.userObject.getAvailableName(manager.find(currentFolder), uploadedFolderName); - - // ask for folder name and files options, then upload all the files! - APP.FM.showFolderUploadModal(availableName, function (folderUploadOptions) { - if (!folderUploadOptions) { return; } - - // verfify folder name is possible, and update files path - availableName = manager.user.userObject.getAvailableName(manager.find(currentFolder), folderUploadOptions.folderName); - if (uploadedFolderName !== availableName) { - files.forEach(function (file) { - file.path[0] = availableName; - }); - } - - // uploadSteps is an array of objects {folders: [], files: []}, containing all the folders and files to create safely - // at the index i + 1, the files and folders are children of the folders at the index i - var maxSteps = files.reduce(function (max, file) { return Math.max(max, file.path.length); }, 0); - var uploadSteps = []; - for (var i = 0 ; i < maxSteps ; i++) { - uploadSteps[i] = { - folders: [], - files: [], - }; - } - files.forEach(function (file) { - // add steps to create subfolders containing file - for (var depth = 0 ; depth < file.path.length - 1 ; depth++) { - var subfolderStr = file.path.slice(0, depth + 1).join("/"); - if (uploadSteps[depth].folders.indexOf(subfolderStr) === -1) { - uploadSteps[depth].folders.push(subfolderStr); - } - } - // add step to upload file (one step later than the step of its direct parent folder) - uploadSteps[file.path.length - 1].files.push(file); - }); - - // add folders, then add files when theirs folders have been created - // wait for the folders to be created to go to the next step (don't wait for the files) - var stepByStep = function (uploadSteps, i) { - if (i >= uploadSteps.length) { return; } - nThen(function (waitFor) { - // add folders - uploadSteps[i].folders.forEach(function (folder) { - var folderPath = folder.split("/"); - var parentFolder = currentFolder.concat(folderPath.slice(0, -1)); - var folderName = folderPath.slice(-1); - manager.addFolder(parentFolder, folderName, waitFor(refresh)); - }); - // upload files - uploadSteps[i].files.forEach(function (file) { - var ev = { - target: $content[0], - path: currentFolder.concat(file.path.slice(0, -1)), - }; - APP.FM.handleFile(file.file, ev, folderUploadOptions); - }); - }).nThen(function () { - stepByStep(uploadSteps, i + 1); - }); - }; - - stepByStep(uploadSteps, 0); - }); - }; var showUploadFolderModal = function () { var $input = $('', { 'type': 'file', diff --git a/www/common/sframe-common-file.js b/www/common/sframe-common-file.js index f32a497b3..a7e69f05a 100644 --- a/www/common/sframe-common-file.js +++ b/www/common/sframe-common-file.js @@ -447,6 +447,9 @@ define([ type = "text/markdown"; } + // Can't upload folder here + if (!file.type && file.size%4096 === 0) { return; } + var thumb; var preview; var alt; @@ -518,7 +521,7 @@ define([ thumb = thumb64; })); if (file.type === "application/pdf") { return; } - MT.preview(buffer, { + MT.preview(file, { type: file.type, }, void 0, w(function (err, el) { if (err) { return void console.error(err); }