diff options
author | Jörn Friedrich Dreyer <jfd@butonic.de> | 2013-08-22 14:29:00 +0200 |
---|---|---|
committer | Jörn Friedrich Dreyer <jfd@butonic.de> | 2013-08-22 14:29:00 +0200 |
commit | 7c9d9992432839f2265b8f6b0f43ed15bfca9ff1 (patch) | |
tree | e286efb0aedb2c0227e8bac2e30e8c74327832d2 /apps | |
parent | bf04daff82758fe9913c706eef07aed30c9b35ea (diff) | |
download | nextcloud-server-7c9d9992432839f2265b8f6b0f43ed15bfca9ff1.tar.gz nextcloud-server-7c9d9992432839f2265b8f6b0f43ed15bfca9ff1.zip |
reduced complexity, added listing conflicts to dialog
Diffstat (limited to 'apps')
-rw-r--r-- | apps/files/ajax/upload.php | 1 | ||||
-rw-r--r-- | apps/files/css/files.css | 53 | ||||
-rw-r--r-- | apps/files/js/file-upload.js | 226 |
3 files changed, 201 insertions, 79 deletions
diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php index 619b5f6a04b..218482cb41d 100644 --- a/apps/files/ajax/upload.php +++ b/apps/files/ajax/upload.php @@ -131,6 +131,7 @@ if (strpos($dir, '..') === false) { $result[] = array('status' => 'success', 'mime' => $meta['mimetype'], + 'mtime' => $meta['mtime'], 'size' => $meta['size'], 'id' => $meta['fileid'], 'name' => basename($target), diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 0ff25a24d76..dcd6aeadf82 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -193,28 +193,54 @@ table.dragshadow td.size { .oc-dialog .fileexists table { width: 100%; } -.oc-dialog .fileexists .original .icon { +.oc-dialog .fileexists th { + padding-left: 0; + padding-right: 0; +} +.oc-dialog .fileexists th input[type='checkbox'] { + margin-right: 3px; +} +.oc-dialog .fileexists th:first-child { + width: 235px; +} +.oc-dialog .fileexists th label { + font-weight: normal; + color:black; +} +.oc-dialog .fileexists th .count { + margin-left: 3px; +} +.oc-dialog .fileexists .conflict { + width: 100%; + height: 85px; +} +.oc-dialog .fileexists .conflict .filename { + color:#777; + word-break: break-all; +} +.oc-dialog .fileexists .icon { width: 64px; height: 64px; - margin: 5px 5px 5px 0px; + margin: 0px 5px 5px 5px; background-repeat: no-repeat; background-size: 64px 64px; float: left; } .oc-dialog .fileexists .replacement { - margin-top: 20px; - margin-bottom: 20px; + float: left; + width: 235px; } - -.oc-dialog .fileexists .replacement .icon { - width: 64px; - height: 64px; - margin: 5px 5px 5px 0px; - background-repeat: no-repeat; - background-size: 64px 64px; +.oc-dialog .fileexists .original { + float: left; + width: 235px; +} +.oc-dialog .fileexists .conflict-wrapper { + overflow-y:scroll; + max-height: 225px; +} +.oc-dialog .fileexists .conflict-wrapper input[type='checkbox'] { float: left; - clear: both; } .oc-dialog .fileexists .toggle { @@ -234,9 +260,6 @@ table.dragshadow td.size { vertical-align: bottom; } -.oc-dialog .fileexists h3 { - font-weight: bold; -} .oc-dialog .oc-dialog-buttonrow { diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js index c620942170c..ec8c97ff457 100644 --- a/apps/files/js/file-upload.js +++ b/apps/files/js/file-upload.js @@ -1,5 +1,44 @@ /** * + * and yet another idea how to handle file uploads: + * let the jquery fileupload thing handle as much as possible + * + * use singlefileupload + * on first add of every selection + * - check all files of originalFiles array with files in dir + * - on conflict show dialog + * - skip all -> remember as default action + * - replace all -> remember as default action + * - choose -> show choose dialog + * - mark files to keep + * - when only existing -> remember as single skip action + * - when only new -> remember as single replace action + * - when both -> remember as single autorename action + * - start uploading selection + * + * on send + * - if single action or default action + * - when skip -> abort upload + * ..- when replace -> add replace=true parameter + * ..- when rename -> add newName=filename parameter + * ..- when autorename -> add autorename=true parameter + * + * on fail + * - if server sent existserror + * - show dialog + * - on skip single -> abort single upload + * - on skip always -> remember as default action + * - on replace single -> replace single upload + * - on replace always -> remember as default action + * - on rename single -> rename single upload, propose autorename - when changed disable remember always checkbox + * - on rename always -> remember autorename as default action + * - resubmit data + * + * on uplad done + * - if last upload -> unset default action + * + * ------------------------------------------------------------- + * * use put t ocacnel upload before it starts? use chunked uploads? * * 1. tracking which file to upload next -> upload queue with data elements added whenever add is called @@ -202,11 +241,11 @@ OC.Upload = { data.submit(); }, logStatus:function(caption, e, data) { - console.log(caption+' ' +OC.Upload.loadedBytes()+' / '+OC.Upload.totalBytes()); - if (data) { - console.log(data); - } - console.log(e); + console.log(caption); + console.log(data); + }, + checkExistingFiles: function (selection, callbacks){ + callbacks.onNoConflicts(selection); } }; @@ -214,44 +253,110 @@ $(document).ready(function() { var file_upload_param = { dropZone: $('#content'), // restrict dropZone to content div + autoUpload: false, + sequentialUploads: true, //singleFileUploads is on by default, so the data.files array will always have length 1 + /** + * on first add of every selection + * - check all files of originalFiles array with files in dir + * - on conflict show dialog + * - skip all -> remember as single skip action for all conflicting files + * - replace all -> remember as single replace action for all conflicting files + * - choose -> show choose dialog + * - mark files to keep + * - when only existing -> remember as single skip action + * - when only new -> remember as single replace action + * - when both -> remember as single autorename action + * - start uploading selection + * @param {type} e + * @param {type} data + * @returns {Boolean} + */ add: function(e, data) { OC.Upload.logStatus('add', e, data); var that = $(this); - // lookup selection for dir - var selection = OC.Upload.getSelection(data.originalFiles); + // we need to collect all data upload objects before starting the upload so we can check their existence + // and set individual conflict actions. unfortunately there is only one variable that we can use to identify + // the selection a data upload is part of, so we have to collect them in data.originalFiles + // turning singleFileUploads off is not an option because we want to gracefully handle server errors like + // already exists - if (!selection.dir) { - selection.dir = $('#dir').val(); + // create a container where we can store the data objects + if ( ! data.originalFiles.selection ) { + // initialize selection and remember number of files to upload + data.originalFiles.selection = { + uploads: [], + filesToUpload: data.originalFiles.length, + totalBytes: 0 + }; } + var selection = data.originalFiles.selection; - if ( ! selection.checked ) { + // add uploads + if ( selection.uploads.length < selection.filesToUpload ){ + // remember upload + selection.uploads.push(data); + } + + //examine file + var file = data.files[0]; + + if (file.type === '' && file.size === 4096) { + data.textStatus = 'dirorzero'; + data.errorThrown = t('files', 'Unable to upload {filename} as it is a directory or has 0 bytes', + {filename: file.name} + ); + } + + // add size + selection.totalBytes += file.size; + + //check max upload size + if (selection.totalBytes > $('#max_upload').val()) { + data.textStatus = 'notenoughspace'; + data.errorThrown = t('files', 'Not enough space available'); + } + + // end upload for whole selection on error + if (data.errorThrown) { + // trigger fileupload fail + var fu = that.data('blueimp-fileupload') || that.data('fileupload'); + fu._trigger('fail', e, data); + return false; //don't upload anything + } + + // check existing files whan all is collected + if ( selection.uploads.length >= selection.filesToUpload ) { - selection.totalBytes = 0; - $.each(data.originalFiles, function(i, file) { - selection.totalBytes += file.size; + //remove our selection hack: + delete data.originalFiles.selection; - if (file.type === '' && file.size === 4096) { - data.textStatus = 'dirorzero'; - data.errorThrown = t('files', 'Unable to upload {filename} as it is a directory or has 0 bytes', - {filename: file.name} - ); - return false; + var callbacks = { + + onNoConflicts: function (selection) { + $.each(selection.uploads, function(i, upload) { + upload.submit(); + }); + }, + onSkipConflicts: function (selection) { + //TODO mark conflicting files as toskip + }, + onReplaceConflicts: function (selection) { + //TODO mark conflicting files as toreplace + }, + onChooseConflicts: function (selection) { + //TODO mark conflicting files as chosen + }, + onCancel: function (selection) { + $.each(selection.uploads, function(i, upload) { + upload.abort(); + }); } - }); + }; - if (selection.totalBytes > $('#max_upload').val()) { - data.textStatus = 'notenoughspace'; - data.errorThrown = t('files', 'Not enough space available'); - } - if (data.errorThrown) { - //don't upload anything - var fu = that.data('blueimp-fileupload') || that.data('fileupload'); - fu._trigger('fail', e, data); - return false; - } + OC.Upload.checkExistingFiles(selection, callbacks); //TODO refactor away: //show cancel button @@ -259,15 +364,8 @@ $(document).ready(function() { $('#uploadprogresswrapper input.stop').show(); } } + - //all subsequent add calls for this selection can be ignored - //allow navigating to the selection from a context - //context.selection = data.originalFiles.selection; - - //allow navigating to contexts / files of a selection - selection.files[data.files[0].name] = data; - - OC.Upload.queueUpload(data); //TODO check filename already exists /* @@ -283,7 +381,7 @@ $(document).ready(function() { } */ - return true; + return true; // continue adding files }, /** * called after the first add, does NOT have the data param @@ -314,8 +412,8 @@ $(document).ready(function() { $('#notification').fadeOut(); }, 5000); } - var selection = OC.Upload.getSelection(data.originalFiles); - OC.Upload.deleteSelectionUpload(selection, data.files[0].name); + //var selection = OC.Upload.getSelection(data.originalFiles); + //OC.Upload.deleteSelectionUpload(selection, data.files[0].name); //if user pressed cancel hide upload progress bar and cancel button if (data.errorThrown === 'abort') { @@ -339,8 +437,8 @@ $(document).ready(function() { if($('html.lte9').length > 0) { return; } - //var progress = (data.loaded/data.total)*100; - var progress = OC.Upload.progressBytes(); + var progress = (data.loaded/data.total)*100; + //var progress = OC.Upload.progressBytes(); $('#uploadprogressbar').progressbar('value', progress); }, /** @@ -359,15 +457,15 @@ $(document).ready(function() { response = data.result[0].body.innerText; } var result=$.parseJSON(response); - var selection = OC.Upload.getSelection(data.originalFiles); + //var selection = OC.Upload.getSelection(data.originalFiles); if(typeof result[0] !== 'undefined' && result[0].status === 'success' ) { - if (selection) { - selection.loadedBytes+=data.loaded; - } - OC.Upload.nextUpload(); + //if (selection) { + // selection.loadedBytes+=data.loaded; + //} + //OC.Upload.nextUpload(); } else { if (result[0].status === 'existserror') { //show "file already exists" dialog @@ -385,10 +483,10 @@ $(document).ready(function() { } //if user pressed cancel hide upload chrome - if (! OC.Upload.isProcessing()) { - $('#uploadprogresswrapper input.stop').fadeOut(); - $('#uploadprogressbar').fadeOut(); - } + //if (! OC.Upload.isProcessing()) { + // $('#uploadprogresswrapper input.stop').fadeOut(); + // $('#uploadprogressbar').fadeOut(); + //} }, /** @@ -398,27 +496,27 @@ $(document).ready(function() { */ stop: function(e, data) { OC.Upload.logStatus('stop', e, data); - if(OC.Upload.progressBytes()>=100) { //only hide controls when all selections have ended uploading + //if(OC.Upload.progressBytes()>=100) { //only hide controls when all selections have ended uploading - OC.Upload.cancelUploads(); //cleanup + //OC.Upload.cancelUploads(); //cleanup - if(data.dataType !== 'iframe') { - $('#uploadprogresswrapper input.stop').hide(); - } + // if(data.dataType !== 'iframe') { + // $('#uploadprogresswrapper input.stop').hide(); + // } //IE < 10 does not fire the necessary events for the progress bar. if($('html.lte9').length > 0) { return; } - $('#uploadprogressbar').progressbar('value', 100); - $('#uploadprogressbar').fadeOut(); - } + // $('#uploadprogressbar').progressbar('value', 100); + // $('#uploadprogressbar').fadeOut(); + //} //if user pressed cancel hide upload chrome - if (! OC.Upload.isProcessing()) { - $('#uploadprogresswrapper input.stop').fadeOut(); - $('#uploadprogressbar').fadeOut(); - } + //if (! OC.Upload.isProcessing()) { + // $('#uploadprogresswrapper input.stop').fadeOut(); + // $('#uploadprogressbar').fadeOut(); + //} } }; |