Fix notifications for encrypted events (#1336)

Remember events that we may need to notify for once decrypted and
evaluate them in an Event.decrypted listener.
This commit is contained in:
David Baker 2017-08-24 14:27:38 +01:00 committed by Richard van der Hoff
parent 814e08d843
commit 939889705e

View file

@ -33,9 +33,16 @@ import Modal from './Modal';
* }
*/
const MAX_PENDING_ENCRYPTED = 20;
const Notifier = {
notifsByRoom: {},
// A list of event IDs that we've received but need to wait until
// they're decrypted until we decide whether to notify for them
// or not
pendingEncryptedEventIds: [],
notificationMessageForEvent: function(ev) {
return TextForEvent.textForEvent(ev);
},
@ -98,8 +105,10 @@ const Notifier = {
this.boundOnRoomTimeline = this.onRoomTimeline.bind(this);
this.boundOnSyncStateChange = this.onSyncStateChange.bind(this);
this.boundOnRoomReceipt = this.onRoomReceipt.bind(this);
this.boundOnEventDecrypted = this.onEventDecrypted.bind(this);
MatrixClientPeg.get().on('Room.timeline', this.boundOnRoomTimeline);
MatrixClientPeg.get().on('Room.receipt', this.boundOnRoomReceipt);
MatrixClientPeg.get().on('Event.decrypted', this.boundOnEventDecrypted);
MatrixClientPeg.get().on("sync", this.boundOnSyncStateChange);
this.toolbarHidden = false;
this.isSyncing = false;
@ -109,6 +118,7 @@ const Notifier = {
if (MatrixClientPeg.get() && this.boundOnRoomTimeline) {
MatrixClientPeg.get().removeListener('Room.timeline', this.boundOnRoomTimeline);
MatrixClientPeg.get().removeListener('Room.receipt', this.boundOnRoomReceipt);
MatrixClientPeg.get().removeListener('Event.decrypted', this.boundOnEventDecrypted);
MatrixClientPeg.get().removeListener('sync', this.boundOnSyncStateChange);
}
this.isSyncing = false;
@ -244,16 +254,26 @@ const Notifier = {
if (ev.sender && ev.sender.userId === MatrixClientPeg.get().credentials.userId) return;
if (data.timeline.getTimelineSet() !== room.getUnfilteredTimelineSet()) return;
const actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
if (actions && actions.notify) {
if (this.isEnabled()) {
this._displayPopupNotification(ev, room);
}
if (actions.tweaks.sound && this.isAudioEnabled()) {
PlatformPeg.get().loudNotification(ev, room);
this._playAudioNotification(ev, room);
// If it's an encrypted event and the type is still 'm.room.encrypted',
// it hasn't yet been decrypted, so wait until it is.
if (event.isBeingDecrypted() || event.isDecryptionFailure()) {
this.pendingEncryptedEventIds.push(ev.getId());
// don't let the list fill up indefinitely
while (this.pendingEncryptedEventIds.length > MAX_PENDING_ENCRYPTED) {
this.pendingEncryptedEventIds.shift();
}
return;
}
this._evaluateEvent(ev);
},
onEventDecrypted: function(ev) {
const idx = this.pendingEncryptedEventIds.indexOf(ev.getId());
if (idx === -1) return;
this.pendingEncryptedEventIds.splice(idx, 1);
this._evaluateEvent(ev);
},
onRoomReceipt: function(ev, room) {
@ -273,6 +293,20 @@ const Notifier = {
delete this.notifsByRoom[room.roomId];
}
},
_evaluateEvent: function(ev) {
const room = MatrixClientPeg.get().getRoom(ev.getRoomId());
const actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
if (actions && actions.notify) {
if (this.isEnabled()) {
this._displayPopupNotification(ev, room);
}
if (actions.tweaks.sound && this.isAudioEnabled()) {
PlatformPeg.get().loudNotification(ev, room);
this._playAudioNotification(ev, room);
}
}
}
};
if (!global.mxNotifier) {