@@ -194,11 +194,13 @@ export function Room(roomId, client, myUserId, opts) {
194
194
const serializedPendingEventList = client . _sessionStore . store . getItem ( pendingEventsKey ( this . roomId ) ) ;
195
195
if ( serializedPendingEventList ) {
196
196
JSON . parse ( serializedPendingEventList )
197
- . forEach ( serializedEvent => {
197
+ . forEach ( async serializedEvent => {
198
198
const event = new MatrixEvent ( serializedEvent ) ;
199
+ if ( event . getType ( ) === "m.room.encrypted" ) {
200
+ await event . attemptDecryption ( this . _client . _crypto ) ;
201
+ }
199
202
event . setStatus ( EventStatus . NOT_SENT ) ;
200
- const txnId = client . makeTxnId ( ) ;
201
- this . addPendingEvent ( event , txnId ) ;
203
+ this . addPendingEvent ( event , event . getTxnId ( ) ) ;
202
204
} ) ;
203
205
}
204
206
}
@@ -396,15 +398,7 @@ Room.prototype.removePendingEvent = function(eventId) {
396
398
} , false ,
397
399
) ;
398
400
399
- const { store } = this . _client . _sessionStore ;
400
- if ( this . _pendingEventList . length > 0 ) {
401
- store . setItem (
402
- pendingEventsKey ( this . roomId ) ,
403
- JSON . stringify ( this . _pendingEventList ) ,
404
- ) ;
405
- } else {
406
- store . removeItem ( pendingEventsKey ( this . roomId ) ) ;
407
- }
401
+ this . _savePendingEvents ( ) ;
408
402
409
403
return removed ;
410
404
} ;
@@ -1271,11 +1265,7 @@ Room.prototype.addPendingEvent = function(event, txnId) {
1271
1265
event . setStatus ( EventStatus . NOT_SENT ) ;
1272
1266
}
1273
1267
this . _pendingEventList . push ( event ) ;
1274
- const { store } = this . _client . _sessionStore ;
1275
- store . setItem (
1276
- pendingEventsKey ( this . roomId ) ,
1277
- JSON . stringify ( this . _pendingEventList ) ,
1278
- ) ;
1268
+ this . _savePendingEvents ( ) ;
1279
1269
if ( event . isRelation ( ) ) {
1280
1270
// For pending events, add them to the relations collection immediately.
1281
1271
// (The alternate case below already covers this as part of adding to
@@ -1312,6 +1302,46 @@ Room.prototype.addPendingEvent = function(event, txnId) {
1312
1302
1313
1303
this . emit ( "Room.localEchoUpdated" , event , this , null , null ) ;
1314
1304
} ;
1305
+
1306
+ /**
1307
+ * Persists all pending events to local storage
1308
+ *
1309
+ * If the current room is encrypted only encrypted events will be persisted
1310
+ * all messages that are not yet encrypted will be discarded
1311
+ *
1312
+ * This is because the flow of EVENT_STATUS transition is
1313
+ * queued => sending => encrypting => sending => sent
1314
+ *
1315
+ * Steps 3 and 4 are skipped for unencrypted room.
1316
+ * It is better to discard an unencrypted message rather than persisting
1317
+ * it locally for everyone to read
1318
+ */
1319
+ Room . prototype . _savePendingEvents = function ( ) {
1320
+ if ( this . _pendingEventList ) {
1321
+ const pendingEvents = this . _pendingEventList . map ( event => {
1322
+ return {
1323
+ ...event . event ,
1324
+ txn_id : event . getTxnId ( ) ,
1325
+ } ;
1326
+ } ) . filter ( event => {
1327
+ // Filter out the unencrypted messages if the room is encrypted
1328
+ const isEventEncrypted = event . type === "m.room.encrypted" ;
1329
+ const isRoomEncrypted = this . _client . isRoomEncrypted ( this . roomId ) ;
1330
+ return isEventEncrypted || ! isRoomEncrypted ;
1331
+ } ) ;
1332
+
1333
+ const { store } = this . _client . _sessionStore ;
1334
+ if ( this . _pendingEventList . length > 0 ) {
1335
+ store . setItem (
1336
+ pendingEventsKey ( this . roomId ) ,
1337
+ JSON . stringify ( pendingEvents ) ,
1338
+ ) ;
1339
+ } else {
1340
+ store . removeItem ( pendingEventsKey ( this . roomId ) ) ;
1341
+ }
1342
+ }
1343
+ } ;
1344
+
1315
1345
/**
1316
1346
* Used to aggregate the local echo for a relation, and also
1317
1347
* for re-applying a relation after it's redaction has been cancelled,
@@ -1472,9 +1502,6 @@ Room.prototype.updatePendingEvent = function(event, newStatus, newEventId) {
1472
1502
for ( let i = 0 ; i < this . _timelineSets . length ; i ++ ) {
1473
1503
this . _timelineSets [ i ] . replaceEventId ( oldEventId , newEventId ) ;
1474
1504
}
1475
- if ( this . _opts . pendingEventOrdering === "detached" ) {
1476
- this . removePendingEvent ( event . event . event_id ) ;
1477
- }
1478
1505
} else if ( newStatus == EventStatus . CANCELLED ) {
1479
1506
// remove it from the pending event list, or the timeline.
1480
1507
if ( this . _pendingEventList ) {
@@ -1488,6 +1515,7 @@ Room.prototype.updatePendingEvent = function(event, newStatus, newEventId) {
1488
1515
}
1489
1516
this . removeEvent ( oldEventId ) ;
1490
1517
}
1518
+ this . _savePendingEvents ( ) ;
1491
1519
1492
1520
this . emit ( "Room.localEchoUpdated" , event , this , oldEventId , oldStatus ) ;
1493
1521
} ;
0 commit comments