diff --git a/src/matrix/room/timeline/Timeline.js b/src/matrix/room/timeline/Timeline.js index 0b6fb5ec..36bcc110 100644 --- a/src/matrix/room/timeline/Timeline.js +++ b/src/matrix/room/timeline/Timeline.js @@ -122,7 +122,9 @@ export class Timeline { for (const entry of entries) { // this will use the comparator and thus // check for equality using the compare method in BaseEntry - this._remoteEntries.update(entry); + this._remoteEntries.findAndUpdate(entry, (previousEntry, entry) => { + entry.transferLocalEchoState(previousEntry); + }); } } diff --git a/src/matrix/room/timeline/entries/BaseEventEntry.js b/src/matrix/room/timeline/entries/BaseEventEntry.js index 4706f5f2..a3748c8b 100644 --- a/src/matrix/room/timeline/entries/BaseEventEntry.js +++ b/src/matrix/room/timeline/entries/BaseEventEntry.js @@ -31,6 +31,11 @@ export class BaseEventEntry extends BaseEntry { return this.isRedacting; } + // when replacing an entry, local echo state can be transfered here + transferLocalEchoState(oldEntry) { + if (oldEntry._pendingRedactions) { + this._pendingRedactions = oldEntry._pendingRedactions; + } } /** diff --git a/src/observable/list/SortedArray.js b/src/observable/list/SortedArray.js index 24378658..d2663f37 100644 --- a/src/observable/list/SortedArray.js +++ b/src/observable/list/SortedArray.js @@ -41,6 +41,22 @@ export class SortedArray extends BaseObservableList { } } + findAndUpdate(newValue, updater) { + const index = this.indexOf(newValue); + if (index !== -1) { + const oldValue = this._items[index]; + // allow bailing out of sending an emit if updater determined its not needed + const params = updater(oldValue, newValue); + if (params !== false) { + this._items[index] = newValue; + this.emitUpdate(index, newValue, params); + } + // found + return true; + } + return false; + } + update(item, updateParams = null) { const idx = this.indexOf(item); if (idx !== -1) {