diff --git a/lib/models/room.js b/lib/models/room.js index 462e707f1..b3958782d 100644 --- a/lib/models/room.js +++ b/lib/models/room.js @@ -35,6 +35,7 @@ function Room(roomId, storageToken) { this.currentState = new RoomState(roomId); this.summary = null; this.storageToken = storageToken; + this._redactions = []; } utils.inherits(Room, EventEmitter); @@ -94,6 +95,10 @@ utils.inherits(Room, EventEmitter); Room.prototype.addEventsToTimeline = function(events, toStartOfTimeline) { var stateContext = toStartOfTimeline ? this.oldState : this.currentState; for (var i = 0; i < events.length; i++) { + if (toStartOfTimeline && this._redactions.indexOf(events[i].getId()) >= 0) { + continue; // do not add the redacted event. + } + setEventMetadata(events[i], stateContext, toStartOfTimeline); // modify state if (events[i].isState()) { @@ -105,6 +110,20 @@ Room.prototype.addEventsToTimeline = function(events, toStartOfTimeline) { setEventMetadata(events[i], stateContext, toStartOfTimeline); } } + if (events[i].getType() === "m.room.redaction") { + // try to remove the element + var removed = utils.removeElement(this.timeline, function(e) { + return e.getId() === events[i].event.redacts + }, true); + if (!removed && toStartOfTimeline) { + // redactions will trickle in BEFORE the event redacted so make + // a note of the redacted event; we'll check it later. + this._redactions.push(events[i].event.redacts); + } + // NB: We continue to add the redaction event to the timeline so clients + // can say "so and so redacted an event" if they wish to. + } + // TODO: pass through filter to see if this should be added to the timeline. if (toStartOfTimeline) { this.timeline.unshift(events[i]); diff --git a/lib/utils.js b/lib/utils.js index f7b1547b8..55edd993b 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -148,6 +148,7 @@ module.exports.findElement = function(array, fn, reverse) { * function signature fn(element, index, array). Return true to * remove this element and break. * @param {boolean} reverse True to search in reverse order. + * @return True if an element was removed. */ module.exports.removeElement = function(array, fn, reverse) { var i; @@ -155,17 +156,19 @@ module.exports.removeElement = function(array, fn, reverse) { for (i = array.length - 1; i >= 0; i--) { if (fn(array[i], i, array)) { array.splice(i, 1); - return; } + return true; + } } } else { for (i = 0; i < array.length; i++) { if (fn(array[i], i, array)) { array.splice(i, 1); - return; + return true; } } } + return false; }; /**