diff --git a/wp-includes/css/media-views.css b/wp-includes/css/media-views.css
index 84308bc342..ed3dd91602 100644
--- a/wp-includes/css/media-views.css
+++ b/wp-includes/css/media-views.css
@@ -715,20 +715,20 @@ a.media-modal-close {
*/
.media-progress-bar {
position: relative;
- height: 8px;
+ height: 10px;
width: 70%;
margin: 10px auto;
- padding: 2px;
- border: 2px solid #ccc;
- border-radius: 8px;
- background: #fff;
+ border-radius: 10px;
+ background: #dfdfdf;
+ background: rgba( 0, 0, 0, 0.1 );
}
.media-progress-bar div {
- height: 8px;
- min-width: 8px;
+ height: 10px;
+ min-width: 20px;
width: 0;
- background: #ccc;
+ background: #aaa;
+ background: rgba( 0, 0, 0, 0.2 );
border-radius: 10px;
-webkit-transition: width 300ms;
-moz-transition: width 300ms;
@@ -737,12 +737,36 @@ a.media-modal-close {
transition: width 300ms;
}
+.media-uploader-status .media-progress-bar {
+ width: 100%;
+}
+
.attachment-preview .media-progress-bar {
position: absolute;
top: 50%;
left: 15%;
width: 70%;
- margin: -8px 0 0 -4px;
+ margin: -5px 0 0 0;
+}
+
+.media-uploader-status {
+ padding-bottom: 10px;
+ border-bottom: 1px solid #dfdfdf;
+ box-shadow: 0 1px 0 #fff;
+}
+
+.media-uploader-status .upload-details {
+ font-size: 12px;
+ color: #666;
+ text-shadow: 0 1px 0 #fff;
+}
+
+.media-uploader-status .upload-detail-separator {
+ padding: 0 4px;
+}
+
+.media-uploader-status .upload-count {
+ color: #464646;
}
.uploader-window {
@@ -1059,7 +1083,7 @@ a.media-modal-close {
}
.uploading .attachment-info .media-progress-bar {
- margin-top: 32px;
+ margin-top: 35px;
}
.attachment-info .thumbnail:after {
diff --git a/wp-includes/js/media-models.js b/wp-includes/js/media-models.js
index 716522808f..0ec33270e9 100644
--- a/wp-includes/js/media-models.js
+++ b/wp-includes/js/media-models.js
@@ -191,6 +191,18 @@ window.wp = window.wp || {};
height: height
};
}
+ },
+
+ // Truncates a string by injecting an ellipsis into the middle.
+ // Useful for filenames.
+ truncate: function( string, length, replacement ) {
+ length = length || 30;
+ replacement = replacement || '…';
+
+ if ( string.length <= length )
+ return string;
+
+ return string.substr( 0, length / 2 ) + replacement + string.substr( -1 * length / 2 );
}
});
diff --git a/wp-includes/js/media-views.js b/wp-includes/js/media-views.js
index a492bd0436..798a143af9 100644
--- a/wp-includes/js/media-views.js
+++ b/wp-includes/js/media-views.js
@@ -255,7 +255,8 @@
toolbar: 'main-attachments',
sidebar: 'settings',
searchable: true,
- filterable: false
+ filterable: false,
+ uploads: true
},
initialize: function() {
@@ -476,6 +477,7 @@
id: 'upload',
content: 'upload',
toolbar: 'empty',
+ uploads: true,
// The state to navigate to when files are uploading.
libraryState: 'library'
@@ -1290,7 +1292,7 @@
model: state,
sortable: state.get('sortable'),
search: state.get('searchable'),
- upload: state.get('upload'),
+ uploads: state.get('uploads'),
filters: state.get('filterable'),
display: state.get('displaySettings'),
@@ -1826,6 +1828,85 @@
}
});
+ /**
+ * wp.media.view.UploaderStatus
+ */
+ media.view.UploaderStatus = media.View.extend({
+ className: 'media-uploader-status',
+ template: media.template('uploader-status'),
+
+ initialize: function() {
+ this.controller = this.options.controller;
+
+ this.queue = wp.Uploader.queue;
+ this.queue.on( 'add remove reset', this.visibility, this );
+ this.queue.on( 'add remove reset change:percent', this.progress, this );
+ this.queue.on( 'add remove reset change:uploading', this.info, this );
+
+ this.errors = wp.Uploader.errors;
+ },
+
+ dispose: function() {
+ wp.Uploader.queue.off( null, null, this );
+ media.View.prototype.dispose.apply( this, arguments );
+ return this;
+ },
+
+ visibility: function() {
+ this.$el.toggleClass( 'uploading', !! this.queue.length );
+ this.$el.toggle( !! this.queue.length || !! this.errors.length );
+ },
+
+ ready: function() {
+ _.each({
+ '$bar': '.media-progress-bar div',
+ '$index': '.upload-index',
+ '$total': '.upload-total',
+ '$filename': '.upload-filename'
+ }, function( selector, key ) {
+ this[ key ] = this.$( selector );
+ }, this );
+
+ this.visibility();
+ this.progress();
+ this.info();
+ },
+
+ progress: function() {
+ var queue = this.queue,
+ $bar = this.$bar,
+ memo = 0;
+
+ if ( ! $bar || ! queue.length )
+ return;
+
+ $bar.width( ( queue.reduce( function( memo, attachment ) {
+ if ( ! attachment.get('uploading') )
+ return memo + 100;
+
+ var percent = attachment.get('percent');
+ return memo + ( _.isNumber( percent ) ? percent : 100 );
+ }, 0 ) / queue.length ) + '%' );
+ },
+
+ info: function() {
+ var queue = this.queue,
+ index = 0, active;
+
+ if ( ! queue.length )
+ return;
+
+ active = this.queue.find( function( attachment, i ) {
+ index = i;
+ return attachment.get('uploading');
+ });
+
+ this.$index.text( index + 1 );
+ this.$total.text( queue.length );
+ this.$filename.html( active ? media.truncate( _.escape( active.get('filename') ), 24 ) : '' );
+ }
+ });
+
/**
* wp.media.view.Toolbar
*/
@@ -2860,7 +2941,7 @@
_.defaults( this.options, {
filters: false,
search: true,
- upload: false,
+ uploads: false,
display: false,
AttachmentView: media.view.Attachment.Library
@@ -2914,15 +2995,6 @@
priority: -40
}) );
}
-
- if ( this.options.upload && this.controller.uploader ) {
- this.toolbar.set( 'upload', new media.view.Button( _.extend({
- el: this.controller.uploader.$browser.detach()[0],
- priority: -60,
- size: 'large',
- text: l10n.selectFiles
- }, this.options.upload ) ).render() );
- }
},
createAttachments: function() {
@@ -2941,14 +3013,26 @@
},
createSidebar: function() {
- this.sidebar = new media.view.Sidebar({
- controller: this.controller
- });
+ var options = this.options,
+ selection = options.selection,
+ sidebar = this.sidebar = new media.view.Sidebar({
+ controller: this.controller
+ });
- this.views.add( this.sidebar );
+ this.views.add( sidebar );
- this.options.selection.on( 'selection:single', this.createSingle, this );
- this.options.selection.on( 'selection:unsingle', this.disposeSingle, this );
+ if ( options.uploads && this.controller.uploader ) {
+ sidebar.set( 'uploads', new media.view.UploaderStatus({
+ controller: this.controller,
+ priority: 40
+ }) );
+ }
+
+ selection.on( 'selection:single', this.createSingle, this );
+ selection.on( 'selection:unsingle', this.disposeSingle, this );
+
+ if ( selection.single() )
+ this.createSingle();
},
createSingle: function() {
diff --git a/wp-includes/js/plupload/wp-plupload.js b/wp-includes/js/plupload/wp-plupload.js
index 2c826085d5..79522e59c5 100644
--- a/wp-includes/js/plupload/wp-plupload.js
+++ b/wp-includes/js/plupload/wp-plupload.js
@@ -86,6 +86,13 @@ window.wp = window.wp || {};
error = function( message, data, file ) {
if ( file.attachment )
file.attachment.destroy();
+
+ Uploader.errors.unshift({
+ message: message,
+ data: data,
+ file: file
+ });
+
self.error( message, data, file );
};
@@ -284,6 +291,7 @@ window.wp = window.wp || {};
});
Uploader.queue = new wp.media.model.Attachments( [], { query: false });
+ Uploader.errors = new Backbone.Collection();
exports.Uploader = Uploader;
})( wp, jQuery );
diff --git a/wp-includes/media.php b/wp-includes/media.php
index 5078b9f0e7..9a24e68599 100644
--- a/wp-includes/media.php
+++ b/wp-includes/media.php
@@ -1443,6 +1443,20 @@ function wp_print_media_templates( $attachment ) {
+
+