You've already forked matrix-js-sdk
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:
197
lib/client.js
197
lib/client.js
@@ -1683,7 +1683,7 @@ MatrixClient.prototype.getEventTimeline = function(timelineSet, eventId) {
|
|||||||
* @param {module:models/event-timeline~EventTimeline} eventTimeline timeline
|
* @param {module:models/event-timeline~EventTimeline} eventTimeline timeline
|
||||||
* object to be updated
|
* object to be updated
|
||||||
* @param {Object} [opts]
|
* @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
|
* false to go forwards
|
||||||
* @param {number} [opts.limit = 30] number of events to request
|
* @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.
|
* events and we reached either end of the timeline; else true.
|
||||||
*/
|
*/
|
||||||
MatrixClient.prototype.paginateEventTimeline = function(eventTimeline, opts) {
|
MatrixClient.prototype.paginateEventTimeline = function(eventTimeline, opts) {
|
||||||
|
var isNotifTimeline = (eventTimeline.getTimelineSet() === this._notifTimelineSet);
|
||||||
|
|
||||||
// TODO: we should implement a backoff (as per scrollback()) to deal more
|
// TODO: we should implement a backoff (as per scrollback()) to deal more
|
||||||
// nicely with HTTP errors.
|
// nicely with HTTP errors.
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
var backwards = opts.backwards || false;
|
var backwards = opts.backwards || false;
|
||||||
|
|
||||||
|
if (isNotifTimeline) {
|
||||||
|
if (!backwards) {
|
||||||
|
throw new Error("paginateNotifTimeline can only paginate backwards");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var room = this.getRoom(eventTimeline.getRoomId());
|
var room = this.getRoom(eventTimeline.getRoomId());
|
||||||
if (!room) {
|
if (!room) {
|
||||||
throw new Error("Unknown room " + eventTimeline.getRoomId());
|
throw new Error("Unknown room " + eventTimeline.getRoomId());
|
||||||
@@ -1716,120 +1724,7 @@ MatrixClient.prototype.paginateEventTimeline = function(eventTimeline, opts) {
|
|||||||
return pendingRequest;
|
return pendingRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
var path = utils.encodeUri(
|
if (isNotifTimeline) {
|
||||||
"/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;
|
|
||||||
}
|
|
||||||
|
|
||||||
var path = "/notifications";
|
var path = "/notifications";
|
||||||
var params = {
|
var params = {
|
||||||
from: token,
|
from: token,
|
||||||
@@ -1869,10 +1764,82 @@ MatrixClient.prototype.paginateNotifTimeline = function(eventTimeline, opts) {
|
|||||||
eventTimeline._paginationRequests[dir] = null;
|
eventTimeline._paginationRequests[dir] = null;
|
||||||
});
|
});
|
||||||
eventTimeline._paginationRequests[dir] = promise;
|
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;
|
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
|
* Peek into a room and receive updates about the room. This only works if the
|
||||||
* history visibility for the room is world_readable.
|
* history visibility for the room is world_readable.
|
||||||
|
|||||||
@@ -255,11 +255,7 @@ TimelineWindow.prototype.paginate = function(direction, size, makeRequest,
|
|||||||
debuglog("TimelineWindow: starting request");
|
debuglog("TimelineWindow: starting request");
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var paginateTimeline = tl.timeline.getRoomId() ?
|
var prom = this._client.paginateEventTimeline(tl.timeline, {
|
||||||
this._client.paginateEventTimeline :
|
|
||||||
this._client.paginateNotifTimeline;
|
|
||||||
|
|
||||||
var prom = paginateTimeline.call(this._client, tl.timeline, {
|
|
||||||
backwards: direction == EventTimeline.BACKWARDS,
|
backwards: direction == EventTimeline.BACKWARDS,
|
||||||
limit: size
|
limit: size
|
||||||
}).finally(function() {
|
}).finally(function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user