Skip to content

Commit

Permalink
Merge pull request #851 from matrix-org/travis/e2e-notifs
Browse files Browse the repository at this point in the history
Calculate encrypted notification counts
  • Loading branch information
ara4n committed Mar 6, 2019
2 parents 8beb836 + 6198943 commit 77270fa
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 1 deletion.
26 changes: 26 additions & 0 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,32 @@ function MatrixClient(opts) {
this._serverSupportsLazyLoading = null;

this._cachedCapabilities = null; // { capabilities: {}, lastUpdated: timestamp }

// The SDK doesn't really provide a clean way for events to recalculate the push
// actions for themselves, so we have to kinda help them out when they are encrypted.
// We do this so that push rules are correctly executed on events in their decrypted
// state, such as highlights when the user's name is mentioned.
this.on("Event.decrypted", (event) => {
const oldActions = event.getPushActions();
const actions = this._pushProcessor.actionsForEvent(event);
event.setPushActions(actions); // Might as well while we're here

// Ensure the unread counts are kept up to date if the event is encrypted
const oldHighlight = oldActions && oldActions.tweaks
? !!oldActions.tweaks.highlight : false;
const newHighlight = actions && actions.tweaks
? !!actions.tweaks.highlight : false;
if (oldHighlight !== newHighlight) {
const room = this.getRoom(event.getRoomId());
// TODO: Handle mentions received while the client is offline
// See also https://github.com/vector-im/riot-web/issues/9069
if (room && !room.hasUserReadEvent(this.getUserId(), event.getId())) {
const current = room.getUnreadNotificationCount("highlight");
const newCount = newHighlight ? current + 1 : current - 1;
room.setUnreadNotificationCount("highlight", newCount);
}
}
});
}
utils.inherits(MatrixClient, EventEmitter);
utils.extend(MatrixClient.prototype, MatrixBaseApis.prototype);
Expand Down
19 changes: 19 additions & 0 deletions src/models/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,14 @@ utils.extend(module.exports.MatrixEvent.prototype, {
this._retryDecryption = false;
this._setClearData(res);

// Before we emit the event, clear the push actions so that they can be recalculated
// by relevant code. We do this because the clear event has now changed, making it
// so that existing rules can be re-run over the applicable properties. Stuff like
// highlighting when the user's name is mentioned rely on this happening. We also want
// to set the push actions before emitting so that any notification listeners don't
// pick up the wrong contents.
this.setPushActions(null);

this.emit("Event.decrypted", this, err);

return;
Expand Down Expand Up @@ -537,6 +545,17 @@ utils.extend(module.exports.MatrixEvent.prototype, {
decryptionResult.forwardingCurve25519KeyChain || [];
},

/**
* Gets the cleartext content for this event. If the event is not encrypted,
* or encryption has not been completed, this will return null.
*
* @returns {Object} The cleartext (decrypted) content for the event
*/
getClearContent: function() {
const ev = this._clearEvent;
return ev && ev.content ? ev.content : null;
},

/**
* Check if the event is encrypted.
* @return {boolean} True if this event is encrypted.
Expand Down
34 changes: 34 additions & 0 deletions src/models/room.js
Original file line number Diff line number Diff line change
Expand Up @@ -1424,6 +1424,40 @@ Room.prototype.getEventReadUpTo = function(userId, ignoreSynthesized) {
return receipts["m.read"][userId].eventId;
};

/**
* Determines if the given user has read a particular event ID with the known
* history of the room. This is not a definitive check as it relies only on
* what is available to the room at the time of execution.
* @param {String} userId The user ID to check the read state of.
* @param {String} eventId The event ID to check if the user read.
* @returns {Boolean} True if the user has read the event, false otherwise.
*/
Room.prototype.hasUserReadEvent = function(userId, eventId) {
const readUpToId = this.getEventReadUpTo(userId, false);
if (readUpToId === eventId) return true;

if (this.timeline.length
&& this.timeline[this.timeline.length - 1].getSender()
&& this.timeline[this.timeline.length - 1].getSender() === userId) {
// It doesn't matter where the event is in the timeline, the user has read
// it because they've sent the latest event.
return true;
}

for (let i = this.timeline.length - 1; i >= 0; --i) {
const ev = this.timeline[i];

// If we encounter the target event first, the user hasn't read it
// however if we encounter the readUpToId first then the user has read
// it. These rules apply because we're iterating bottom-up.
if (ev.getId() === eventId) return false;
if (ev.getId() === readUpToId) return true;
}

// We don't know if the user has read it, so assume not.
return false;
};

/**
* Get a list of receipts for the given event.
* @param {MatrixEvent} event the event to get receipts for
Expand Down
5 changes: 4 additions & 1 deletion src/pushprocessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,10 @@ function PushProcessor(client) {
};

const eventFulfillsDisplayNameCondition = function(cond, ev) {
const content = ev.getContent();
let content = ev.getContent();
if (ev.isEncrypted() && ev.getClearContent()) {
content = ev.getClearContent();
}
if (!content || !content.body || typeof content.body != 'string') {
return false;
}
Expand Down

0 comments on commit 77270fa

Please sign in to comment.