From 4875095ea3d2bd67f80db58367c8d3281cf99ba6 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 11 Sep 2020 17:47:35 +0200 Subject: [PATCH] fix event tiles not updating when event is decrypted when room keys come --- .../session/room/timeline/TilesCollection.js | 14 ++++++++++++++ .../session/room/timeline/UpdateAction.js | 17 +++++++++++++---- .../room/timeline/tiles/EncryptedEventTile.js | 11 +++++++++++ .../session/room/timeline/tiles/SimpleTile.js | 4 ++-- src/observable/list/SortedArray.js | 1 + .../session/room/timeline/TextMessageView.js | 2 +- 6 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/domain/session/room/timeline/TilesCollection.js b/src/domain/session/room/timeline/TilesCollection.js index 396aba9e..6854bd5e 100644 --- a/src/domain/session/room/timeline/TilesCollection.js +++ b/src/domain/session/room/timeline/TilesCollection.js @@ -144,6 +144,9 @@ export class TilesCollection extends BaseObservableList { const tile = this._findTileAtIdx(entry, tileIdx); if (tile) { const action = tile.updateEntry(entry, params); + if (action.shouldReplace) { + this._replaceTile(tileIdx, this._tileCreator(entry)); + } if (action.shouldRemove) { this._removeTile(tileIdx, tile); } @@ -164,6 +167,17 @@ export class TilesCollection extends BaseObservableList { // merge with neighbours? ... hard to imagine use case for this ... } + _replaceTile(tileIdx, newTile) { + const prevTile = this._getTileAtIdx(tileIdx - 1); + const nextTile = this._getTileAtIdx(tileIdx + 1); + this._tiles[tileIdx] = newTile; + prevTile?.updateNextSibling(newTile); + newTile.updatePreviousSibling(prevTile); + newTile.updateNextSibling(nextTile); + nextTile?.updatePreviousSibling(newTile); + this.emitUpdate(tileIdx, newTile, null); + } + _removeTile(tileIdx, tile) { const prevTile = this._getTileAtIdx(tileIdx - 1); const nextTile = this._getTileAtIdx(tileIdx + 1); diff --git a/src/domain/session/room/timeline/UpdateAction.js b/src/domain/session/room/timeline/UpdateAction.js index 193d903f..33a5dbe6 100644 --- a/src/domain/session/room/timeline/UpdateAction.js +++ b/src/domain/session/room/timeline/UpdateAction.js @@ -15,12 +15,17 @@ limitations under the License. */ export class UpdateAction { - constructor(remove, update, updateParams) { + constructor(remove, update, replace, updateParams) { this._remove = remove; this._update = update; + this._replace = replace; this._updateParams = updateParams; } + get shouldReplace() { + return this._replace; + } + get shouldRemove() { return this._remove; } @@ -34,14 +39,18 @@ export class UpdateAction { } static Remove() { - return new UpdateAction(true, false, null); + return new UpdateAction(true, false, false, null); } static Update(newParams) { - return new UpdateAction(false, true, newParams); + return new UpdateAction(false, true, false, newParams); } static Nothing() { - return new UpdateAction(false, false, null); + return new UpdateAction(false, false, false, null); + } + + static Replace() { + return new UpdateAction(false, false, true, null); } } diff --git a/src/domain/session/room/timeline/tiles/EncryptedEventTile.js b/src/domain/session/room/timeline/tiles/EncryptedEventTile.js index 537bd6d9..99c8a291 100644 --- a/src/domain/session/room/timeline/tiles/EncryptedEventTile.js +++ b/src/domain/session/room/timeline/tiles/EncryptedEventTile.js @@ -15,8 +15,19 @@ limitations under the License. */ import {MessageTile} from "./MessageTile.js"; +import {UpdateAction} from "../UpdateAction.js"; export class EncryptedEventTile extends MessageTile { + updateEntry(entry, params) { + const parentResult = super.updateEntry(entry, params); + // event got decrypted, recreate the tile and replace this one with it + if (entry.eventType !== "m.room.encrypted") { + return UpdateAction.Replace(); + } else { + return parentResult; + } + } + get text() { return this.i18n`**Encrypted message**`; } diff --git a/src/domain/session/room/timeline/tiles/SimpleTile.js b/src/domain/session/room/timeline/tiles/SimpleTile.js index 2ccb1d17..7b018b37 100644 --- a/src/domain/session/room/timeline/tiles/SimpleTile.js +++ b/src/domain/session/room/timeline/tiles/SimpleTile.js @@ -64,9 +64,9 @@ export class SimpleTile extends ViewModel { } // update received for already included (falls within sort keys) entry - updateEntry(entry) { + updateEntry(entry, params) { this._entry = entry; - return UpdateAction.Nothing(); + return UpdateAction.Update(params); } // return whether the tile should be removed diff --git a/src/observable/list/SortedArray.js b/src/observable/list/SortedArray.js index 3348307b..6d3e90c6 100644 --- a/src/observable/list/SortedArray.js +++ b/src/observable/list/SortedArray.js @@ -45,6 +45,7 @@ export class SortedArray extends BaseObservableList { const idx = this.indexOf(item); if (idx !== -1) { this._items[idx] = item; + this.emitUpdate(idx, item, null); } } diff --git a/src/ui/web/session/room/timeline/TextMessageView.js b/src/ui/web/session/room/timeline/TextMessageView.js index d3d8e167..886eae5d 100644 --- a/src/ui/web/session/room/timeline/TextMessageView.js +++ b/src/ui/web/session/room/timeline/TextMessageView.js @@ -20,7 +20,7 @@ import {renderMessage} from "./common.js"; export class TextMessageView extends TemplateView { render(t, vm) { return renderMessage(t, vm, - [t.p([vm.text, t.time({className: {hidden: !vm.date}}, vm.date + " " + vm.time)])] + [t.p([vm => vm.text, t.time({className: {hidden: !vm.date}}, vm.date + " " + vm.time)])] ); } }