From 9546b13821a8fa2e773a8df772d5c6b2b0173d86 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 5 May 2021 17:07:26 +0200 Subject: [PATCH] attempt to load sync writer position when joining a room during sync since fragments and events are not archived, just the summary, attempt to load the room and sync writer during sync, so we write the timeline correctly and don't cause ConstraintErrors because unaware of fragments and events already there. --- src/matrix/Sync.js | 15 ++++++++++++--- src/matrix/room/Room.js | 7 +++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/matrix/Sync.js b/src/matrix/Sync.js index f459297d..0fc10b84 100644 --- a/src/matrix/Sync.js +++ b/src/matrix/Sync.js @@ -223,7 +223,11 @@ export class Sync { return this._storage.readTxn([ storeNames.olmSessions, storeNames.inboundGroupSessions, - storeNames.timelineEvents // to read events that can now be decrypted + // to read fragments when loading sync writer when rejoining archived room + storeNames.timelineFragments, + // to read fragments when loading sync writer when rejoining archived room + // to read events that can now be decrypted + storeNames.timelineEvents, ]); } @@ -250,8 +254,13 @@ export class Sync { await Promise.all(roomStates.map(async rs => { const newKeys = newKeysByRoom?.get(rs.room.id); - rs.preparation = await log.wrap("room", log => rs.room.prepareSync( - rs.roomResponse, rs.membership, rs.invite, newKeys, prepareTxn, log), log.level.Detail); + rs.preparation = await log.wrap("room", async log => { + if (rs.isNewRoom) { + await rs.room.load(null, prepareTxn, log); + } + return rs.room.prepareSync( + rs.roomResponse, rs.membership, rs.invite, newKeys, prepareTxn, log) + }, log.level.Detail); })); // This is needed for safari to not throw TransactionInactiveErrors on the syncTxn. See docs/INDEXEDDB.md diff --git a/src/matrix/room/Room.js b/src/matrix/room/Room.js index 213575e9..61e3ff2e 100644 --- a/src/matrix/room/Room.js +++ b/src/matrix/room/Room.js @@ -423,7 +423,10 @@ export class Room extends EventEmitter { async load(summary, txn, log) { log.set("id", this.id); try { - this._summary.load(summary); + // if called from sync, there is no summary yet + if (summary) { + this._summary.load(summary); + } if (this._summary.data.encryption) { const roomEncryption = this._createRoomEncryption(this, this._summary.data.encryption); this._setEncryption(roomEncryption); @@ -714,7 +717,7 @@ export class Room extends EventEmitter { if (this._roomEncryption) { this._timeline.enableEncryption(this._decryptEntries.bind(this, DecryptionSource.Timeline)); } - await this._timeline.load(this._user, this._summary.data.membership, log); + await this._timeline.load(this._user, this.membership, log); return this._timeline; }); }