From 2daa1b6007508e2ea9e39c79dbf5565d63ae555f Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 4 Sep 2016 13:57:56 +0100 Subject: [PATCH] change TimelineWindow to take a timelineSet rather than a Room --- lib/client.js | 25 +++++------ lib/models/room.js | 14 ++++++ lib/timeline-window.js | 11 ++--- .../matrix-client-event-timeline.spec.js | 43 ++++++++++++------- spec/unit/timeline-window.spec.js | 26 +++++------ 5 files changed, 73 insertions(+), 46 deletions(-) diff --git a/lib/client.js b/lib/client.js index a9c2ac740..84c527201 100644 --- a/lib/client.js +++ b/lib/client.js @@ -1618,18 +1618,18 @@ MatrixClient.prototype.paginateEventContext = function(eventContext, opts) { /** * Get an EventTimeline for the given event * - *

If the room object already has the given event in its store, the + *

If the EventTimelineSet object already has the given event in its store, the * corresponding timeline will be returned. Otherwise, a /context request is * made, and used to construct an EventTimeline. * - * @param {Room} room The room to look for the event in + * @param {EventTimelineSet} timelineSet The timelineSet to look for the event in * @param {string} eventId The ID of the event to look for * * @return {module:client.Promise} Resolves: * {@link module:models/event-timeline~EventTimeline} including the given * event */ -MatrixClient.prototype.getEventTimeline = function(room, eventId) { +MatrixClient.prototype.getEventTimeline = function(timelineSet, eventId) { // don't allow any timeline support unless it's been enabled. if (!this.timelineSupport) { throw new Error("timeline support is disabled. Set the 'timelineSupport'" + @@ -1637,13 +1637,13 @@ MatrixClient.prototype.getEventTimeline = function(room, eventId) { " it."); } - if (room.getTimelineForEvent(eventId)) { - return q(room.getTimelineForEvent(eventId)); + if (timelineSet.getTimelineForEvent(eventId)) { + return q(timelineSet.getTimelineForEvent(eventId)); } var path = utils.encodeUri( "/rooms/$roomId/context/$eventId", { - $roomId: room.roomId, + $roomId: timelineSet.room.roomId, $eventId: eventId, } ); @@ -1660,8 +1660,8 @@ MatrixClient.prototype.getEventTimeline = function(room, eventId) { // by the time the request completes, the event might have ended up in // the timeline. - if (room.getTimelineForEvent(eventId)) { - return room.getTimelineForEvent(eventId); + if (timelineSet.getTimelineForEvent(eventId)) { + return timelineSet.getTimelineForEvent(eventId); } // we start with the last event, since that's the point at which we @@ -1673,21 +1673,22 @@ MatrixClient.prototype.getEventTimeline = function(room, eventId) { .concat(res.events_before); var matrixEvents = utils.map(events, self.getEventMapper()); - var timeline = room.getTimelineForEvent(matrixEvents[0].getId()); + var timeline = timelineSet.getTimelineForEvent(matrixEvents[0].getId()); if (!timeline) { - timeline = room.addTimeline(); + timeline = timelineSet.addTimeline(); timeline.initialiseState(utils.map(res.state, self.getEventMapper())); timeline.getState(EventTimeline.FORWARDS).paginationToken = res.end; } - room.addEventsToTimeline(matrixEvents, true, timeline, res.start); + timelineSet.addEventsToTimeline(matrixEvents, true, timeline, res.start); // there is no guarantee that the event ended up in "timeline" (we // might have switched to a neighbouring timeline) - so check the // room's index again. On the other hand, there's no guarantee the // event ended up anywhere, if it was later redacted, so we just // return the timeline we first thought of. - return room.getTimelineForEvent(eventId) || timeline; + var tl = timelineSet.getTimelineForEvent(eventId) || timeline; + return tl; }); return promise; }; diff --git a/lib/models/room.js b/lib/models/room.js index 60c5a608c..b337a05b1 100644 --- a/lib/models/room.js +++ b/lib/models/room.js @@ -244,6 +244,20 @@ Room.prototype._fixUpLegacyTimelineFields = function() { this.currentState = this._timelineSets[0].getLiveTimeline().getState(EventTimeline.FORWARDS); }; +/** + * Return the timeline sets for this room + */ +Room.prototype.getTimelineSets = function() { + return this._timelineSets; +}; + +/** + * Return the notification timeline set for this room + */ +Room.prototype.getNotifTimelineSet = function() { + return this._notifTimelineSet; +}; + /** * Get the timeline which contains the given event from the unfiltered set, if any * diff --git a/lib/timeline-window.js b/lib/timeline-window.js index 89acec9dc..bbe16fb31 100644 --- a/lib/timeline-window.js +++ b/lib/timeline-window.js @@ -19,6 +19,7 @@ limitations under the License. var q = require("q"); var EventTimeline = require("./models/event-timeline"); +var EventTimelineSet = require("./models/event-timeline-set"); /** * @private @@ -56,7 +57,7 @@ var DEFAULT_PAGINATE_LOOP_LIMIT = 5; * @param {MatrixClient} client MatrixClient to be used for context/pagination * requests. * - * @param {Room} room The room to track + * @param {EventTimelineSet} timelineSet The timelineSet to track * * @param {Object} [opts] Configuration options for this window * @@ -66,10 +67,10 @@ var DEFAULT_PAGINATE_LOOP_LIMIT = 5; * * @constructor */ -function TimelineWindow(client, room, opts) { +function TimelineWindow(client, timelineSet, opts) { opts = opts || {}; this._client = client; - this._room = room; + this._timelineSet = timelineSet; // these will be TimelineIndex objects; they delineate the 'start' and // 'end' of the window. @@ -113,7 +114,7 @@ TimelineWindow.prototype.load = function(initialEventId, initialWindowSize) { // TODO: ideally we'd spot getEventTimeline returning a resolved promise and // skip straight to the find-event loop. if (initialEventId) { - return this._client.getEventTimeline(this._room, initialEventId) + return this._client.getEventTimeline(this._timelineSet, initialEventId) .then(function(tl) { // make sure that our window includes the event for (var i = 0; i < tl.getEvents().length; i++) { @@ -126,7 +127,7 @@ TimelineWindow.prototype.load = function(initialEventId, initialWindowSize) { }); } else { // start with the most recent events - var tl = this._room.getLiveTimeline(); + var tl = this._timelineSet.getLiveTimeline(); initFields(tl, tl.getEvents().length); return q(); } diff --git a/spec/integ/matrix-client-event-timeline.spec.js b/spec/integ/matrix-client-event-timeline.spec.js index 6d77cd4d8..b5cac3959 100644 --- a/spec/integ/matrix-client-event-timeline.spec.js +++ b/spec/integ/matrix-client-event-timeline.spec.js @@ -121,7 +121,8 @@ describe("getEventTimeline support", function() { startClient(httpBackend, client ).then(function() { var room = client.getRoom(roomId); - expect(function() { client.getEventTimeline(room, "event"); }) + var timelineSet = room.getTimelineSets()[0]; + expect(function() { client.getEventTimeline(timelineSet, "event"); }) .toThrow(); }).catch(utils.failTest).done(done); }); @@ -137,7 +138,8 @@ describe("getEventTimeline support", function() { startClient(httpBackend, client ).then(function() { var room = client.getRoom(roomId); - expect(function() { client.getEventTimeline(room, "event"); }) + var timelineSet = room.getTimelineSets()[0]; + expect(function() { client.getEventTimeline(timelineSet, "event"); }) .not.toThrow(); }).catch(utils.failTest).done(done); @@ -242,6 +244,7 @@ describe("MatrixClient event timelines", function() { describe("getEventTimeline", function() { it("should create a new timeline for new events", function(done) { var room = client.getRoom(roomId); + var timelineSet = room.getTimelineSets()[0]; httpBackend.when("GET", "/rooms/!foo%3Abar/context/event1%3Abar") .respond(200, function() { return { @@ -257,7 +260,7 @@ describe("MatrixClient event timelines", function() { }; }); - client.getEventTimeline(room, "event1:bar").then(function(tl) { + client.getEventTimeline(timelineSet, "event1:bar").then(function(tl) { expect(tl.getEvents().length).toEqual(4); for (var i = 0; i < 4; i++) { expect(tl.getEvents()[i].event).toEqual(EVENTS[i]); @@ -274,6 +277,7 @@ describe("MatrixClient event timelines", function() { it("should return existing timeline for known events", function(done) { var room = client.getRoom(roomId); + var timelineSet = room.getTimelineSets()[0]; httpBackend.when("GET", "/sync").respond(200, { next_batch: "s_5_4", rooms: { @@ -291,7 +295,7 @@ describe("MatrixClient event timelines", function() { }); httpBackend.flush("/sync").then(function() { - return client.getEventTimeline(room, EVENTS[0].event_id); + return client.getEventTimeline(timelineSet, EVENTS[0].event_id); }).then(function(tl) { expect(tl.getEvents().length).toEqual(2); expect(tl.getEvents()[1].event).toEqual(EVENTS[0]); @@ -305,6 +309,7 @@ describe("MatrixClient event timelines", function() { it("should update timelines where they overlap a previous /sync", function(done) { var room = client.getRoom(roomId); + var timelineSet = room.getTimelineSets()[0]; httpBackend.when("GET", "/sync").respond(200, { next_batch: "s_5_4", rooms: { @@ -335,7 +340,7 @@ describe("MatrixClient event timelines", function() { }); client.on("sync", function() { - client.getEventTimeline(room, EVENTS[2].event_id + client.getEventTimeline(timelineSet, EVENTS[2].event_id ).then(function(tl) { expect(tl.getEvents().length).toEqual(4); expect(tl.getEvents()[0].event).toEqual(EVENTS[1]); @@ -354,6 +359,7 @@ describe("MatrixClient event timelines", function() { it("should join timelines where they overlap a previous /context", function(done) { var room = client.getRoom(roomId); + var timelineSet = room.getTimelineSets()[0]; // we fetch event 0, then 2, then 3, and finally 1. 1 is returned // with context which joins them all up. @@ -410,19 +416,19 @@ describe("MatrixClient event timelines", function() { }); var tl0, tl2, tl3; - client.getEventTimeline(room, EVENTS[0].event_id + client.getEventTimeline(timelineSet, EVENTS[0].event_id ).then(function(tl) { expect(tl.getEvents().length).toEqual(1); tl0 = tl; - return client.getEventTimeline(room, EVENTS[2].event_id); + return client.getEventTimeline(timelineSet, EVENTS[2].event_id); }).then(function(tl) { expect(tl.getEvents().length).toEqual(1); tl2 = tl; - return client.getEventTimeline(room, EVENTS[3].event_id); + return client.getEventTimeline(timelineSet, EVENTS[3].event_id); }).then(function(tl) { expect(tl.getEvents().length).toEqual(1); tl3 = tl; - return client.getEventTimeline(room, EVENTS[1].event_id); + return client.getEventTimeline(timelineSet, EVENTS[1].event_id); }).then(function(tl) { // we expect it to get merged in with event 2 expect(tl.getEvents().length).toEqual(2); @@ -447,6 +453,7 @@ describe("MatrixClient event timelines", function() { it("should fail gracefully if there is no event field", function(done) { var room = client.getRoom(roomId); + var timelineSet = room.getTimelineSets()[0]; // we fetch event 0, then 2, then 3, and finally 1. 1 is returned // with context which joins them all up. httpBackend.when("GET", "/rooms/!foo%3Abar/context/event1") @@ -460,7 +467,7 @@ describe("MatrixClient event timelines", function() { }; }); - client.getEventTimeline(room, "event1" + client.getEventTimeline(timelineSet, "event1" ).then(function(tl) { // could do with a fail() expect(true).toBeFalsy(); @@ -475,6 +482,7 @@ describe("MatrixClient event timelines", function() { describe("paginateEventTimeline", function() { it("should allow you to paginate backwards", function(done) { var room = client.getRoom(roomId); + var timelineSet = room.getTimelineSets()[0]; httpBackend.when("GET", "/rooms/!foo%3Abar/context/" + encodeURIComponent(EVENTS[0].event_id)) @@ -503,7 +511,7 @@ describe("MatrixClient event timelines", function() { }); var tl; - client.getEventTimeline(room, EVENTS[0].event_id + client.getEventTimeline(timelineSet, EVENTS[0].event_id ).then(function(tl0) { tl = tl0; return client.paginateEventTimeline(tl, {backwards: true}); @@ -525,6 +533,7 @@ describe("MatrixClient event timelines", function() { it("should allow you to paginate forwards", function(done) { var room = client.getRoom(roomId); + var timelineSet = room.getTimelineSets()[0]; httpBackend.when("GET", "/rooms/!foo%3Abar/context/" + encodeURIComponent(EVENTS[0].event_id)) @@ -553,7 +562,7 @@ describe("MatrixClient event timelines", function() { }); var tl; - client.getEventTimeline(room, EVENTS[0].event_id + client.getEventTimeline(timelineSet, EVENTS[0].event_id ).then(function(tl0) { tl = tl0; return client.paginateEventTimeline( @@ -607,10 +616,11 @@ describe("MatrixClient event timelines", function() { it("should work when /send returns before /sync", function(done) { var room = client.getRoom(roomId); + var timelineSet = room.getTimelineSets()[0]; client.sendTextMessage(roomId, "a body", TXN_ID).then(function(res) { expect(res.event_id).toEqual(event.event_id); - return client.getEventTimeline(room, event.event_id); + return client.getEventTimeline(timelineSet, event.event_id); }).then(function(tl) { // 2 because the initial sync contained an event expect(tl.getEvents().length).toEqual(2); @@ -619,7 +629,7 @@ describe("MatrixClient event timelines", function() { // now let the sync complete, and check it again return httpBackend.flush("/sync", 1); }).then(function() { - return client.getEventTimeline(room, event.event_id); + return client.getEventTimeline(timelineSet, event.event_id); }).then(function(tl) { expect(tl.getEvents().length).toEqual(2); expect(tl.getEvents()[1].event).toEqual(event); @@ -630,13 +640,14 @@ describe("MatrixClient event timelines", function() { it("should work when /send returns after /sync", function(done) { var room = client.getRoom(roomId); + var timelineSet = room.getTimelineSets()[0]; // initiate the send, and set up checks to be done when it completes // - but note that it won't complete until after the /sync does, below. client.sendTextMessage(roomId, "a body", TXN_ID).then(function(res) { console.log("sendTextMessage completed"); expect(res.event_id).toEqual(event.event_id); - return client.getEventTimeline(room, event.event_id); + return client.getEventTimeline(timelineSet, event.event_id); }).then(function(tl) { console.log("getEventTimeline completed (2)"); expect(tl.getEvents().length).toEqual(2); @@ -644,7 +655,7 @@ describe("MatrixClient event timelines", function() { }).catch(utils.failTest).done(done); httpBackend.flush("/sync", 1).then(function() { - return client.getEventTimeline(room, event.event_id); + return client.getEventTimeline(timelineSet, event.event_id); }).then(function(tl) { console.log("getEventTimeline completed (1)"); expect(tl.getEvents().length).toEqual(2); diff --git a/spec/unit/timeline-window.spec.js b/spec/unit/timeline-window.spec.js index b6f91d111..9c706d75f 100644 --- a/spec/unit/timeline-window.spec.js +++ b/spec/unit/timeline-window.spec.js @@ -133,19 +133,19 @@ describe("TimelineIndex", function() { describe("TimelineWindow", function() { /** - * create a dummy room and client, and a TimelineWindow + * create a dummy eventTimelineSet and client, and a TimelineWindow * attached to them. */ - var room, client; + var timelineSet, client; function createWindow(timeline, opts) { - room = {}; + timelineSet = {}; client = {}; - client.getEventTimeline = function(room0, eventId0) { - expect(room0).toBe(room); + client.getEventTimeline = function(timelineSet0, eventId0) { + expect(timelineSet0).toBe(timelineSet); return q(timeline); }; - return new TimelineWindow(client, room, opts); + return new TimelineWindow(client, timelineSet, opts); } beforeEach(function() { @@ -169,15 +169,15 @@ describe("TimelineWindow", function() { var timeline = createTimeline(); var eventId = timeline.getEvents()[1].getId(); - var room = {}; + var timelineSet = {}; var client = {}; - client.getEventTimeline = function(room0, eventId0) { - expect(room0).toBe(room); + client.getEventTimeline = function(timelineSet0, eventId0) { + expect(timelineSet0).toBe(timelineSet); expect(eventId0).toEqual(eventId); return q(timeline); }; - var timelineWindow = new TimelineWindow(client, room); + var timelineWindow = new TimelineWindow(client, timelineSet); timelineWindow.load(eventId, 3).then(function() { var expectedEvents = timeline.getEvents(); expect(timelineWindow.getEvents()).toEqual(expectedEvents); @@ -192,12 +192,12 @@ describe("TimelineWindow", function() { var eventId = timeline.getEvents()[1].getId(); - var room = {}; + var timelineSet = {}; var client = {}; - var timelineWindow = new TimelineWindow(client, room); + var timelineWindow = new TimelineWindow(client, timelineSet); - client.getEventTimeline = function(room0, eventId0) { + client.getEventTimeline = function(timelineSet0, eventId0) { expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS)) .toBe(false); expect(timelineWindow.canPaginate(EventTimeline.FORWARDS))