diff --git a/files/renderer.php b/files/renderer.php
index 8d7c34e16d8..fe5415ab8e5 100644
--- a/files/renderer.php
+++ b/files/renderer.php
@@ -223,6 +223,7 @@ class core_files_renderer extends plugin_renderer_base {
'.$strdndenabledinbox.'
'.$strdroptoupload.'
+
'.$icon_progress.'
'.$icon_progress.'
diff --git a/lib/form/dndupload.js b/lib/form/dndupload.js
index 1e68cc8faf2..3a3a4b175e3 100644
--- a/lib/form/dndupload.js
+++ b/lib/form/dndupload.js
@@ -54,6 +54,8 @@ M.form_dndupload.init = function(Y, options) {
// dragenter+dragleave(moving between child elements) and dragleave (leaving element)
entercount: 0,
pageentercount: 0,
+ // Holds the progress bar elements for each file.
+ progressbars: {},
/**
* Initalise the drag and drop upload interface
@@ -316,8 +318,12 @@ M.form_dndupload.init = function(Y, options) {
repositoryid: this.repositoryid,
currentfilecount: this.filemanager.filecount, // All files uploaded.
currentfiles: this.filemanager.options.list, // Only the current folder.
- callback: Y.bind('update_filemanager', this)
+ callback: Y.bind('update_filemanager', this),
+ callbackprogress: Y.bind('update_progress', this),
+ callbackcancel:Y.bind('hide_progress', this)
};
+ this.clear_progress();
+ this.show_progress();
var uploader = new dnduploader(options);
uploader.start_upload();
} else {
@@ -328,8 +334,12 @@ M.form_dndupload.init = function(Y, options) {
repositoryid: this.repositoryid,
currentfilecount: 0,
currentfiles: [],
- callback: Y.bind('callback', this)
+ callback: Y.bind('update_filemanager', this),
+ callbackprogress: Y.bind('update_progress', this),
+ callbackcancel:Y.bind('hide_progress', this)
};
+ this.clear_progress();
+ this.show_progress();
uploader = new dnduploader(options);
uploader.start_upload();
}
@@ -379,15 +389,68 @@ M.form_dndupload.init = function(Y, options) {
this.container.removeClass('dndupload-over');
},
+ /**
+ * Show the element showing the upload in progress
+ */
+ show_progress: function() {
+ this.container.addClass('dndupload-inprogress');
+ },
+
+ /**
+ * Hide the element showing upload in progress
+ */
+ hide_progress: function() {
+ this.container.removeClass('dndupload-inprogress');
+ },
+
/**
* Tell the attached filemanager element (if any) to refresh on file
* upload
*/
- update_filemanager: function() {
+ update_filemanager: function(params) {
+ this.hide_progress();
if (this.filemanager) {
// update the filemanager that we've uploaded the files
this.filemanager.filepicker_callback();
+ } else if (this.callback) {
+ this.callback(params);
}
+ },
+
+ /**
+ * Clear the current progress bars
+ */
+ clear_progress: function() {
+ var filename;
+ for (filename in this.progressbars) {
+ if (this.progressbars.hasOwnProperty(filename)) {
+ this.progressbars[filename].progressouter.remove(true);
+ delete this.progressbars[filename];
+ }
+ }
+ },
+
+ /**
+ * Show the current progress of the uploaded file
+ */
+ update_progress: function(filename, percent) {
+ if (this.progressbars[filename] === undefined) {
+ var dispfilename = filename;
+ if (dispfilename.length > 50) {
+ dispfilename = dispfilename.substr(0, 49)+'…';
+ }
+ var progressouter = this.container.create(''+dispfilename+':
');
+ var progressinner = progressouter.one('.dndupload-progress-inner');
+ var progresscontainer = this.container.one('.dndupload-progressbars');
+ progresscontainer.appendChild(progressouter);
+
+ this.progressbars[filename] = {
+ progressouter: progressouter,
+ progressinner: progressinner
+ };
+ }
+
+ this.progressbars[filename].progressinner.setStyle('width', percent + '%');
}
};
@@ -402,6 +465,10 @@ M.form_dndupload.init = function(Y, options) {
options: {},
// The function to call when all uploads complete.
callback: null,
+ // The function to call as the upload progresses
+ callbackprogress: null,
+ // The function to call if the upload is cancelled
+ callbackcancel: null,
// The list of files dropped onto the element.
files: null,
// The ID of the 'upload' repository.
@@ -438,6 +505,8 @@ M.form_dndupload.init = function(Y, options) {
this.options = params.options;
this.repositoryid = params.repositoryid;
this.callback = params.callback;
+ this.callbackprogress = params.callbackprogress;
+ this.callbackcancel = params.callbackcancel;
this.currentfiles = params.currentfiles;
this.currentfilecount = params.currentfilecount;
this.currentareasize = 0;
@@ -447,7 +516,11 @@ M.form_dndupload.init = function(Y, options) {
this.currentareasize += this.currentfiles[i].size;
};
- this.initialise_queue(params.files);
+ if (!this.initialise_queue(params.files)) {
+ if (this.callbackcancel) {
+ this.callbackcancel();
+ }
+ }
},
/**
@@ -519,11 +592,12 @@ M.form_dndupload.init = function(Y, options) {
this.renamequeue.push(files[i]);
} else {
if (!this.add_to_upload_queue(files[i], files[i].name, false)) {
- return;
+ return false;
}
}
this.queuesize += files[i].size;
}
+ return true;
},
/**
@@ -633,6 +707,9 @@ M.form_dndupload.init = function(Y, options) {
node.one('.fp-dlg-butcancel').on('click', function(e) {
e.preventDefault();
process_dlg.hide();
+ if (self.callbackcancel) {
+ self.callbackcancel();
+ }
}, this);
// When we are at the file limit, only allow 'overwrite', not rename.
@@ -775,6 +852,15 @@ M.form_dndupload.init = function(Y, options) {
// http://yuilibrary.com/projects/yui3/ticket/2531274
var xhr = new XMLHttpRequest();
var self = this;
+
+ // Update the progress bar
+ xhr.upload.addEventListener('progress', function(e) {
+ if (e.lengthComputable && self.callbackprogress) {
+ var percentage = Math.round((e.loaded * 100) / e.total);
+ self.callbackprogress(filename, percentage);
+ }
+ }, false);
+
xhr.onreadystatechange = function() { // Process the server response
if (xhr.readyState == 4) {
if (xhr.status == 200) {
@@ -792,6 +878,9 @@ M.form_dndupload.init = function(Y, options) {
result.url = result.newfile.url;
}
result.client_id = self.options.clientid;
+ if (self.callbackprogress) {
+ self.callbackprogress(filename, 100);
+ }
}
}
self.do_upload(result); // continue uploading
diff --git a/lib/form/filepicker.js b/lib/form/filepicker.js
index b2811a25dbc..e3632e2f07e 100644
--- a/lib/form/filepicker.js
+++ b/lib/form/filepicker.js
@@ -5,6 +5,7 @@ M.form_filepicker.instances = [];
M.form_filepicker.callback = function(params) {
var html = ''+params['file']+'';
+ html += '';
M.form_filepicker.Y.one('#file_info_'+params['client_id'] + ' .filepicker-filename').setContent(html);
//When file is added then set status of global variable to true
var elementname = M.core_filepicker.instances[params['client_id']].options.elementname;
diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php
index 45d9618c84b..791886cda27 100644
--- a/lib/outputrenderers.php
+++ b/lib/outputrenderers.php
@@ -2211,6 +2211,7 @@ EOD;
$currentfile$strdndenabled
+
diff --git a/theme/base/pix/progress.gif b/theme/base/pix/progress.gif
new file mode 100644
index 00000000000..0bc00dfa146
Binary files /dev/null and b/theme/base/pix/progress.gif differ
diff --git a/theme/base/style/course.css b/theme/base/style/course.css
index 1bd7200113b..aff2b696ceb 100644
--- a/theme/base/style/course.css
+++ b/theme/base/style/course.css
@@ -204,6 +204,6 @@ input.titleeditor { width: 330px; vertical-align: text-bottom; }
#dndupload-status {width:40%;margin:0 30%;padding:6px;border:1px solid #ddd;text-align:center;background:#ffc;position:absolute;z-index:9999;box-shadow:2px 2px 5px 1px #ccc;border-radius:0px 0px 8px 8px;z-index: 0;}
.dndupload-preview {color:#909090;border:1px dashed #909090;list-style:none; margin-top: .2em; padding: .3em; line-height: 16px;}
.dndupload-preview img.icon { vertical-align: text-bottom; padding: 0;}
-.dndupload-progress-outer {width:70px;border:1px solid black;height:10px;display:inline-block;margin:0;padding:0;overflow:hidden;position:relative;}
-.dndupload-progress-inner {width:0%;height:100%;background-color:green;display:inline-block;margin:0;padding:0;float:left;}
+.dndupload-progress-outer {width:70px;border:1px solid black;border-radius:4px;height:10px;display:inline-block;margin:0;padding:0;overflow:hidden;position:relative;}
+.dndupload-progress-inner {width:0%;height:100%;background-color:green;display:inline-block;margin:0;padding:0;float:left;box-shadow: 0 0 4px #229b15;border-radius:2px;background-repeat:repeat-x;background-position:top;background-image:url([[pix:theme_base|progress]])}
.dndupload-hidden {display:none;}
diff --git a/theme/base/style/filemanager.css b/theme/base/style/filemanager.css
index ed52934b7ea..b9706ac41dc 100644
--- a/theme/base/style/filemanager.css
+++ b/theme/base/style/filemanager.css
@@ -347,6 +347,12 @@ a.ygtvspacer:hover {color: transparent;text-decoration: none;}
.dndupload-uploading .dndupload-uploadinprogress {display:block;}
.dndupload-arrow {background:url([[pix:theme|fp/dnd_arrow]]) center no-repeat;width:60px;height:80px;position:absolute;margin-left: -28px;top: 5px;}
.fitem.disabled .filepicker-container, .fitem.disabled .fm-empty-container {display:none;}
+.dndupload-progressbars {padding:10px;display:none;}
+.dndupload-inprogress .dndupload-progressbars {display:block;}
+.dndupload-inprogress .fp-content {display:none;}
+.filemanager.fm-noitems .dndupload-inprogress .fm-empty-container {display:none;}
+.filepicker-filelist.dndupload-inprogress .filepicker-container {display:none;}
+.filepicker-filelist.dndupload-inprogress a {display:none;}
/*
* Select Dialogue (File Manager only)