1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-06 12:02:40 +03:00

change TimelineWindow to take a timelineSet rather than a Room

This commit is contained in:
Matthew Hodgson
2016-09-04 13:57:56 +01:00
parent 4ff2ad9fac
commit 2daa1b6007
5 changed files with 73 additions and 46 deletions

View File

@@ -1618,18 +1618,18 @@ MatrixClient.prototype.paginateEventContext = function(eventContext, opts) {
/** /**
* Get an EventTimeline for the given event * Get an EventTimeline for the given event
* *
* <p>If the room object already has the given event in its store, the * <p>If the EventTimelineSet object already has the given event in its store, the
* corresponding timeline will be returned. Otherwise, a /context request is * corresponding timeline will be returned. Otherwise, a /context request is
* made, and used to construct an EventTimeline. * 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 * @param {string} eventId The ID of the event to look for
* *
* @return {module:client.Promise} Resolves: * @return {module:client.Promise} Resolves:
* {@link module:models/event-timeline~EventTimeline} including the given * {@link module:models/event-timeline~EventTimeline} including the given
* event * event
*/ */
MatrixClient.prototype.getEventTimeline = function(room, eventId) { MatrixClient.prototype.getEventTimeline = function(timelineSet, eventId) {
// don't allow any timeline support unless it's been enabled. // don't allow any timeline support unless it's been enabled.
if (!this.timelineSupport) { if (!this.timelineSupport) {
throw new Error("timeline support is disabled. Set the 'timelineSupport'" + throw new Error("timeline support is disabled. Set the 'timelineSupport'" +
@@ -1637,13 +1637,13 @@ MatrixClient.prototype.getEventTimeline = function(room, eventId) {
" it."); " it.");
} }
if (room.getTimelineForEvent(eventId)) { if (timelineSet.getTimelineForEvent(eventId)) {
return q(room.getTimelineForEvent(eventId)); return q(timelineSet.getTimelineForEvent(eventId));
} }
var path = utils.encodeUri( var path = utils.encodeUri(
"/rooms/$roomId/context/$eventId", { "/rooms/$roomId/context/$eventId", {
$roomId: room.roomId, $roomId: timelineSet.room.roomId,
$eventId: eventId, $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 // by the time the request completes, the event might have ended up in
// the timeline. // the timeline.
if (room.getTimelineForEvent(eventId)) { if (timelineSet.getTimelineForEvent(eventId)) {
return room.getTimelineForEvent(eventId); return timelineSet.getTimelineForEvent(eventId);
} }
// we start with the last event, since that's the point at which we // 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); .concat(res.events_before);
var matrixEvents = utils.map(events, self.getEventMapper()); var matrixEvents = utils.map(events, self.getEventMapper());
var timeline = room.getTimelineForEvent(matrixEvents[0].getId()); var timeline = timelineSet.getTimelineForEvent(matrixEvents[0].getId());
if (!timeline) { if (!timeline) {
timeline = room.addTimeline(); timeline = timelineSet.addTimeline();
timeline.initialiseState(utils.map(res.state, timeline.initialiseState(utils.map(res.state,
self.getEventMapper())); self.getEventMapper()));
timeline.getState(EventTimeline.FORWARDS).paginationToken = res.end; 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 // there is no guarantee that the event ended up in "timeline" (we
// might have switched to a neighbouring timeline) - so check the // might have switched to a neighbouring timeline) - so check the
// room's index again. On the other hand, there's no guarantee 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 // event ended up anywhere, if it was later redacted, so we just
// return the timeline we first thought of. // return the timeline we first thought of.
return room.getTimelineForEvent(eventId) || timeline; var tl = timelineSet.getTimelineForEvent(eventId) || timeline;
return tl;
}); });
return promise; return promise;
}; };

View File

@@ -244,6 +244,20 @@ Room.prototype._fixUpLegacyTimelineFields = function() {
this.currentState = this._timelineSets[0].getLiveTimeline().getState(EventTimeline.FORWARDS); 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 * Get the timeline which contains the given event from the unfiltered set, if any
* *

View File

@@ -19,6 +19,7 @@ limitations under the License.
var q = require("q"); var q = require("q");
var EventTimeline = require("./models/event-timeline"); var EventTimeline = require("./models/event-timeline");
var EventTimelineSet = require("./models/event-timeline-set");
/** /**
* @private * @private
@@ -56,7 +57,7 @@ var DEFAULT_PAGINATE_LOOP_LIMIT = 5;
* @param {MatrixClient} client MatrixClient to be used for context/pagination * @param {MatrixClient} client MatrixClient to be used for context/pagination
* requests. * requests.
* *
* @param {Room} room The room to track * @param {EventTimelineSet} timelineSet The timelineSet to track
* *
* @param {Object} [opts] Configuration options for this window * @param {Object} [opts] Configuration options for this window
* *
@@ -66,10 +67,10 @@ var DEFAULT_PAGINATE_LOOP_LIMIT = 5;
* *
* @constructor * @constructor
*/ */
function TimelineWindow(client, room, opts) { function TimelineWindow(client, timelineSet, opts) {
opts = opts || {}; opts = opts || {};
this._client = client; this._client = client;
this._room = room; this._timelineSet = timelineSet;
// these will be TimelineIndex objects; they delineate the 'start' and // these will be TimelineIndex objects; they delineate the 'start' and
// 'end' of the window. // '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 // TODO: ideally we'd spot getEventTimeline returning a resolved promise and
// skip straight to the find-event loop. // skip straight to the find-event loop.
if (initialEventId) { if (initialEventId) {
return this._client.getEventTimeline(this._room, initialEventId) return this._client.getEventTimeline(this._timelineSet, initialEventId)
.then(function(tl) { .then(function(tl) {
// make sure that our window includes the event // make sure that our window includes the event
for (var i = 0; i < tl.getEvents().length; i++) { for (var i = 0; i < tl.getEvents().length; i++) {
@@ -126,7 +127,7 @@ TimelineWindow.prototype.load = function(initialEventId, initialWindowSize) {
}); });
} else { } else {
// start with the most recent events // start with the most recent events
var tl = this._room.getLiveTimeline(); var tl = this._timelineSet.getLiveTimeline();
initFields(tl, tl.getEvents().length); initFields(tl, tl.getEvents().length);
return q(); return q();
} }

View File

@@ -121,7 +121,8 @@ describe("getEventTimeline support", function() {
startClient(httpBackend, client startClient(httpBackend, client
).then(function() { ).then(function() {
var room = client.getRoom(roomId); var room = client.getRoom(roomId);
expect(function() { client.getEventTimeline(room, "event"); }) var timelineSet = room.getTimelineSets()[0];
expect(function() { client.getEventTimeline(timelineSet, "event"); })
.toThrow(); .toThrow();
}).catch(utils.failTest).done(done); }).catch(utils.failTest).done(done);
}); });
@@ -137,7 +138,8 @@ describe("getEventTimeline support", function() {
startClient(httpBackend, client startClient(httpBackend, client
).then(function() { ).then(function() {
var room = client.getRoom(roomId); var room = client.getRoom(roomId);
expect(function() { client.getEventTimeline(room, "event"); }) var timelineSet = room.getTimelineSets()[0];
expect(function() { client.getEventTimeline(timelineSet, "event"); })
.not.toThrow(); .not.toThrow();
}).catch(utils.failTest).done(done); }).catch(utils.failTest).done(done);
@@ -242,6 +244,7 @@ describe("MatrixClient event timelines", function() {
describe("getEventTimeline", function() { describe("getEventTimeline", function() {
it("should create a new timeline for new events", function(done) { it("should create a new timeline for new events", function(done) {
var room = client.getRoom(roomId); var room = client.getRoom(roomId);
var timelineSet = room.getTimelineSets()[0];
httpBackend.when("GET", "/rooms/!foo%3Abar/context/event1%3Abar") httpBackend.when("GET", "/rooms/!foo%3Abar/context/event1%3Abar")
.respond(200, function() { .respond(200, function() {
return { 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); expect(tl.getEvents().length).toEqual(4);
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
expect(tl.getEvents()[i].event).toEqual(EVENTS[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) { it("should return existing timeline for known events", function(done) {
var room = client.getRoom(roomId); var room = client.getRoom(roomId);
var timelineSet = room.getTimelineSets()[0];
httpBackend.when("GET", "/sync").respond(200, { httpBackend.when("GET", "/sync").respond(200, {
next_batch: "s_5_4", next_batch: "s_5_4",
rooms: { rooms: {
@@ -291,7 +295,7 @@ describe("MatrixClient event timelines", function() {
}); });
httpBackend.flush("/sync").then(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) { }).then(function(tl) {
expect(tl.getEvents().length).toEqual(2); expect(tl.getEvents().length).toEqual(2);
expect(tl.getEvents()[1].event).toEqual(EVENTS[0]); 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) { it("should update timelines where they overlap a previous /sync", function(done) {
var room = client.getRoom(roomId); var room = client.getRoom(roomId);
var timelineSet = room.getTimelineSets()[0];
httpBackend.when("GET", "/sync").respond(200, { httpBackend.when("GET", "/sync").respond(200, {
next_batch: "s_5_4", next_batch: "s_5_4",
rooms: { rooms: {
@@ -335,7 +340,7 @@ describe("MatrixClient event timelines", function() {
}); });
client.on("sync", function() { client.on("sync", function() {
client.getEventTimeline(room, EVENTS[2].event_id client.getEventTimeline(timelineSet, EVENTS[2].event_id
).then(function(tl) { ).then(function(tl) {
expect(tl.getEvents().length).toEqual(4); expect(tl.getEvents().length).toEqual(4);
expect(tl.getEvents()[0].event).toEqual(EVENTS[1]); 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", it("should join timelines where they overlap a previous /context",
function(done) { function(done) {
var room = client.getRoom(roomId); var room = client.getRoom(roomId);
var timelineSet = room.getTimelineSets()[0];
// we fetch event 0, then 2, then 3, and finally 1. 1 is returned // we fetch event 0, then 2, then 3, and finally 1. 1 is returned
// with context which joins them all up. // with context which joins them all up.
@@ -410,19 +416,19 @@ describe("MatrixClient event timelines", function() {
}); });
var tl0, tl2, tl3; var tl0, tl2, tl3;
client.getEventTimeline(room, EVENTS[0].event_id client.getEventTimeline(timelineSet, EVENTS[0].event_id
).then(function(tl) { ).then(function(tl) {
expect(tl.getEvents().length).toEqual(1); expect(tl.getEvents().length).toEqual(1);
tl0 = tl; tl0 = tl;
return client.getEventTimeline(room, EVENTS[2].event_id); return client.getEventTimeline(timelineSet, EVENTS[2].event_id);
}).then(function(tl) { }).then(function(tl) {
expect(tl.getEvents().length).toEqual(1); expect(tl.getEvents().length).toEqual(1);
tl2 = tl; tl2 = tl;
return client.getEventTimeline(room, EVENTS[3].event_id); return client.getEventTimeline(timelineSet, EVENTS[3].event_id);
}).then(function(tl) { }).then(function(tl) {
expect(tl.getEvents().length).toEqual(1); expect(tl.getEvents().length).toEqual(1);
tl3 = tl; tl3 = tl;
return client.getEventTimeline(room, EVENTS[1].event_id); return client.getEventTimeline(timelineSet, EVENTS[1].event_id);
}).then(function(tl) { }).then(function(tl) {
// we expect it to get merged in with event 2 // we expect it to get merged in with event 2
expect(tl.getEvents().length).toEqual(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) { it("should fail gracefully if there is no event field", function(done) {
var room = client.getRoom(roomId); var room = client.getRoom(roomId);
var timelineSet = room.getTimelineSets()[0];
// we fetch event 0, then 2, then 3, and finally 1. 1 is returned // we fetch event 0, then 2, then 3, and finally 1. 1 is returned
// with context which joins them all up. // with context which joins them all up.
httpBackend.when("GET", "/rooms/!foo%3Abar/context/event1") 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) { ).then(function(tl) {
// could do with a fail() // could do with a fail()
expect(true).toBeFalsy(); expect(true).toBeFalsy();
@@ -475,6 +482,7 @@ describe("MatrixClient event timelines", function() {
describe("paginateEventTimeline", function() { describe("paginateEventTimeline", function() {
it("should allow you to paginate backwards", function(done) { it("should allow you to paginate backwards", function(done) {
var room = client.getRoom(roomId); var room = client.getRoom(roomId);
var timelineSet = room.getTimelineSets()[0];
httpBackend.when("GET", "/rooms/!foo%3Abar/context/" + httpBackend.when("GET", "/rooms/!foo%3Abar/context/" +
encodeURIComponent(EVENTS[0].event_id)) encodeURIComponent(EVENTS[0].event_id))
@@ -503,7 +511,7 @@ describe("MatrixClient event timelines", function() {
}); });
var tl; var tl;
client.getEventTimeline(room, EVENTS[0].event_id client.getEventTimeline(timelineSet, EVENTS[0].event_id
).then(function(tl0) { ).then(function(tl0) {
tl = tl0; tl = tl0;
return client.paginateEventTimeline(tl, {backwards: true}); return client.paginateEventTimeline(tl, {backwards: true});
@@ -525,6 +533,7 @@ describe("MatrixClient event timelines", function() {
it("should allow you to paginate forwards", function(done) { it("should allow you to paginate forwards", function(done) {
var room = client.getRoom(roomId); var room = client.getRoom(roomId);
var timelineSet = room.getTimelineSets()[0];
httpBackend.when("GET", "/rooms/!foo%3Abar/context/" + httpBackend.when("GET", "/rooms/!foo%3Abar/context/" +
encodeURIComponent(EVENTS[0].event_id)) encodeURIComponent(EVENTS[0].event_id))
@@ -553,7 +562,7 @@ describe("MatrixClient event timelines", function() {
}); });
var tl; var tl;
client.getEventTimeline(room, EVENTS[0].event_id client.getEventTimeline(timelineSet, EVENTS[0].event_id
).then(function(tl0) { ).then(function(tl0) {
tl = tl0; tl = tl0;
return client.paginateEventTimeline( return client.paginateEventTimeline(
@@ -607,10 +616,11 @@ describe("MatrixClient event timelines", function() {
it("should work when /send returns before /sync", function(done) { it("should work when /send returns before /sync", function(done) {
var room = client.getRoom(roomId); var room = client.getRoom(roomId);
var timelineSet = room.getTimelineSets()[0];
client.sendTextMessage(roomId, "a body", TXN_ID).then(function(res) { client.sendTextMessage(roomId, "a body", TXN_ID).then(function(res) {
expect(res.event_id).toEqual(event.event_id); 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) { }).then(function(tl) {
// 2 because the initial sync contained an event // 2 because the initial sync contained an event
expect(tl.getEvents().length).toEqual(2); expect(tl.getEvents().length).toEqual(2);
@@ -619,7 +629,7 @@ describe("MatrixClient event timelines", function() {
// now let the sync complete, and check it again // now let the sync complete, and check it again
return httpBackend.flush("/sync", 1); return httpBackend.flush("/sync", 1);
}).then(function() { }).then(function() {
return client.getEventTimeline(room, event.event_id); return client.getEventTimeline(timelineSet, event.event_id);
}).then(function(tl) { }).then(function(tl) {
expect(tl.getEvents().length).toEqual(2); expect(tl.getEvents().length).toEqual(2);
expect(tl.getEvents()[1].event).toEqual(event); 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) { it("should work when /send returns after /sync", function(done) {
var room = client.getRoom(roomId); var room = client.getRoom(roomId);
var timelineSet = room.getTimelineSets()[0];
// initiate the send, and set up checks to be done when it completes // 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. // - but note that it won't complete until after the /sync does, below.
client.sendTextMessage(roomId, "a body", TXN_ID).then(function(res) { client.sendTextMessage(roomId, "a body", TXN_ID).then(function(res) {
console.log("sendTextMessage completed"); console.log("sendTextMessage completed");
expect(res.event_id).toEqual(event.event_id); 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) { }).then(function(tl) {
console.log("getEventTimeline completed (2)"); console.log("getEventTimeline completed (2)");
expect(tl.getEvents().length).toEqual(2); expect(tl.getEvents().length).toEqual(2);
@@ -644,7 +655,7 @@ describe("MatrixClient event timelines", function() {
}).catch(utils.failTest).done(done); }).catch(utils.failTest).done(done);
httpBackend.flush("/sync", 1).then(function() { httpBackend.flush("/sync", 1).then(function() {
return client.getEventTimeline(room, event.event_id); return client.getEventTimeline(timelineSet, event.event_id);
}).then(function(tl) { }).then(function(tl) {
console.log("getEventTimeline completed (1)"); console.log("getEventTimeline completed (1)");
expect(tl.getEvents().length).toEqual(2); expect(tl.getEvents().length).toEqual(2);

View File

@@ -133,19 +133,19 @@ describe("TimelineIndex", function() {
describe("TimelineWindow", 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. * attached to them.
*/ */
var room, client; var timelineSet, client;
function createWindow(timeline, opts) { function createWindow(timeline, opts) {
room = {}; timelineSet = {};
client = {}; client = {};
client.getEventTimeline = function(room0, eventId0) { client.getEventTimeline = function(timelineSet0, eventId0) {
expect(room0).toBe(room); expect(timelineSet0).toBe(timelineSet);
return q(timeline); return q(timeline);
}; };
return new TimelineWindow(client, room, opts); return new TimelineWindow(client, timelineSet, opts);
} }
beforeEach(function() { beforeEach(function() {
@@ -169,15 +169,15 @@ describe("TimelineWindow", function() {
var timeline = createTimeline(); var timeline = createTimeline();
var eventId = timeline.getEvents()[1].getId(); var eventId = timeline.getEvents()[1].getId();
var room = {}; var timelineSet = {};
var client = {}; var client = {};
client.getEventTimeline = function(room0, eventId0) { client.getEventTimeline = function(timelineSet0, eventId0) {
expect(room0).toBe(room); expect(timelineSet0).toBe(timelineSet);
expect(eventId0).toEqual(eventId); expect(eventId0).toEqual(eventId);
return q(timeline); return q(timeline);
}; };
var timelineWindow = new TimelineWindow(client, room); var timelineWindow = new TimelineWindow(client, timelineSet);
timelineWindow.load(eventId, 3).then(function() { timelineWindow.load(eventId, 3).then(function() {
var expectedEvents = timeline.getEvents(); var expectedEvents = timeline.getEvents();
expect(timelineWindow.getEvents()).toEqual(expectedEvents); expect(timelineWindow.getEvents()).toEqual(expectedEvents);
@@ -192,12 +192,12 @@ describe("TimelineWindow", function() {
var eventId = timeline.getEvents()[1].getId(); var eventId = timeline.getEvents()[1].getId();
var room = {}; var timelineSet = {};
var client = {}; 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)) expect(timelineWindow.canPaginate(EventTimeline.BACKWARDS))
.toBe(false); .toBe(false);
expect(timelineWindow.canPaginate(EventTimeline.FORWARDS)) expect(timelineWindow.canPaginate(EventTimeline.FORWARDS))