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) { async _loadEncryptedFile(file) {
const buffer = await this._mediaRepository.downloadEncryptedFile(file); const bufferHandle = await this._mediaRepository.downloadEncryptedFile(file);
if (this.isDisposed) { if (this.isDisposed) {
bufferHandle.dispose();
return; return;
} }
return this.track(this.platform.createBufferURL(buffer, file.mimetype)); return this.track(bufferHandle);
} }
async load() { async load() {

View file

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

View file

@ -18,10 +18,9 @@ import {encodeQueryParams} from "./common.js";
import {decryptAttachment} from "../e2ee/attachment.js"; import {decryptAttachment} from "../e2ee/attachment.js";
export class MediaRepository { export class MediaRepository {
constructor({homeServer, crypto, request}) { constructor({homeServer, platform}) {
this._homeServer = homeServer; this._homeServer = homeServer;
this._crypto = crypto; this._platform = platform;
this._request = request;
} }
mxcUrlThumbnail(url, width, height, method) { mxcUrlThumbnail(url, width, height, method) {
@ -55,8 +54,8 @@ export class MediaRepository {
async downloadEncryptedFile(fileEntry) { async downloadEncryptedFile(fileEntry) {
const url = this.mxcUrl(fileEntry.url); const url = this.mxcUrl(fileEntry.url);
const {body: encryptedBuffer} = await this._request(url, {method: "GET", format: "buffer", cache: true}).response(); const {body: encryptedBuffer} = await this._platform.request(url, {method: "GET", format: "buffer", cache: true}).response();
const decryptedBuffer = await decryptAttachment(this._crypto, encryptedBuffer, fileEntry); const decryptedBuffer = await decryptAttachment(this._platform.crypto, encryptedBuffer, fileEntry);
return decryptedBuffer; 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 {Crypto} from "./dom/Crypto.js";
import {estimateStorageUsage} from "./dom/StorageEstimate.js"; import {estimateStorageUsage} from "./dom/StorageEstimate.js";
import {WorkerPool} from "./dom/WorkerPool.js"; import {WorkerPool} from "./dom/WorkerPool.js";
import {BufferURL} from "./dom/BufferURL.js"; import {BufferHandle} from "./dom/BufferHandle.js";
function addScript(src) { function addScript(src) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
@ -129,7 +129,7 @@ export class Platform {
this._serviceWorkerHandler?.setNavigation(navigation); this._serviceWorkerHandler?.setNavigation(navigation);
} }
createBufferURL(buffer, mimetype) { createBufferHandle(buffer, mimetype) {
return new BufferURL(buffer, mimetype); return new BufferHandle(buffer, mimetype);
} }
} }

View file

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