From cbd48aa5286197d4ef4cdf86c27f3054e6e954f3 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 26 Oct 2020 09:49:42 +0100 Subject: [PATCH] only load main image when clicking thumbnail --- .../session/room/timeline/tiles/ImageTile.js | 48 ++++++++++++------- src/ui/web/session/room/timeline/ImageView.js | 13 ++++- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/src/domain/session/room/timeline/tiles/ImageTile.js b/src/domain/session/room/timeline/tiles/ImageTile.js index 670ec774..55dc5acb 100644 --- a/src/domain/session/room/timeline/tiles/ImageTile.js +++ b/src/domain/session/room/timeline/tiles/ImageTile.js @@ -23,26 +23,37 @@ export class ImageTile extends MessageTile { constructor(options) { super(options); + this._decryptedThumbailUrl = null; this._decryptedUrl = null; this.load(); } + async _loadEncryptedFile(file) { + const buffer = await this._mediaRepository.downloadEncryptedFile(file); + // TODO: fix XSS bug here by not checking mimetype + const blob = new Blob([buffer], {type: file.mimetype}); + if (this.isDisposed) { + return; + } + return URL.createObjectURL(blob); + } + async load() { - const thumbnailFile = this._getContent().file; + const thumbnailFile = this._getContent().info?.thumbnail_file; + const file = this._getContent().file; if (thumbnailFile) { - const buffer = await this._mediaRepository.downloadEncryptedFile(thumbnailFile); - // TODO: fix XSS bug here by not checking mimetype - const blob = new Blob([buffer], {type: thumbnailFile.mimetype}); - if (this.isDisposed) { - return; - } - this._decryptedUrl = URL.createObjectURL(blob); + this._decryptedThumbailUrl = await this._loadEncryptedFile(thumbnailFile); + this.emitChange("thumbnailUrl"); + } else if (file) { + this._decryptedUrl = await this._loadEncryptedFile(file); this.emitChange("thumbnailUrl"); } } get thumbnailUrl() { - if (this._decryptedUrl) { + if (this._decryptedThumbailUrl) { + return this._decryptedThumbailUrl; + } else if (this._decryptedUrl) { return this._decryptedUrl; } const mxcUrl = this._getContent()?.url; @@ -52,15 +63,14 @@ export class ImageTile extends MessageTile { return ""; } - get url() { - if (this._decryptedUrl) { - return this._decryptedUrl; + async loadImageUrl() { + if (!this._decryptedUrl) { + const file = this._getContent().file; + if (file) { + this._decryptedUrl = await this._loadEncryptedFile(file); + } } - const mxcUrl = this._getContent()?.url; - if (typeof mxcUrl === "string") { - return this._mediaRepository.mxcUrl(mxcUrl); - } - return ""; + return this._decryptedUrl || ""; } _scaleFactor() { @@ -91,6 +101,10 @@ export class ImageTile extends MessageTile { } dispose() { + if (this._decryptedThumbailUrl) { + URL.revokeObjectURL(this._decryptedThumbailUrl); + this._decryptedThumbailUrl = null; + } if (this._decryptedUrl) { URL.revokeObjectURL(this._decryptedUrl); this._decryptedUrl = null; diff --git a/src/ui/web/session/room/timeline/ImageView.js b/src/ui/web/session/room/timeline/ImageView.js index 0cc918f7..06d479f3 100644 --- a/src/ui/web/session/room/timeline/ImageView.js +++ b/src/ui/web/session/room/timeline/ImageView.js @@ -30,7 +30,8 @@ export class ImageView extends TemplateView { alt: vm.label, }); const linkContainer = t.a({ - href: vm => vm.url, + href: "#", + onClick: evt => this.openImage(evt), target: "_blank", style: `padding-top: ${heightRatioPercent}%; width: ${vm.thumbnailWidth}px;` }, image); @@ -39,4 +40,14 @@ export class ImageView extends TemplateView { [t.div(linkContainer), t.p(t.time(vm.date + " " + vm.time))] ); } + + async openImage(evt) { + const link = evt.currentTarget; + if (link.getAttribute("href") === "#") { + evt.preventDefault(); + const url = await this.value.loadImageUrl(); + link.setAttribute("href", url); + link.click(); + } + } }