report attachment upload progress
This commit is contained in:
parent
1dd46b875b
commit
83cbe78cd6
4 changed files with 31 additions and 10 deletions
|
@ -110,6 +110,7 @@ export class HomeServerApi {
|
||||||
headers,
|
headers,
|
||||||
body: encodedBody,
|
body: encodedBody,
|
||||||
timeout: options?.timeout,
|
timeout: options?.timeout,
|
||||||
|
uploadProgress: options?.uploadProgress,
|
||||||
format: "json" // response format
|
format: "json" // response format
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -35,12 +35,17 @@ export class AttachmentUpload {
|
||||||
this._aborted = false;
|
this._aborted = false;
|
||||||
this._error = null;
|
this._error = null;
|
||||||
this._status = new ObservableValue(UploadStatus.Waiting);
|
this._status = new ObservableValue(UploadStatus.Waiting);
|
||||||
|
this._progress = new ObservableValue(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
get status() {
|
get status() {
|
||||||
return this._status;
|
return this._status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get uploadProgress() {
|
||||||
|
return this._progress;
|
||||||
|
}
|
||||||
|
|
||||||
async upload() {
|
async upload() {
|
||||||
if (this._status.get() === UploadStatus.Waiting) {
|
if (this._status.get() === UploadStatus.Waiting) {
|
||||||
this._upload();
|
this._upload();
|
||||||
|
@ -66,9 +71,13 @@ export class AttachmentUpload {
|
||||||
if (this._aborted) {
|
if (this._aborted) {
|
||||||
throw new AbortError("upload aborted during encryption");
|
throw new AbortError("upload aborted during encryption");
|
||||||
}
|
}
|
||||||
|
this._progress.set(0);
|
||||||
this._status.set(UploadStatus.Uploading);
|
this._status.set(UploadStatus.Uploading);
|
||||||
this._uploadRequest = this._hsApi.uploadAttachment(transferredBlob, this._filename);
|
this._uploadRequest = this._hsApi.uploadAttachment(transferredBlob, this._filename, {
|
||||||
|
uploadProgress: sentBytes => this._progress.set(sentBytes / transferredBlob.size)
|
||||||
|
});
|
||||||
const {content_uri} = await this._uploadRequest.response();
|
const {content_uri} = await this._uploadRequest.response();
|
||||||
|
this._progress.set(1);
|
||||||
this._mxcUrl = content_uri;
|
this._mxcUrl = content_uri;
|
||||||
this._transferredBlob = transferredBlob;
|
this._transferredBlob = transferredBlob;
|
||||||
this._status.set(UploadStatus.Uploaded);
|
this._status.set(UploadStatus.Uploaded);
|
||||||
|
|
|
@ -21,6 +21,7 @@ import {
|
||||||
} from "../../../../matrix/error.js";
|
} from "../../../../matrix/error.js";
|
||||||
import {abortOnTimeout} from "./timeout.js";
|
import {abortOnTimeout} from "./timeout.js";
|
||||||
import {addCacheBuster} from "./common.js";
|
import {addCacheBuster} from "./common.js";
|
||||||
|
import {xhrRequest} from "./xhr.js";
|
||||||
|
|
||||||
class RequestResult {
|
class RequestResult {
|
||||||
constructor(promise, controller) {
|
constructor(promise, controller) {
|
||||||
|
@ -51,7 +52,12 @@ class RequestResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createFetchRequest(createTimeout) {
|
export function createFetchRequest(createTimeout) {
|
||||||
return function fetchRequest(url, {method, headers, body, timeout, format, cache = false}) {
|
return function fetchRequest(url, requestOptions) {
|
||||||
|
// fetch doesn't do upload progress yet, delegate to xhr
|
||||||
|
if (requestOptions?.uploadProgress) {
|
||||||
|
return xhrRequest(url, requestOptions);
|
||||||
|
}
|
||||||
|
let {method, headers, body, timeout, format, cache = false} = requestOptions;
|
||||||
const controller = typeof AbortController === "function" ? new AbortController() : null;
|
const controller = typeof AbortController === "function" ? new AbortController() : null;
|
||||||
// if a BlobHandle, take native blob
|
// if a BlobHandle, take native blob
|
||||||
if (body?.nativeBlob) {
|
if (body?.nativeBlob) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ class RequestResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function send(url, {method, headers, timeout, body, format}) {
|
function createXhr(url, {method, headers, timeout, format, uploadProgress}) {
|
||||||
const xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
xhr.open(method, url);
|
xhr.open(method, url);
|
||||||
|
|
||||||
|
@ -52,11 +52,9 @@ function send(url, {method, headers, timeout, body, format}) {
|
||||||
xhr.timeout = timeout;
|
xhr.timeout = timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if a BlobHandle, take native blob
|
if (uploadProgress) {
|
||||||
if (body?.nativeBlob) {
|
xhr.upload.addEventListener("progress", evt => uploadProgress(evt.loaded));
|
||||||
body = body.nativeBlob;
|
|
||||||
}
|
}
|
||||||
xhr.send(body || null);
|
|
||||||
|
|
||||||
return xhr;
|
return xhr;
|
||||||
}
|
}
|
||||||
|
@ -71,12 +69,12 @@ function xhrAsPromise(xhr, method, url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function xhrRequest(url, options) {
|
export function xhrRequest(url, options) {
|
||||||
const {cache, format} = options;
|
let {cache, format, body, method} = options;
|
||||||
if (!cache) {
|
if (!cache) {
|
||||||
url = addCacheBuster(url);
|
url = addCacheBuster(url);
|
||||||
}
|
}
|
||||||
const xhr = send(url, options);
|
const xhr = createXhr(url, options);
|
||||||
const promise = xhrAsPromise(xhr, options.method, url).then(xhr => {
|
const promise = xhrAsPromise(xhr, method, url).then(xhr => {
|
||||||
const {status} = xhr;
|
const {status} = xhr;
|
||||||
let body = null;
|
let body = null;
|
||||||
if (format === "buffer") {
|
if (format === "buffer") {
|
||||||
|
@ -86,5 +84,12 @@ export function xhrRequest(url, options) {
|
||||||
}
|
}
|
||||||
return {status, body};
|
return {status, body};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// if a BlobHandle, take native blob
|
||||||
|
if (body?.nativeBlob) {
|
||||||
|
body = body.nativeBlob;
|
||||||
|
}
|
||||||
|
xhr.send(body || null);
|
||||||
|
|
||||||
return new RequestResult(promise, xhr);
|
return new RequestResult(promise, xhr);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue