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

maintain the global notification timeline set.

* track notifTimelineSet on MatrixClient
* stop Rooms from tracking notifTimelineSet as they don't need to
* Implement client.paginateNotifTimelineSet
* make Events store their pushActions properly
* insert live notifs directly into the notifTimelineSet in /sync, ordering by origin_server_ts.
This commit is contained in:
Matthew Hodgson
2016-09-08 02:57:49 +01:00
parent fc495a5f1e
commit e4ec2aa55f
6 changed files with 164 additions and 29 deletions

View File

@@ -146,6 +146,7 @@ function MatrixClient(opts) {
this._ongoingScrollbacks = {};
this.timelineSupport = Boolean(opts.timelineSupport);
this.urlPreviewCache = {};
this._notifTimelineSet = null;
this._crypto = null;
if (CRYPTO_ENABLED && opts.sessionStore !== null &&
@@ -249,6 +250,24 @@ MatrixClient.prototype.retryImmediately = function() {
return this._syncApi.retryImmediately();
};
/**
* Return the global notification EventTimelineSet, if any
*
* @return {EventTimelineSet} the globl notification EventTimelineSet
*/
MatrixClient.prototype.getNotifTimelineSet = function() {
return this._notifTimelineSet;
};
/**
* Set the global notification EventTimelineSet
*
* @param {EventTimelineSet} notifTimelineSet
*/
MatrixClient.prototype.setNotifTimelineSet = function(notifTimelineSet) {
this._notifTimelineSet = notifTimelineSet;
};
// Crypto bits
// ===========
@@ -1365,16 +1384,16 @@ function _membershipChange(client, roomId, userId, membership, reason, callback)
/**
* Obtain a dict of actions which should be performed for this event according
* to the push rules for this user.
* to the push rules for this user. Caches the dict on the event.
* @param {MatrixEvent} event The event to get push actions for.
* @return {module:pushprocessor~PushAction} A dict of actions to perform.
*/
MatrixClient.prototype.getPushActionsForEvent = function(event) {
if (event._pushActions === undefined) {
if (!event.getPushActions()) {
var pushProcessor = new PushProcessor(this);
event._pushActions = pushProcessor.actionsForEvent(event);
event.setPushActions(pushProcessor.actionsForEvent(event));
}
return event._pushActions;
return event.getPushActions();
};
// Profile operations
@@ -1774,6 +1793,88 @@ MatrixClient.prototype.paginateEventTimeline = function(eventTimeline, opts) {
return promise;
};
/**
* 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 params = {
from: token,
limit: ('limit' in opts) ? opts.limit : 30,
only: 'highlight',
};
var self = this;
var promise =
this._http.authedRequestWithPrefix(undefined, "GET", path, params,
undefined, httpApi.PREFIX_UNSTABLE
).then(function(res) {
var token = res.next_token;
var matrixEvents = [];
for (var i = 0; i < res.notifications.length; i++) {
var notification = res.notifications[i];
var event = self.getEventMapper()(notification.event);
event.setPushActions(notification.actions);
matrixEvents[i] = event;
}
eventTimeline.getEventTimelineSet()
.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.next_token) {
eventTimeline.setPaginationToken(null, dir);
}
return res.next_token ? true : false;
}).finally(function() {
eventTimeline._paginationRequests[dir] = null;
});
eventTimeline._paginationRequests[dir] = promise;
return promise;
};
/**
* Peek into a room and receive updates about the room. This only works if the
* history visibility for the room is world_readable.