1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-28 05:03:59 +03:00

Add ability to cancel file uploads

This commit is contained in:
David Baker
2015-12-02 18:14:13 +00:00
parent 0c114a2ab3
commit 92ea275275
2 changed files with 67 additions and 8 deletions

View File

@@ -1284,6 +1284,27 @@ MatrixClient.prototype.uploadContent = function(file, callback) {
return this._http.uploadContent(file, callback); return this._http.uploadContent(file, callback);
}; };
/**
* Cancel a file upload in progress
* @param {module:client.Promise} promise The promise returned from uploadContent
* @return {boolean} true if canceled, otherwise false
*/
MatrixClient.prototype.cancelUpload = function(promise) {
return this._http.cancelUpload(promise);
};
/**
* Get a list of all file uploads in progress
* @return {array} Array of objects representing current uploads.
* Currently in progress is element 0. Keys:
* - promise: The promise associated with the upload
* - loaded: Number of bytes uploaded
* - total: Total number of bytes to upload
*/
MatrixClient.prototype.getCurrentUploads = function() {
return this._http.getCurrentUploads();
};
/** /**
* @param {string} roomId * @param {string} roomId
* @param {boolean} isTyping * @param {boolean} isTyping

View File

@@ -50,6 +50,7 @@ module.exports.MatrixHttpApi = function MatrixHttpApi(opts) {
utils.checkObjectHasKeys(opts, ["baseUrl", "request", "prefix"]); utils.checkObjectHasKeys(opts, ["baseUrl", "request", "prefix"]);
opts.onlyData = opts.onlyData || false; opts.onlyData = opts.onlyData || false;
this.opts = opts; this.opts = opts;
this.uploads = [];
}; };
module.exports.MatrixHttpApi.prototype = { module.exports.MatrixHttpApi.prototype = {
@@ -95,8 +96,12 @@ module.exports.MatrixHttpApi.prototype = {
// use XMLHttpRequest directly. // use XMLHttpRequest directly.
// (browser-request doesn't support progress either, which is also kind // (browser-request doesn't support progress either, which is also kind
// of important here) // of important here)
var upload = { loaded: 0, total: 0 };
if (global.XMLHttpRequest) { if (global.XMLHttpRequest) {
var xhr = new global.XMLHttpRequest(); var xhr = new global.XMLHttpRequest();
upload.xhr = xhr;
var cb = requestCallback(defer, callback, this.opts.onlyData); var cb = requestCallback(defer, callback, this.opts.onlyData);
var timeout_fn = function() { var timeout_fn = function() {
@@ -128,6 +133,8 @@ module.exports.MatrixHttpApi.prototype = {
}; };
xhr.upload.addEventListener("progress", function(ev) { xhr.upload.addEventListener("progress", function(ev) {
clearTimeout(xhr.timeout_timer); clearTimeout(xhr.timeout_timer);
upload.loaded = ev.loaded;
upload.total = ev.total;
xhr.timeout_timer = setTimeout(timeout_fn, 30000); xhr.timeout_timer = setTimeout(timeout_fn, 30000);
defer.notify(ev); defer.notify(ev);
}); });
@@ -148,16 +155,47 @@ module.exports.MatrixHttpApi.prototype = {
filename: file.name, filename: file.name,
access_token: this.opts.accessToken access_token: this.opts.accessToken
}; };
file.stream.pipe( upload.request = this.opts.request({
this.opts.request({ uri: url,
uri: url, qs: queryParams,
qs: queryParams, method: "POST"
method: "POST" }, requestCallback(defer, callback, this.opts.onlyData));
}, requestCallback(defer, callback, this.opts.onlyData)) file.stream.pipe(this.opts.request);
);
} }
return defer.promise; this.uploads.push(upload);
var self = this;
upload.promise = defer.promise.finally(function() {
var uploadsKeys = Object.keys(self.uploads);
for (var i = 0; i < uploadsKeys.length; ++i) {
if (self.uploads[uploadsKeys[i]].promise === defer.promise) {
self.uploads.splice(uploadsKeys[i], 1);
}
}
});
return upload.promise;
},
cancelUpload: function(promise) {
var uploadsKeys = Object.keys(this.uploads);
for (var i = 0; i < uploadsKeys.length; ++i) {
var upload = this.uploads[uploadsKeys[i]];
if (upload.promise === promise) {
if (upload.xhr !== undefined) {
upload.xhr.abort();
return true;
} else if (upload.request !== undefined) {
upload.request.abort();
return true;
}
}
}
return false;
},
getCurrentUploads: function() {
return this.uploads;
}, },
idServerRequest: function(callback, method, path, params, prefix) { idServerRequest: function(callback, method, path, params, prefix) {