diff --git a/lib/filter-component.js b/lib/filter-component.js index 236de7a77..6c1e289f6 100644 --- a/lib/filter-component.js +++ b/lib/filter-component.js @@ -51,21 +51,15 @@ function FilterComponent(filter_json) { /** * Checks with the filter component matches the given event + * + * Takes a MatrixEvent object */ FilterComponent.prototype.check = function(event) { - var sender = event.sender; - if (!sender) { - // Presence events have their 'sender' in content.user_id - if (event.content) { - sender = event.content.user_id; - } - } - return this.checkFields( - event.room_id, - sender, - event.type, - event.content ? event.content.url !== undefined : false + event.getRoomId(), + event.getSender(), + event.getType(), + event.getContent() ? event.getContent().url !== undefined : false ); }; @@ -81,15 +75,16 @@ FilterComponent.prototype.checkFields = "types": function(v) { return _matches_wildcard(event_type, v); }, }; + var self = this; Object.keys(literal_keys).forEach(function(name) { var match_func = literal_keys[name]; var not_name = "not_" + name; - var disallowed_values = this[not_name]; + var disallowed_values = self[not_name]; if (disallowed_values.map(match_func)) { return false; } - var allowed_values = this[name]; + var allowed_values = self[name]; if (allowed_values) { if (!allowed_values.map(match_func)) { return false; @@ -108,7 +103,7 @@ FilterComponent.prototype.checkFields = }; FilterComponent.prototype.filter = function(events) { - return events.filter(this.check); + return events.filter(this.check, this); }; FilterComponent.prototype.limit = function() { diff --git a/lib/models/event-timeline-set.js b/lib/models/event-timeline-set.js index 1f5823926..26ea4a1ec 100644 --- a/lib/models/event-timeline-set.js +++ b/lib/models/event-timeline-set.js @@ -71,7 +71,7 @@ utils.inherits(EventTimelineSet, EventEmitter); /** * Get the filter object this timeline list is filtered on */ -EventTimeline.prototype.getFilter = function() { +EventTimelineSet.prototype.getFilter = function() { return this._filter; }; @@ -79,10 +79,30 @@ EventTimeline.prototype.getFilter = function() { * Set the filter object this timeline list is filtered on * (passed to the server when paginating via /messages). */ -EventTimeline.prototype.setFilter = function(filter) { +EventTimelineSet.prototype.setFilter = function(filter) { this._filter = filter; }; +/** + * Get the list of pending sent events for this timelineSet's room, filtered + * by the timelineSet's filter if appropriate. + * + * @return {module:models/event.MatrixEvent[]} A list of the sent events + * waiting for remote echo. + * + * @throws If opts.pendingEventOrdering was not 'detached' + */ +EventTimelineSet.prototype.getPendingEvents = function() { + if (!this.room) return []; + + if (this._filter) { + return this._filter.filterRoomTimeline(this.room.getPendingEvents()); + } + else { + return this.room.getPendingEvents(); + } +}; + /** * Get the live timeline for this room. * @@ -224,7 +244,7 @@ EventTimelineSet.prototype.addEventsToTimeline = function(events, toStartOfTimel if (this._filter) { events = this._filter.filterRoomTimeline(events); - if (!events) { + if (!events.length) { return; } } @@ -372,7 +392,7 @@ EventTimelineSet.prototype.addEventsToTimeline = function(events, toStartOfTimel EventTimelineSet.prototype.addLiveEvent = function(event, duplicateStrategy) { if (this._filter) { var events = this._filter.filterRoomTimeline([event]); - if (!events) { + if (!events.length) { return; } } @@ -443,7 +463,14 @@ EventTimelineSet.prototype.replaceOrAddEvent = function(localEvent, oldEventId, delete this._eventIdToTimeline[oldEventId]; this._eventIdToTimeline[newEventId] = existingTimeline; } else { - this.addEventToTimeline(localEvent, this._liveTimeline, false); + if (this._filter) { + if (this._filter.filterRoomTimeline([localEvent]).length) { + this.addEventToTimeline(localEvent, this._liveTimeline, false); + } + } + else { + this.addEventToTimeline(localEvent, this._liveTimeline, false); + } } }; diff --git a/lib/models/room.js b/lib/models/room.js index cca017c48..c5fdd21b4 100644 --- a/lib/models/room.js +++ b/lib/models/room.js @@ -464,11 +464,8 @@ Room.prototype.getOrCreateFilteredTimelineSet = function(filter) { if (this._filteredTimelineSets[filter.filterId]) { return this._filteredTimelineSets[filter.filterId]; } - var timelineSet = new EventTimelineSet( - this.roomId, this, { - filter: filter, - } - ); + var opts = Object.assign({ filter: filter }, this._opts); + var timelineSet = new EventTimelineSet(this.roomId, this, opts); reEmit(this, timelineSet, [ "Room.timeline" ]); this._filteredTimelineSets[filter.filterId] = timelineSet; this._timelineSets.push(timelineSet); @@ -607,7 +604,15 @@ Room.prototype.addPendingEvent = function(event, txnId) { this._pendingEventList.push(event); } else { for (var i = 0; i < this._timelineSets.length; i++) { - this._timelineSets[i].addEventToTimeline(event, this._timelineSets[i].getLiveTimeline(), false); + var timelineSet = this._timelineSets[i]; + if (timelineSet.getFilter()) { + if (this._filter.filterRoomTimeline([event]).length) { + timelineSet.addEventToTimeline(event, timelineSet.getLiveTimeline(), false); + } + } + else { + timelineSet.addEventToTimeline(event, timelineSet.getLiveTimeline(), false); + } } // notifications are receive-only, so we don't need to worry about this._notifTimelineSet. }