1
1
/*
2
2
Copyright 2015, 2016 OpenMarket Ltd
3
3
Copyright 2017 Vector Creations Ltd
4
+ Copyright 2017 New Vector Ltd
4
5
5
6
Licensed under the Apache License, Version 2.0 (the "License");
6
7
you may not use this file except in compliance with the License.
@@ -33,9 +34,16 @@ import Modal from './Modal';
33
34
* }
34
35
*/
35
36
37
+ const MAX_PENDING_ENCRYPTED = 20 ;
38
+
36
39
const Notifier = {
37
40
notifsByRoom : { } ,
38
41
42
+ // A list of event IDs that we've received but need to wait until
43
+ // they're decrypted until we decide whether to notify for them
44
+ // or not
45
+ pendingEncryptedEventIds : [ ] ,
46
+
39
47
notificationMessageForEvent : function ( ev ) {
40
48
return TextForEvent . textForEvent ( ev ) ;
41
49
} ,
@@ -89,26 +97,28 @@ const Notifier = {
89
97
_playAudioNotification : function ( ev , room ) {
90
98
const e = document . getElementById ( "messageAudio" ) ;
91
99
if ( e ) {
92
- e . load ( ) ;
93
100
e . play ( ) ;
94
101
}
95
102
} ,
96
103
97
104
start : function ( ) {
98
- this . boundOnRoomTimeline = this . onRoomTimeline . bind ( this ) ;
105
+ this . boundOnEvent = this . onEvent . bind ( this ) ;
99
106
this . boundOnSyncStateChange = this . onSyncStateChange . bind ( this ) ;
100
107
this . boundOnRoomReceipt = this . onRoomReceipt . bind ( this ) ;
101
- MatrixClientPeg . get ( ) . on ( 'Room.timeline' , this . boundOnRoomTimeline ) ;
108
+ this . boundOnEventDecrypted = this . onEventDecrypted . bind ( this ) ;
109
+ MatrixClientPeg . get ( ) . on ( 'event' , this . boundOnEvent ) ;
102
110
MatrixClientPeg . get ( ) . on ( 'Room.receipt' , this . boundOnRoomReceipt ) ;
111
+ MatrixClientPeg . get ( ) . on ( 'Event.decrypted' , this . boundOnEventDecrypted ) ;
103
112
MatrixClientPeg . get ( ) . on ( "sync" , this . boundOnSyncStateChange ) ;
104
113
this . toolbarHidden = false ;
105
114
this . isSyncing = false ;
106
115
} ,
107
116
108
117
stop : function ( ) {
109
118
if ( MatrixClientPeg . get ( ) && this . boundOnRoomTimeline ) {
110
- MatrixClientPeg . get ( ) . removeListener ( 'Room.timeline ' , this . boundOnRoomTimeline ) ;
119
+ MatrixClientPeg . get ( ) . removeListener ( 'Event ' , this . boundOnEvent ) ;
111
120
MatrixClientPeg . get ( ) . removeListener ( 'Room.receipt' , this . boundOnRoomReceipt ) ;
121
+ MatrixClientPeg . get ( ) . removeListener ( 'Event.decrypted' , this . boundOnEventDecrypted ) ;
112
122
MatrixClientPeg . get ( ) . removeListener ( 'sync' , this . boundOnSyncStateChange ) ;
113
123
}
114
124
this . isSyncing = false ;
@@ -237,23 +247,30 @@ const Notifier = {
237
247
}
238
248
} ,
239
249
240
- onRoomTimeline : function ( ev , room , toStartOfTimeline , removed , data ) {
241
- if ( toStartOfTimeline ) return ;
242
- if ( ! room ) return ;
250
+ onEvent : function ( ev ) {
243
251
if ( ! this . isSyncing ) return ; // don't alert for any messages initially
244
252
if ( ev . sender && ev . sender . userId === MatrixClientPeg . get ( ) . credentials . userId ) return ;
245
- if ( data . timeline . getTimelineSet ( ) !== room . getUnfilteredTimelineSet ( ) ) return ;
246
253
247
- const actions = MatrixClientPeg . get ( ) . getPushActionsForEvent ( ev ) ;
248
- if ( actions && actions . notify ) {
249
- if ( this . isEnabled ( ) ) {
250
- this . _displayPopupNotification ( ev , room ) ;
251
- }
252
- if ( actions . tweaks . sound && this . isAudioEnabled ( ) ) {
253
- PlatformPeg . get ( ) . loudNotification ( ev , room ) ;
254
- this . _playAudioNotification ( ev , room ) ;
254
+ // If it's an encrypted event and the type is still 'm.room.encrypted',
255
+ // it hasn't yet been decrypted, so wait until it is.
256
+ if ( ev . isBeingDecrypted ( ) || ev . isDecryptionFailure ( ) ) {
257
+ this . pendingEncryptedEventIds . push ( ev . getId ( ) ) ;
258
+ // don't let the list fill up indefinitely
259
+ while ( this . pendingEncryptedEventIds . length > MAX_PENDING_ENCRYPTED ) {
260
+ this . pendingEncryptedEventIds . shift ( ) ;
255
261
}
262
+ return ;
256
263
}
264
+
265
+ this . _evaluateEvent ( ev ) ;
266
+ } ,
267
+
268
+ onEventDecrypted : function ( ev ) {
269
+ const idx = this . pendingEncryptedEventIds . indexOf ( ev . getId ( ) ) ;
270
+ if ( idx === - 1 ) return ;
271
+
272
+ this . pendingEncryptedEventIds . splice ( idx , 1 ) ;
273
+ this . _evaluateEvent ( ev ) ;
257
274
} ,
258
275
259
276
onRoomReceipt : function ( ev , room ) {
@@ -273,6 +290,20 @@ const Notifier = {
273
290
delete this . notifsByRoom [ room . roomId ] ;
274
291
}
275
292
} ,
293
+
294
+ _evaluateEvent : function ( ev ) {
295
+ const room = MatrixClientPeg . get ( ) . getRoom ( ev . getRoomId ( ) ) ;
296
+ const actions = MatrixClientPeg . get ( ) . getPushActionsForEvent ( ev ) ;
297
+ if ( actions && actions . notify ) {
298
+ if ( this . isEnabled ( ) ) {
299
+ this . _displayPopupNotification ( ev , room ) ;
300
+ }
301
+ if ( actions . tweaks . sound && this . isAudioEnabled ( ) ) {
302
+ PlatformPeg . get ( ) . loudNotification ( ev , room ) ;
303
+ this . _playAudioNotification ( ev , room ) ;
304
+ }
305
+ }
306
+ }
276
307
} ;
277
308
278
309
if ( ! global . mxNotifier ) {
0 commit comments