return BufferHandles from the media repository

BufferHandles are platform specific handles to a buffer. On web,
they have a .blob and .url property.
This commit is contained in:
Bruno Windels 2020-10-30 15:18:27 +01:00
parent 68a0dd30ca
commit 7d81306a49
5 changed files with 26 additions and 18 deletions

View file

@ -35,11 +35,12 @@ export class ImageTile extends MessageTile {
}
async _loadEncryptedFile(file) {
const buffer = await this._mediaRepository.downloadEncryptedFile(file);
const bufferHandle = await this._mediaRepository.downloadEncryptedFile(file);
if (this.isDisposed) {
bufferHandle.dispose();
return;
}
return this.track(this.platform.createBufferURL(buffer, file.mimetype));
return this.track(bufferHandle);
}
async load() {

View file

@ -167,8 +167,7 @@ export class SessionContainer {
this._requestScheduler.start();
const mediaRepository = new MediaRepository({
homeServer: sessionInfo.homeServer,
crypto: this._platform.crypto,
request: this._platform.request,
platform: this._platform,
});
this._session = new Session({
storage: this._storage,

View file

@ -18,10 +18,9 @@ import {encodeQueryParams} from "./common.js";
import {decryptAttachment} from "../e2ee/attachment.js";
export class MediaRepository {
constructor({homeServer, crypto, request}) {
constructor({homeServer, platform}) {
this._homeServer = homeServer;
this._crypto = crypto;
this._request = request;
this._platform = platform;
}
mxcUrlThumbnail(url, width, height, method) {
@ -55,8 +54,8 @@ export class MediaRepository {
async downloadEncryptedFile(fileEntry) {
const url = this.mxcUrl(fileEntry.url);
const {body: encryptedBuffer} = await this._request(url, {method: "GET", format: "buffer", cache: true}).response();
const decryptedBuffer = await decryptAttachment(this._crypto, encryptedBuffer, fileEntry);
return decryptedBuffer;
const {body: encryptedBuffer} = await this._platform.request(url, {method: "GET", format: "buffer", cache: true}).response();
const decryptedBuffer = await decryptAttachment(this._platform.crypto, encryptedBuffer, fileEntry);
return this._platform.createBufferHandle(decryptedBuffer, fileEntry.mimetype);
}
}

View file

@ -27,7 +27,7 @@ import {OnlineStatus} from "./dom/OnlineStatus.js";
import {Crypto} from "./dom/Crypto.js";
import {estimateStorageUsage} from "./dom/StorageEstimate.js";
import {WorkerPool} from "./dom/WorkerPool.js";
import {BufferURL} from "./dom/BufferURL.js";
import {BufferHandle} from "./dom/BufferHandle.js";
function addScript(src) {
return new Promise(function (resolve, reject) {
@ -129,7 +129,7 @@ export class Platform {
this._serviceWorkerHandler?.setNavigation(navigation);
}
createBufferURL(buffer, mimetype) {
return new BufferURL(buffer, mimetype);
createBufferHandle(buffer, mimetype) {
return new BufferHandle(buffer, mimetype);
}
}

View file

@ -69,18 +69,27 @@ const ALLOWED_BLOB_MIMETYPES = {
'audio/x-flac': true,
};
export class BufferURL {
export class BufferHandle {
constructor(buffer, mimetype) {
mimetype = mimetype ? mimetype.split(";")[0].trim() : '';
if (!ALLOWED_BLOB_MIMETYPES[mimetype]) {
mimetype = 'application/octet-stream';
}
const blob = new Blob([buffer], {type: mimetype});
this.url = URL.createObjectURL(blob);
this.blob = new Blob([buffer], {type: mimetype});
this._url = null;
}
get url() {
if (!this._url) {
this._url = URL.createObjectURL(this.blob);
}
return this._url;
}
dispose() {
URL.revokeObjectURL(this.url);
this.url = null;
if (this._url) {
URL.revokeObjectURL(this._url);
this._url = null;
}
}
}