Fix folder upload using drag&drop in the drive

pull/1/head
yflory 3 years ago
parent 4f7d3af1cd
commit 7224c83760

@ -1857,6 +1857,103 @@ define([
APP.FM.onFileDrop(file, ev); 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<entries.length; i++) {
traverseFileTree(entries[i], path + item.name + "/", w, files);
}
}));
}
};
// 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 || file.fix_path).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 onDrop = function (ev) { var onDrop = function (ev) {
ev.preventDefault(); ev.preventDefault();
$('.cp-app-drive-element-droppable').removeClass('cp-app-drive-element-droppable'); $('.cp-app-drive-element-droppable').removeClass('cp-app-drive-element-droppable');
@ -1869,9 +1966,32 @@ define([
return void UI.warn(Messages.fm_forbidden); return void UI.warn(Messages.fm_forbidden);
} }
// Don't use the normal drop handler for file upload var fileDrop = ev.dataTransfer.items;
var fileDrop = ev.dataTransfer.files; if (fileDrop.length) {
if (fileDrop.length) { return void onFileDrop(fileDrop, ev); } // 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; var oldPaths = JSON.parse(data).path;
if (!oldPaths) { return; } if (!oldPaths) { return; }
@ -2680,82 +2800,6 @@ define([
$input.click(); $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 showUploadFolderModal = function () {
var $input = $('<input>', { var $input = $('<input>', {
'type': 'file', 'type': 'file',

@ -447,6 +447,9 @@ define([
type = "text/markdown"; type = "text/markdown";
} }
// Can't upload folder here
if (!file.type && file.size%4096 === 0) { return; }
var thumb; var thumb;
var preview; var preview;
var alt; var alt;
@ -518,7 +521,7 @@ define([
thumb = thumb64; thumb = thumb64;
})); }));
if (file.type === "application/pdf") { return; } if (file.type === "application/pdf") { return; }
MT.preview(buffer, { MT.preview(file, {
type: file.type, type: file.type,
}, void 0, w(function (err, el) { }, void 0, w(function (err, el) {
if (err) { return void console.error(err); } if (err) { return void console.error(err); }

Loading…
Cancel
Save