mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 08:42:41 +01:00
Show upload status, success and failures for drag-and-drop files in notifications
Summary: Currently, we do a poor job of communicating drag-and-drop upload errors. Show progress and success/failure in notifications. Test Plan: {F20671} {F20672} Uploaded files to maniphest attachments, remarkup text areas, Files tool. Reviewers: btrahan, vrana Reviewed By: vrana CC: aran Differential Revision: https://secure.phabricator.com/D3655
This commit is contained in:
parent
e00d3b72fe
commit
2bc9ac5e2e
7 changed files with 267 additions and 71 deletions
|
@ -916,7 +916,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-behavior-aphront-drag-and-drop' =>
|
||||
array(
|
||||
'uri' => '/res/724c922b/rsrc/js/application/core/behavior-drag-and-drop.js',
|
||||
'uri' => '/res/0910fc0a/rsrc/js/application/core/behavior-drag-and-drop.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -929,7 +929,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-behavior-aphront-drag-and-drop-textarea' =>
|
||||
array(
|
||||
'uri' => '/res/99f58821/rsrc/js/application/core/behavior-drag-and-drop-textarea.js',
|
||||
'uri' => '/res/ad737ce4/rsrc/js/application/core/behavior-drag-and-drop-textarea.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -1301,7 +1301,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-behavior-files-drag-and-drop' =>
|
||||
array(
|
||||
'uri' => '/res/3a7a2a8a/rsrc/js/application/core/behavior-files-drag-and-drop.js',
|
||||
'uri' => '/res/4893f577/rsrc/js/application/core/behavior-files-drag-and-drop.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -2361,7 +2361,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'phabricator-drag-and-drop-file-upload' =>
|
||||
array(
|
||||
'uri' => '/res/63a06ad9/rsrc/js/application/core/DragAndDropFileUpload.js',
|
||||
'uri' => '/res/0db5b9d5/rsrc/js/application/core/DragAndDropFileUpload.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -2370,6 +2370,7 @@ celerity_register_resource_map(array(
|
|||
2 => 'javelin-request',
|
||||
3 => 'javelin-dom',
|
||||
4 => 'javelin-uri',
|
||||
5 => 'phabricator-file-upload',
|
||||
),
|
||||
'disk' => '/rsrc/js/application/core/DragAndDropFileUpload.js',
|
||||
),
|
||||
|
@ -2397,6 +2398,16 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/css/application/feed/feed.css',
|
||||
),
|
||||
'phabricator-file-upload' =>
|
||||
array(
|
||||
'uri' => '/res/98503231/rsrc/js/application/core/FileUpload.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
0 => 'javelin-install',
|
||||
),
|
||||
'disk' => '/rsrc/js/application/core/FileUpload.js',
|
||||
),
|
||||
'phabricator-filetree-view-css' =>
|
||||
array(
|
||||
'uri' => '/res/be0ab498/rsrc/css/layout/phabricator-filetree-view.css',
|
||||
|
@ -2512,7 +2523,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'phabricator-notification-css' =>
|
||||
array(
|
||||
'uri' => '/res/77e8c821/rsrc/css/aphront/notification.css',
|
||||
'uri' => '/res/91197237/rsrc/css/aphront/notification.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -2636,7 +2647,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'phabricator-remarkup-css' =>
|
||||
array(
|
||||
'uri' => '/res/66b4cd42/rsrc/css/core/remarkup.css',
|
||||
'uri' => '/res/2e0d0042/rsrc/css/core/remarkup.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -3003,7 +3014,7 @@ celerity_register_resource_map(array(
|
|||
), array(
|
||||
'packages' =>
|
||||
array(
|
||||
'c88632b0' =>
|
||||
'315e8536' =>
|
||||
array(
|
||||
'name' => 'core.pkg.css',
|
||||
'symbols' =>
|
||||
|
@ -3032,7 +3043,7 @@ celerity_register_resource_map(array(
|
|||
21 => 'phabricator-flag-css',
|
||||
22 => 'aphront-error-view-css',
|
||||
),
|
||||
'uri' => '/res/pkg/c88632b0/core.pkg.css',
|
||||
'uri' => '/res/pkg/315e8536/core.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'3a455e4f' =>
|
||||
|
@ -3084,7 +3095,7 @@ celerity_register_resource_map(array(
|
|||
'uri' => '/res/pkg/2ba14b3d/differential.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'a5cb9310' =>
|
||||
'a569df32' =>
|
||||
array(
|
||||
'name' => 'differential.pkg.js',
|
||||
'symbols' =>
|
||||
|
@ -3107,7 +3118,7 @@ celerity_register_resource_map(array(
|
|||
15 => 'differential-inline-comment-editor',
|
||||
16 => 'javelin-behavior-differential-dropdown-menus',
|
||||
),
|
||||
'uri' => '/res/pkg/a5cb9310/differential.pkg.js',
|
||||
'uri' => '/res/pkg/a569df32/differential.pkg.js',
|
||||
'type' => 'js',
|
||||
),
|
||||
'c8ce2d88' =>
|
||||
|
@ -3199,23 +3210,23 @@ celerity_register_resource_map(array(
|
|||
'reverse' =>
|
||||
array(
|
||||
'aphront-attached-file-view-css' => '7839ae2d',
|
||||
'aphront-crumbs-view-css' => 'c88632b0',
|
||||
'aphront-dialog-view-css' => 'c88632b0',
|
||||
'aphront-error-view-css' => 'c88632b0',
|
||||
'aphront-form-view-css' => 'c88632b0',
|
||||
'aphront-crumbs-view-css' => '315e8536',
|
||||
'aphront-dialog-view-css' => '315e8536',
|
||||
'aphront-error-view-css' => '315e8536',
|
||||
'aphront-form-view-css' => '315e8536',
|
||||
'aphront-headsup-action-list-view-css' => '2ba14b3d',
|
||||
'aphront-headsup-view-css' => 'c88632b0',
|
||||
'aphront-list-filter-view-css' => 'c88632b0',
|
||||
'aphront-pager-view-css' => 'c88632b0',
|
||||
'aphront-panel-view-css' => 'c88632b0',
|
||||
'aphront-side-nav-view-css' => 'c88632b0',
|
||||
'aphront-table-view-css' => 'c88632b0',
|
||||
'aphront-tokenizer-control-css' => 'c88632b0',
|
||||
'aphront-tooltip-css' => 'c88632b0',
|
||||
'aphront-typeahead-control-css' => 'c88632b0',
|
||||
'aphront-headsup-view-css' => '315e8536',
|
||||
'aphront-list-filter-view-css' => '315e8536',
|
||||
'aphront-pager-view-css' => '315e8536',
|
||||
'aphront-panel-view-css' => '315e8536',
|
||||
'aphront-side-nav-view-css' => '315e8536',
|
||||
'aphront-table-view-css' => '315e8536',
|
||||
'aphront-tokenizer-control-css' => '315e8536',
|
||||
'aphront-tooltip-css' => '315e8536',
|
||||
'aphront-typeahead-control-css' => '315e8536',
|
||||
'differential-changeset-view-css' => '2ba14b3d',
|
||||
'differential-core-view-css' => '2ba14b3d',
|
||||
'differential-inline-comment-editor' => 'a5cb9310',
|
||||
'differential-inline-comment-editor' => 'a569df32',
|
||||
'differential-local-commits-view-css' => '2ba14b3d',
|
||||
'differential-results-table-css' => '2ba14b3d',
|
||||
'differential-revision-add-comment-css' => '2ba14b3d',
|
||||
|
@ -3229,20 +3240,20 @@ celerity_register_resource_map(array(
|
|||
'inline-comment-summary-css' => '2ba14b3d',
|
||||
'javelin-behavior' => '6c45a1d8',
|
||||
'javelin-behavior-aphront-basic-tokenizer' => '81c9cd69',
|
||||
'javelin-behavior-aphront-drag-and-drop' => 'a5cb9310',
|
||||
'javelin-behavior-aphront-drag-and-drop-textarea' => 'a5cb9310',
|
||||
'javelin-behavior-aphront-drag-and-drop' => 'a569df32',
|
||||
'javelin-behavior-aphront-drag-and-drop-textarea' => 'a569df32',
|
||||
'javelin-behavior-aphront-form-disable-on-submit' => '3a455e4f',
|
||||
'javelin-behavior-audit-preview' => '5e68be89',
|
||||
'javelin-behavior-differential-accept-with-errors' => 'a5cb9310',
|
||||
'javelin-behavior-differential-add-reviewers-and-ccs' => 'a5cb9310',
|
||||
'javelin-behavior-differential-comment-jump' => 'a5cb9310',
|
||||
'javelin-behavior-differential-diff-radios' => 'a5cb9310',
|
||||
'javelin-behavior-differential-dropdown-menus' => 'a5cb9310',
|
||||
'javelin-behavior-differential-edit-inline-comments' => 'a5cb9310',
|
||||
'javelin-behavior-differential-feedback-preview' => 'a5cb9310',
|
||||
'javelin-behavior-differential-keyboard-navigation' => 'a5cb9310',
|
||||
'javelin-behavior-differential-populate' => 'a5cb9310',
|
||||
'javelin-behavior-differential-show-more' => 'a5cb9310',
|
||||
'javelin-behavior-differential-accept-with-errors' => 'a569df32',
|
||||
'javelin-behavior-differential-add-reviewers-and-ccs' => 'a569df32',
|
||||
'javelin-behavior-differential-comment-jump' => 'a569df32',
|
||||
'javelin-behavior-differential-diff-radios' => 'a569df32',
|
||||
'javelin-behavior-differential-dropdown-menus' => 'a569df32',
|
||||
'javelin-behavior-differential-edit-inline-comments' => 'a569df32',
|
||||
'javelin-behavior-differential-feedback-preview' => 'a569df32',
|
||||
'javelin-behavior-differential-keyboard-navigation' => 'a569df32',
|
||||
'javelin-behavior-differential-populate' => 'a569df32',
|
||||
'javelin-behavior-differential-show-more' => 'a569df32',
|
||||
'javelin-behavior-diffusion-commit-graph' => '5e68be89',
|
||||
'javelin-behavior-diffusion-pull-lastmodified' => '5e68be89',
|
||||
'javelin-behavior-maniphest-batch-selector' => '7707de41',
|
||||
|
@ -3252,12 +3263,12 @@ celerity_register_resource_map(array(
|
|||
'javelin-behavior-maniphest-transaction-preview' => '7707de41',
|
||||
'javelin-behavior-phabricator-autofocus' => '3a455e4f',
|
||||
'javelin-behavior-phabricator-keyboard-shortcuts' => '3a455e4f',
|
||||
'javelin-behavior-phabricator-object-selector' => 'a5cb9310',
|
||||
'javelin-behavior-phabricator-object-selector' => 'a569df32',
|
||||
'javelin-behavior-phabricator-oncopy' => '3a455e4f',
|
||||
'javelin-behavior-phabricator-tooltips' => '3a455e4f',
|
||||
'javelin-behavior-phabricator-watch-anchor' => '3a455e4f',
|
||||
'javelin-behavior-refresh-csrf' => '3a455e4f',
|
||||
'javelin-behavior-repository-crossreference' => 'a5cb9310',
|
||||
'javelin-behavior-repository-crossreference' => 'a569df32',
|
||||
'javelin-behavior-workflow' => '3a455e4f',
|
||||
'javelin-dom' => '6c45a1d8',
|
||||
'javelin-event' => '6c45a1d8',
|
||||
|
@ -3278,15 +3289,15 @@ celerity_register_resource_map(array(
|
|||
'javelin-workflow' => '3a455e4f',
|
||||
'maniphest-task-summary-css' => '7839ae2d',
|
||||
'maniphest-transaction-detail-css' => '7839ae2d',
|
||||
'phabricator-app-buttons-css' => 'c88632b0',
|
||||
'phabricator-app-buttons-css' => '315e8536',
|
||||
'phabricator-content-source-view-css' => '2ba14b3d',
|
||||
'phabricator-core-buttons-css' => 'c88632b0',
|
||||
'phabricator-core-css' => 'c88632b0',
|
||||
'phabricator-directory-css' => 'c88632b0',
|
||||
'phabricator-drag-and-drop-file-upload' => 'a5cb9310',
|
||||
'phabricator-core-buttons-css' => '315e8536',
|
||||
'phabricator-core-css' => '315e8536',
|
||||
'phabricator-directory-css' => '315e8536',
|
||||
'phabricator-drag-and-drop-file-upload' => 'a569df32',
|
||||
'phabricator-dropdown-menu' => '3a455e4f',
|
||||
'phabricator-flag-css' => 'c88632b0',
|
||||
'phabricator-jump-nav' => 'c88632b0',
|
||||
'phabricator-flag-css' => '315e8536',
|
||||
'phabricator-jump-nav' => '315e8536',
|
||||
'phabricator-keyboard-shortcut' => '3a455e4f',
|
||||
'phabricator-keyboard-shortcut-manager' => '3a455e4f',
|
||||
'phabricator-menu-item' => '3a455e4f',
|
||||
|
@ -3294,11 +3305,11 @@ celerity_register_resource_map(array(
|
|||
'phabricator-paste-file-upload' => '3a455e4f',
|
||||
'phabricator-prefab' => '3a455e4f',
|
||||
'phabricator-project-tag-css' => '7839ae2d',
|
||||
'phabricator-remarkup-css' => 'c88632b0',
|
||||
'phabricator-shaped-request' => 'a5cb9310',
|
||||
'phabricator-standard-page-view' => 'c88632b0',
|
||||
'phabricator-remarkup-css' => '315e8536',
|
||||
'phabricator-shaped-request' => 'a569df32',
|
||||
'phabricator-standard-page-view' => '315e8536',
|
||||
'phabricator-tooltip' => '3a455e4f',
|
||||
'phabricator-transaction-view-css' => 'c88632b0',
|
||||
'syntax-highlighting-css' => 'c88632b0',
|
||||
'phabricator-transaction-view-css' => '315e8536',
|
||||
'syntax-highlighting-css' => '315e8536',
|
||||
),
|
||||
));
|
||||
|
|
|
@ -38,3 +38,13 @@
|
|||
background: #ffa0ff;
|
||||
border: 1px solid #aa60aa;
|
||||
}
|
||||
|
||||
.jx-notification-done {
|
||||
background: #d0ffd0;
|
||||
border: 1px solid #60aa60;
|
||||
}
|
||||
|
||||
.jx-notification-error {
|
||||
background: #ffd0d0;
|
||||
border: 1px solid #aa6060;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* javelin-request
|
||||
* javelin-dom
|
||||
* javelin-uri
|
||||
* phabricator-file-upload
|
||||
* @provides phabricator-drag-and-drop-file-upload
|
||||
* @javelin
|
||||
*/
|
||||
|
@ -14,7 +15,7 @@ JX.install('PhabricatorDragAndDropFileUpload', {
|
|||
this._node = node;
|
||||
},
|
||||
|
||||
events : ['willUpload', 'didUpload'],
|
||||
events : ['willUpload', 'progress', 'didUpload', 'didError'],
|
||||
|
||||
statics : {
|
||||
isSupported : function() {
|
||||
|
@ -88,24 +89,80 @@ JX.install('PhabricatorDragAndDropFileUpload', {
|
|||
|
||||
var files = e.getRawEvent().dataTransfer.files;
|
||||
for (var ii = 0; ii < files.length; ii++) {
|
||||
var file = files[ii];
|
||||
|
||||
this.invoke('willUpload', file);
|
||||
|
||||
var up_uri = JX.$U(this.getURI())
|
||||
.setQueryParam('name', file.name)
|
||||
.toString();
|
||||
|
||||
new JX.Request(up_uri, JX.bind(this, function(r) {
|
||||
this.invoke('didUpload', r);
|
||||
}))
|
||||
.setFile(file)
|
||||
.send();
|
||||
this._sendRequest(files[ii]);
|
||||
}
|
||||
|
||||
// Force depth to 0.
|
||||
this._updateDepth(-this._depth);
|
||||
}));
|
||||
},
|
||||
_sendRequest : function(spec) {
|
||||
var file = new JX.PhabricatorFileUpload()
|
||||
.setName(spec.name)
|
||||
.setTotalBytes(spec.size)
|
||||
.setStatus('uploading')
|
||||
.update();
|
||||
|
||||
this.invoke('willUpload', file);
|
||||
|
||||
var up_uri = JX.$U(this.getURI())
|
||||
.setQueryParam('name', file.getName())
|
||||
.toString();
|
||||
|
||||
var onupload = JX.bind(this, function(r) {
|
||||
if (r.error) {
|
||||
file
|
||||
.setStatus('error')
|
||||
.setError(r.error)
|
||||
.update();
|
||||
|
||||
this.invoke('didError', file);
|
||||
} else {
|
||||
file
|
||||
.setID(r.id)
|
||||
.setPHID(r.phid)
|
||||
.setURI(r.uri)
|
||||
.setMarkup(r.html)
|
||||
.setStatus('done')
|
||||
.update();
|
||||
|
||||
this.invoke('didUpload', file);
|
||||
}
|
||||
});
|
||||
|
||||
var req = new JX.Request(up_uri, onupload);
|
||||
|
||||
var onerror = JX.bind(this, function(error) {
|
||||
file.setStatus('error');
|
||||
|
||||
if (error) {
|
||||
file.setError(error.code + ': ' + error.info);
|
||||
} else {
|
||||
var xhr = req.getTransport();
|
||||
if (xhr.responseText) {
|
||||
file.setError('Server responded: ' + xhr.responseText);
|
||||
}
|
||||
}
|
||||
|
||||
file.update();
|
||||
this.invoke('didError', file);
|
||||
});
|
||||
|
||||
var onprogress = JX.bind(this, function(progress) {
|
||||
file
|
||||
.setTotalBytes(progress.total)
|
||||
.setUploadedBytes(progress.loaded)
|
||||
.update();
|
||||
|
||||
this.invoke('progress', file);
|
||||
});
|
||||
|
||||
req.listen('error', onerror);
|
||||
req.listen('uploadprogress', onprogress);
|
||||
|
||||
req
|
||||
.setFile(spec)
|
||||
.send();
|
||||
}
|
||||
},
|
||||
properties: {
|
||||
|
|
111
webroot/rsrc/js/application/core/FileUpload.js
Normal file
111
webroot/rsrc/js/application/core/FileUpload.js
Normal file
|
@ -0,0 +1,111 @@
|
|||
/**
|
||||
* @requires javelin-install
|
||||
* @provides phabricator-file-upload
|
||||
* @javelin
|
||||
*/
|
||||
|
||||
JX.install('PhabricatorFileUpload', {
|
||||
|
||||
construct : function() {
|
||||
this._notification = new JX.Notification();
|
||||
},
|
||||
|
||||
properties : {
|
||||
name : null,
|
||||
totalBytes : null,
|
||||
uploadedBytes : null,
|
||||
ID : null,
|
||||
PHID : null,
|
||||
URI : null,
|
||||
status : null,
|
||||
markup : null,
|
||||
error : null
|
||||
},
|
||||
|
||||
members : {
|
||||
_notification : null,
|
||||
|
||||
update : function() {
|
||||
if (!this._notification) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._notification
|
||||
.setDuration(0)
|
||||
.show();
|
||||
|
||||
switch (this.getStatus()) {
|
||||
case 'done':
|
||||
var link = JX.$N('a', {href: this.getURI()}, 'F' + this.getID());
|
||||
|
||||
var content = [
|
||||
JX.$N('strong', {}, ['Upload Complete (', link, ')']),
|
||||
JX.$N('br'),
|
||||
this.getName()
|
||||
];
|
||||
|
||||
this._notification
|
||||
.setContent(content)
|
||||
.alterClassName('jx-notification-done', true)
|
||||
.setDuration(12000);
|
||||
this._notification = null;
|
||||
break;
|
||||
case 'error':
|
||||
var content = [
|
||||
JX.$N('strong', {}, 'Upload Failure'),
|
||||
JX.$N('br'),
|
||||
this.getName(),
|
||||
JX.$N('br'),
|
||||
JX.$N('br'),
|
||||
this.getError()
|
||||
];
|
||||
|
||||
this._notification
|
||||
.setContent(content)
|
||||
.alterClassName('jx-notification-error', true);
|
||||
this._notification = null;
|
||||
break;
|
||||
default:
|
||||
var info = '';
|
||||
if (this.getTotalBytes()) {
|
||||
var p = this._renderPercentComplete();
|
||||
var f = this._renderFileSize();
|
||||
info = ' (' + p + ' of ' + f + ')';
|
||||
}
|
||||
|
||||
info = 'Uploading "' + this.getName() + '"' + info + '...';
|
||||
|
||||
this._notification
|
||||
.setContent(info);
|
||||
break;
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
_renderPercentComplete : function() {
|
||||
if (!this.getTotalBytes()) {
|
||||
return null;
|
||||
}
|
||||
var ratio = this.getUploadedBytes() / this.getTotalBytes();
|
||||
return parseInt(100 * ratio) + '%';
|
||||
},
|
||||
_renderFileSize : function() {
|
||||
if (!this.getTotalBytes()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var s = 3;
|
||||
var n = this.getTotalBytes();
|
||||
while (s && n >= 1000) {
|
||||
n = Math.round(n / 100);
|
||||
n = n / 10;
|
||||
s--;
|
||||
}
|
||||
|
||||
s = ['GB', 'MB', 'KB', 'bytes'][s];
|
||||
return n + ' ' + s;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -12,7 +12,7 @@ JX.behavior('aphront-drag-and-drop-textarea', function(config) {
|
|||
var target = JX.$(config.target);
|
||||
|
||||
function onupload(f) {
|
||||
JX.TextAreaUtils.setSelectionText(target, '{F' + f.id + '}');
|
||||
JX.TextAreaUtils.setSelectionText(target, '{F' + f.getID() + '}');
|
||||
}
|
||||
|
||||
if (JX.PhabricatorDragAndDropFileUpload.isSupported()) {
|
||||
|
|
|
@ -32,7 +32,7 @@ JX.behavior('aphront-drag-and-drop', function(config) {
|
|||
});
|
||||
|
||||
drop.listen('didUpload', function(f) {
|
||||
files[f.phid] = f;
|
||||
files[f.getPHID()] = f;
|
||||
|
||||
// This redraws "Upload complete!"
|
||||
pending--;
|
||||
|
@ -59,13 +59,13 @@ JX.behavior('aphront-drag-and-drop', function(config) {
|
|||
var items = [];
|
||||
for (var k in files) {
|
||||
var file = files[k];
|
||||
items.push(JX.$N('div', {}, JX.$H(file.html)));
|
||||
items.push(JX.$N('div', {}, JX.$H(file.getMarkup())));
|
||||
items.push(JX.$N(
|
||||
'input',
|
||||
{
|
||||
type: "hidden",
|
||||
name: config.name + "[" + file.phid + "]",
|
||||
value: file.phid
|
||||
name: config.name + "[" + file.getPHID() + "]",
|
||||
value: file.getPHID()
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ JX.behavior('files-drag-and-drop', function(config) {
|
|||
|
||||
var pending = 0;
|
||||
var files = [];
|
||||
var errors = false;
|
||||
|
||||
var control = JX.$(config.control);
|
||||
// Show the control, since we have browser support.
|
||||
|
@ -34,14 +35,14 @@ JX.behavior('files-drag-and-drop', function(config) {
|
|||
files.push(f);
|
||||
|
||||
pending--;
|
||||
if (pending == 0) {
|
||||
if (pending == 0 && !errors) {
|
||||
// If whatever the user dropped in has finished uploading, send them to
|
||||
// their uploads.
|
||||
var uri;
|
||||
uri = JX.$U(config.browseURI);
|
||||
var ids = [];
|
||||
for (var ii = 0; ii < files.length; ii++) {
|
||||
ids.push(files[ii].id);
|
||||
ids.push(files[ii].getID());
|
||||
}
|
||||
uri.setQueryParam('h', ids.join('-'));
|
||||
|
||||
|
@ -56,6 +57,12 @@ JX.behavior('files-drag-and-drop', function(config) {
|
|||
}
|
||||
});
|
||||
|
||||
drop.listen('didError', function(f) {
|
||||
pending--;
|
||||
errors = true;
|
||||
redraw();
|
||||
});
|
||||
|
||||
drop.start();
|
||||
redraw();
|
||||
|
||||
|
|
Loading…
Reference in a new issue