summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2015-09-28 17:50:11 +0200
committerVincent Petry <pvince81@owncloud.com>2015-09-28 17:50:11 +0200
commitcc8efaa037fdf186f413beadd1ed1ab49d2f6756 (patch)
tree4d9e60ae1f289353701dec3ddd21ecc1322b42ad
parentd68079f93210f8fe0b5327e686497db97fde6a3e (diff)
downloadnextcloud-server-cc8efaa037fdf186f413beadd1ed1ab49d2f6756.tar.gz
nextcloud-server-cc8efaa037fdf186f413beadd1ed1ab49d2f6756.zip
Show conflict dialog before upload when possible
When uploading files, first check if the files exist in the current file list. For the ones that do, show a conflict dialog. For the rest, upload directly. If the upload operation detects a conflict on the server side, it will also continue populating the conflict dialog. From now on, server side conflict can only occur if someone concurrently uploaded a file into the same folder but the current user hasn't refreshed the list yet.
-rw-r--r--apps/files/js/file-upload.js65
-rw-r--r--apps/files/js/filelist.js21
2 files changed, 64 insertions, 22 deletions
diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js
index 17f0f777169..03330ad7c5d 100644
--- a/apps/files/js/file-upload.js
+++ b/apps/files/js/file-upload.js
@@ -18,7 +18,7 @@
* - TODO music upload button
*/
-/* global Files, FileList, jQuery, oc_requesttoken, humanFileSize, getUniqueName */
+/* global jQuery, oc_requesttoken, humanFileSize */
/**
* Function that will allow us to know if Ajax uploads are supported
@@ -139,6 +139,9 @@ OC.Upload = {
if (data.data) {
data.data.append('resolution', 'replace');
} else {
+ if (!data.formData) {
+ data.formData = [];
+ }
data.formData.push({name:'resolution', value:'replace'}); //hack for ie8
}
data.submit();
@@ -152,6 +155,9 @@ OC.Upload = {
if (data.data) {
data.data.append('resolution', 'autorename');
} else {
+ if (!data.formData) {
+ data.formData = [];
+ }
data.formData.push({name:'resolution', value:'autorename'}); //hack for ie8
}
data.submit();
@@ -164,8 +170,9 @@ OC.Upload = {
}
},
/**
- * TODO checks the list of existing files prior to uploading and shows a simple dialog to choose
+ * checks the list of existing files prior to uploading and shows a simple dialog to choose
* skip all, replace all or choose which files to keep
+ *
* @param {array} selection of files to upload
* @param {object} callbacks - object with several callback methods
* @param {function} callbacks.onNoConflicts
@@ -175,14 +182,34 @@ OC.Upload = {
* @param {function} callbacks.onCancel
*/
checkExistingFiles: function (selection, callbacks) {
- /*
- $.each(selection.uploads, function(i, upload) {
- var $row = OCA.Files.App.fileList.findFileEl(upload.files[0].name);
- if ($row) {
- // TODO check filelist before uploading and show dialog on conflicts, use callbacks
+ var fileList = OCA.Files.App.fileList;
+ var conflicts = [];
+ // only keep non-conflicting uploads
+ selection.uploads = _.filter(selection.uploads, function(upload) {
+ var fileInfo = fileList.findFile(upload.files[0].name);
+ if (fileInfo) {
+ conflicts.push([
+ // original
+ _.extend(fileInfo, {
+ directory: fileInfo.directory || fileInfo.path || fileList.getCurrentDirectory()
+ }),
+ // replacement (File object)
+ upload
+ ]);
+ return false;
}
+ return true;
});
- */
+ if (conflicts.length) {
+ _.each(conflicts, function(conflictData) {
+ OC.dialogs.fileexists(conflictData[1], conflictData[0], conflictData[1].files[0], OC.Upload);
+ });
+ }
+
+ // upload non-conflicting files
+ // note: when reaching the server they might still meet conflicts
+ // if the folder was concurrently modified, these will get added
+ // to the already visible dialog, if applicable
callbacks.onNoConflicts(selection);
},
@@ -368,18 +395,18 @@ OC.Upload = {
},
submit: function(e, data) {
OC.Upload.rememberUpload(data);
- if ( ! data.formData ) {
- var fileDirectory = '';
- if(typeof data.files[0].relativePath !== 'undefined') {
- fileDirectory = data.files[0].relativePath;
- }
- // noone set update parameters, we set the minimum
- data.formData = {
- requesttoken: oc_requesttoken,
- dir: data.targetDir || FileList.getCurrentDirectory(),
- file_directory: fileDirectory
- };
+ if (!data.formData) {
+ data.formData = [];
+ }
+
+ var fileDirectory = '';
+ if(typeof data.files[0].relativePath !== 'undefined') {
+ fileDirectory = data.files[0].relativePath;
}
+ // FIXME: prevent re-adding the same
+ data.formData.push({name: 'requesttoken', value: oc_requesttoken});
+ data.formData.push({name: 'dir', value: data.targetDir || FileList.getCurrentDirectory()});
+ data.formData.push({name: 'file_directory', value: fileDirectory});
},
fail: function(e, data) {
OC.Upload.log('fail', e, data);
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index e4a7aadd600..1b069530e69 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -719,8 +719,23 @@
return true;
},
/**
- * Returns the tr element for a given file name
- * @param fileName file name
+ * Returns the file info for the given file name from the internal collection.
+ *
+ * @param {string} fileName file name
+ * @return {OCA.Files.FileInfo} file info or null if it was not found
+ *
+ * @since 8.2
+ */
+ findFile: function(fileName) {
+ return _.find(this.files, function(aFile) {
+ return (aFile.name === fileName);
+ }) || null;
+ },
+ /**
+ * Returns the tr element for a given file name, but only if it was already rendered.
+ *
+ * @param {string} fileName file name
+ * @return {Object} jQuery object of the matching row
*/
findFileEl: function(fileName){
// use filterAttr to avoid escaping issues
@@ -1877,7 +1892,7 @@
* @return {bool} true if the file exists in the list, false otherwise
*/
inList:function(file) {
- return this.findFileEl(file).length;
+ return this.findFile(file);
},
/**