1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-29 16:43:09 +03:00

refactr paginateNotifTimeline out of existence

This commit is contained in:
Matthew Hodgson
2016-09-09 16:49:39 +01:00
parent 5a5257a598
commit bd32ed5598
2 changed files with 85 additions and 122 deletions

View File

@@ -1683,7 +1683,7 @@ MatrixClient.prototype.getEventTimeline = function(timelineSet, eventId) {
* @param {module:models/event-timeline~EventTimeline} eventTimeline timeline
* object to be updated
* @param {Object} [opts]
* @param {boolean} [opts.backwards = false] true to fill backwards,
* @param {bool} [opts.backwards = false] true to fill backwards,
* false to go forwards
* @param {number} [opts.limit = 30] number of events to request
*
@@ -1691,11 +1691,19 @@ MatrixClient.prototype.getEventTimeline = function(timelineSet, eventId) {
* events and we reached either end of the timeline; else true.
*/
MatrixClient.prototype.paginateEventTimeline = function(eventTimeline, opts) {
var isNotifTimeline = (eventTimeline.getTimelineSet() === this._notifTimelineSet);
// TODO: we should implement a backoff (as per scrollback()) to deal more
// nicely with HTTP errors.
opts = opts || {};
var backwards = opts.backwards || false;
if (isNotifTimeline) {
if (!backwards) {
throw new Error("paginateNotifTimeline can only paginate backwards");
}
}
var room = this.getRoom(eventTimeline.getRoomId());
if (!room) {
throw new Error("Unknown room " + eventTimeline.getRoomId());
@@ -1716,120 +1724,7 @@ MatrixClient.prototype.paginateEventTimeline = function(eventTimeline, opts) {
return pendingRequest;
}
var path = utils.encodeUri(
"/rooms/$roomId/messages", {$roomId: eventTimeline.getRoomId()}
);
var params = {
from: token,
limit: ('limit' in opts) ? opts.limit : 30,
dir: dir
};
var filter = eventTimeline.getFilter();
if (filter) {
// XXX: it's horrific that /messages' filter parameter doesn't match
// /sync's one - see https://matrix.org/jira/browse/SPEC-451
params.filter = JSON.stringify(filter.getRoomTimelineFilterComponent());
}
var self = this;
var promise =
this._http.authedRequest(undefined, "GET", path, params
).then(function(res) {
var token = res.end;
var matrixEvents = utils.map(res.chunk, self.getEventMapper());
room.addEventsToTimeline(matrixEvents, backwards, eventTimeline, token);
// if we've hit the end of the timeline, we need to stop trying to
// paginate. We need to keep the 'forwards' token though, to make sure
// we can recover from gappy syncs.
if (backwards && res.end == res.start) {
eventTimeline.setPaginationToken(null, dir);
}
return res.end != res.start;
}).finally(function() {
eventTimeline._paginationRequests[dir] = null;
});
eventTimeline._paginationRequests[dir] = promise;
return promise;
};
/**
* Reset the notifTimelineSet entirely, paginating in some historical notifs as
* a starting point for subsequent pagination.
*/
MatrixClient.prototype.resetNotifTimelineSet = function() {
if (!this._notifTimelineSet) {
return;
}
// FIXME: This thing is a total hack, and results in duplicate events being
// added to the timeline both from /sync and /notifications, and lots of
// slow and wasteful processing and pagination. The correct solution is to
// extend /messages or /search or something to filter on notifications.
// use the fictitious token 'end'. in practice we would ideally give it
// the oldest backwards pagination token from /sync, but /sync doesn't
// know about /notifications, so we have no choice but to start paginating
// from the current point in time. This may well overlap with historical
// notifs which are then inserted into the timeline by /sync responses.
this._notifTimelineSet.resetLiveTimeline('end', true);
// we could try to paginate a single event at this point in order to get
// a more valid pagination token, but it just ends up with an out of order
// timeline. given what a mess this is and given we're going to have duplicate
// events anyway, just leave it with the dummy token for now.
/*
this.paginateNotifTimeline(this._notifTimelineSet.getLiveTimeline(), {
backwards: true,
limit: 1
});
*/
};
/**
* Take an EventTimeline, and backfill results from the notifications API.
* In future, the notifications API should probably be replaced by /messages
* with a custom filter or something - so we don't feel too bad about this being
* cargoculted from paginateEventTimeLine.
*
* @param {module:models/event-timeline~EventTimeline} eventTimeline timeline
* object to be updated
* @param {Object} [opts]
* @param {boolean} [opts.backwards = false] true to fill backwards,
* false to go forwards. <b>Forwards is not implemented yet!</b>
* @param {number} [opts.limit = 30] number of events to request
*
* @return {module:client.Promise} Resolves to a boolean: false if there are no
* events and we reached either end of the timeline; else true.
*/
MatrixClient.prototype.paginateNotifTimeline = function(eventTimeline, opts) {
// TODO: we should implement a backoff (as per scrollback()) to deal more
// nicely with HTTP errors.
opts = opts || {};
var backwards = opts.backwards || false;
if (!backwards) {
throw new Error("paginateNotifTimeline can only paginate backwards");
}
if (eventTimeline.getRoomId()) {
throw new Error("paginateNotifTimeline should never be called on a " +
"timeline associated with a room");
}
var dir = backwards ? EventTimeline.BACKWARDS : EventTimeline.FORWARDS;
var token = eventTimeline.getPaginationToken(dir);
var pendingRequest = eventTimeline._paginationRequests[dir];
if (pendingRequest) {
// already a request in progress - return the existing promise
return pendingRequest;
}
if (isNotifTimeline) {
var path = "/notifications";
var params = {
from: token,
@@ -1869,10 +1764,82 @@ MatrixClient.prototype.paginateNotifTimeline = function(eventTimeline, opts) {
eventTimeline._paginationRequests[dir] = null;
});
eventTimeline._paginationRequests[dir] = promise;
}
else {
var path = utils.encodeUri(
"/rooms/$roomId/messages", {$roomId: eventTimeline.getRoomId()}
);
var params = {
from: token,
limit: ('limit' in opts) ? opts.limit : 30,
dir: dir
};
var filter = eventTimeline.getFilter();
if (filter) {
// XXX: it's horrific that /messages' filter parameter doesn't match
// /sync's one - see https://matrix.org/jira/browse/SPEC-451
params.filter = JSON.stringify(filter.getRoomTimelineFilterComponent());
}
var self = this;
var promise =
this._http.authedRequest(undefined, "GET", path, params
).then(function(res) {
var token = res.end;
var matrixEvents = utils.map(res.chunk, self.getEventMapper());
room.addEventsToTimeline(matrixEvents, backwards, eventTimeline, token);
// if we've hit the end of the timeline, we need to stop trying to
// paginate. We need to keep the 'forwards' token though, to make sure
// we can recover from gappy syncs.
if (backwards && res.end == res.start) {
eventTimeline.setPaginationToken(null, dir);
}
return res.end != res.start;
}).finally(function() {
eventTimeline._paginationRequests[dir] = null;
});
eventTimeline._paginationRequests[dir] = promise;
}
return promise;
};
/**
* Reset the notifTimelineSet entirely, paginating in some historical notifs as
* a starting point for subsequent pagination.
*/
MatrixClient.prototype.resetNotifTimelineSet = function() {
if (!this._notifTimelineSet) {
return;
}
// FIXME: This thing is a total hack, and results in duplicate events being
// added to the timeline both from /sync and /notifications, and lots of
// slow and wasteful processing and pagination. The correct solution is to
// extend /messages or /search or something to filter on notifications.
// use the fictitious token 'end'. in practice we would ideally give it
// the oldest backwards pagination token from /sync, but /sync doesn't
// know about /notifications, so we have no choice but to start paginating
// from the current point in time. This may well overlap with historical
// notifs which are then inserted into the timeline by /sync responses.
this._notifTimelineSet.resetLiveTimeline('end', true);
// we could try to paginate a single event at this point in order to get
// a more valid pagination token, but it just ends up with an out of order
// timeline. given what a mess this is and given we're going to have duplicate
// events anyway, just leave it with the dummy token for now.
/*
this.paginateNotifTimeline(this._notifTimelineSet.getLiveTimeline(), {
backwards: true,
limit: 1
});
*/
};
/**
* Peek into a room and receive updates about the room. This only works if the
* history visibility for the room is world_readable.

View File

@@ -255,11 +255,7 @@ TimelineWindow.prototype.paginate = function(direction, size, makeRequest,
debuglog("TimelineWindow: starting request");
var self = this;
var paginateTimeline = tl.timeline.getRoomId() ?
this._client.paginateEventTimeline :
this._client.paginateNotifTimeline;
var prom = paginateTimeline.call(this._client, tl.timeline, {
var prom = this._client.paginateEventTimeline(tl.timeline, {
backwards: direction == EventTimeline.BACKWARDS,
limit: size
}).finally(function() {