Summary: This was slightly more complex than I believed, but not too terrible. Test Plan: {F1096126} - Also used some normal file uploaders to make sure I didn't break that. Reviewers: chad Reviewed By: chad Differential Revision: https://secure.phabricator.com/D15202
198 lines
4.5 KiB
JavaScript
198 lines
4.5 KiB
JavaScript
/**
|
|
* @requires javelin-install
|
|
* javelin-dom
|
|
* phabricator-notification
|
|
* @provides phabricator-file-upload
|
|
* @javelin
|
|
*/
|
|
|
|
JX.install('PhabricatorFileUpload', {
|
|
|
|
construct : function() {
|
|
this._notification = new JX.Notification();
|
|
},
|
|
|
|
properties : {
|
|
name: null,
|
|
totalBytes: null,
|
|
uploadedBytes: null,
|
|
rawFileObject: null,
|
|
allocatedPHID: null,
|
|
ID: null,
|
|
PHID: null,
|
|
URI: null,
|
|
status: null,
|
|
markup: null,
|
|
targetNode: null,
|
|
error: null
|
|
},
|
|
|
|
members : {
|
|
_notification : null,
|
|
_chunks: null,
|
|
_isResume: false,
|
|
|
|
addUploadedBytes: function(bytes) {
|
|
var uploaded = this.getUploadedBytes();
|
|
this.setUploadedBytes(uploaded + bytes);
|
|
return this;
|
|
},
|
|
|
|
setChunks: function(chunks) {
|
|
var chunk;
|
|
for (var ii = 0; ii < chunks.length; ii++) {
|
|
chunk = chunks[ii];
|
|
if (chunk.complete) {
|
|
this.addUploadedBytes(chunk.byteEnd - chunk.byteStart);
|
|
this._isResume = true;
|
|
}
|
|
}
|
|
|
|
this._chunks = chunks;
|
|
|
|
return this;
|
|
},
|
|
|
|
getChunks: function() {
|
|
return this._chunks;
|
|
},
|
|
|
|
getRemainingChunks: function() {
|
|
var chunks = this.getChunks();
|
|
|
|
var result = [];
|
|
for (var ii = 0; ii < chunks.length; ii++) {
|
|
if (!chunks[ii].complete) {
|
|
result.push(chunks[ii]);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
didCompleteChunk: function(chunk) {
|
|
var chunks = this.getRemainingChunks();
|
|
for (var ii = 0; ii < chunks.length; ii++) {
|
|
if (chunks[ii].byteStart == chunk.byteStart) {
|
|
if (chunks[ii].byteEnd == chunk.byteEnd) {
|
|
if (!chunks[ii].complete) {
|
|
chunks[ii].complete = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
update : function() {
|
|
if (!this._notification) {
|
|
return;
|
|
}
|
|
|
|
this._notification
|
|
.setDuration(0)
|
|
.show();
|
|
|
|
var content;
|
|
|
|
// TODO: This stuff needs some work for translations.
|
|
|
|
switch (this.getStatus()) {
|
|
case 'done':
|
|
var link = JX.$N('a', {href: this.getURI()}, 'F' + this.getID());
|
|
|
|
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':
|
|
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;
|
|
case 'allocate':
|
|
content = 'Allocating "' + this.getName() + '"...';
|
|
this._notification
|
|
.setContent(content);
|
|
break;
|
|
case 'chunks':
|
|
content = 'Loading chunks for "' + this.getName() + '"...';
|
|
this._notification
|
|
.setContent(content);
|
|
break;
|
|
default:
|
|
var info = '';
|
|
if (this.getTotalBytes()) {
|
|
var p = this._renderPercentComplete();
|
|
var f = this._renderFileSize();
|
|
info = p + ' of ' + f;
|
|
}
|
|
|
|
var head;
|
|
if (this._isResume) {
|
|
head = 'Resuming:';
|
|
} else if (this._chunks) {
|
|
head = 'Uploading chunks:';
|
|
} else {
|
|
head = 'Uploading:';
|
|
}
|
|
|
|
info = [
|
|
JX.$N('strong', {}, this.getName()),
|
|
JX.$N('br'),
|
|
head + ' ' + 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, 10) + '%';
|
|
},
|
|
_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;
|
|
}
|
|
}
|
|
|
|
});
|