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:
parent
814e08d843
commit
939889705e
1 changed files with 42 additions and 8 deletions
|
@ -33,9 +33,16 @@ import Modal from './Modal';
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const MAX_PENDING_ENCRYPTED = 20;
|
||||||
|
|
||||||
const Notifier = {
|
const Notifier = {
|
||||||
notifsByRoom: {},
|
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) {
|
notificationMessageForEvent: function(ev) {
|
||||||
return TextForEvent.textForEvent(ev);
|
return TextForEvent.textForEvent(ev);
|
||||||
},
|
},
|
||||||
|
@ -98,8 +105,10 @@ const Notifier = {
|
||||||
this.boundOnRoomTimeline = this.onRoomTimeline.bind(this);
|
this.boundOnRoomTimeline = this.onRoomTimeline.bind(this);
|
||||||
this.boundOnSyncStateChange = this.onSyncStateChange.bind(this);
|
this.boundOnSyncStateChange = this.onSyncStateChange.bind(this);
|
||||||
this.boundOnRoomReceipt = this.onRoomReceipt.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.timeline', this.boundOnRoomTimeline);
|
||||||
MatrixClientPeg.get().on('Room.receipt', this.boundOnRoomReceipt);
|
MatrixClientPeg.get().on('Room.receipt', this.boundOnRoomReceipt);
|
||||||
|
MatrixClientPeg.get().on('Event.decrypted', this.boundOnEventDecrypted);
|
||||||
MatrixClientPeg.get().on("sync", this.boundOnSyncStateChange);
|
MatrixClientPeg.get().on("sync", this.boundOnSyncStateChange);
|
||||||
this.toolbarHidden = false;
|
this.toolbarHidden = false;
|
||||||
this.isSyncing = false;
|
this.isSyncing = false;
|
||||||
|
@ -109,6 +118,7 @@ const Notifier = {
|
||||||
if (MatrixClientPeg.get() && this.boundOnRoomTimeline) {
|
if (MatrixClientPeg.get() && this.boundOnRoomTimeline) {
|
||||||
MatrixClientPeg.get().removeListener('Room.timeline', this.boundOnRoomTimeline);
|
MatrixClientPeg.get().removeListener('Room.timeline', this.boundOnRoomTimeline);
|
||||||
MatrixClientPeg.get().removeListener('Room.receipt', this.boundOnRoomReceipt);
|
MatrixClientPeg.get().removeListener('Room.receipt', this.boundOnRoomReceipt);
|
||||||
|
MatrixClientPeg.get().removeListener('Event.decrypted', this.boundOnEventDecrypted);
|
||||||
MatrixClientPeg.get().removeListener('sync', this.boundOnSyncStateChange);
|
MatrixClientPeg.get().removeListener('sync', this.boundOnSyncStateChange);
|
||||||
}
|
}
|
||||||
this.isSyncing = false;
|
this.isSyncing = false;
|
||||||
|
@ -244,16 +254,26 @@ const Notifier = {
|
||||||
if (ev.sender && ev.sender.userId === MatrixClientPeg.get().credentials.userId) return;
|
if (ev.sender && ev.sender.userId === MatrixClientPeg.get().credentials.userId) return;
|
||||||
if (data.timeline.getTimelineSet() !== room.getUnfilteredTimelineSet()) return;
|
if (data.timeline.getTimelineSet() !== room.getUnfilteredTimelineSet()) return;
|
||||||
|
|
||||||
const actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
|
// If it's an encrypted event and the type is still 'm.room.encrypted',
|
||||||
if (actions && actions.notify) {
|
// it hasn't yet been decrypted, so wait until it is.
|
||||||
if (this.isEnabled()) {
|
if (event.isBeingDecrypted() || event.isDecryptionFailure()) {
|
||||||
this._displayPopupNotification(ev, room);
|
this.pendingEncryptedEventIds.push(ev.getId());
|
||||||
}
|
// don't let the list fill up indefinitely
|
||||||
if (actions.tweaks.sound && this.isAudioEnabled()) {
|
while (this.pendingEncryptedEventIds.length > MAX_PENDING_ENCRYPTED) {
|
||||||
PlatformPeg.get().loudNotification(ev, room);
|
this.pendingEncryptedEventIds.shift();
|
||||||
this._playAudioNotification(ev, room);
|
|
||||||
}
|
}
|
||||||
|
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) {
|
onRoomReceipt: function(ev, room) {
|
||||||
|
@ -273,6 +293,20 @@ const Notifier = {
|
||||||
delete this.notifsByRoom[room.roomId];
|
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) {
|
if (!global.mxNotifier) {
|
||||||
|
|
Loading…
Reference in a new issue