diff --git a/src/models/room.js b/src/models/room.js index b5ce503cb..818d0e263 100644 --- a/src/models/room.js +++ b/src/models/room.js @@ -178,7 +178,7 @@ function Room(roomId, client, myUserId, opts) { // read by megolm; boolean value - null indicates "use global value" this._blacklistUnverifiedDevices = null; - this._syncedMembership = null; + this._selfMembership = null; this._summaryHeroes = null; // awaited by getEncryptionTargetMembers while room members are loading @@ -263,7 +263,7 @@ Room.prototype.getMyMembership = function() { return me.membership; } } - return this._syncedMembership; + return this._selfMembership; }; /** @@ -278,7 +278,7 @@ Room.prototype.getDMInviter = function() { return me.getDMInviter(); } } - if (this._syncedMembership === "invite") { + if (this._selfMembership === "invite") { // fall back to summary information const memberCount = this.getInvitedAndJoinedMemberCount(); if (memberCount == 2 && this._summaryHeroes.length) { @@ -362,8 +362,15 @@ Room.prototype.getAvatarFallbackMember = function() { * Sets the membership this room was received as during sync * @param {string} membership join | leave | invite */ -Room.prototype.setSyncedMembership = function(membership) { - this._syncedMembership = membership; +Room.prototype.updateMyMembership = function(membership) { + const prevMembership = this._selfMembership; + this._selfMembership = membership; + if (prevMembership !== membership) { + if (membership === "leave") { + this._cleanupAfterLeaving(); + } + this.emit("Room.myMembership", this, membership, prevMembership); + } }; Room.prototype._loadMembersFromServer = async function() { @@ -470,7 +477,7 @@ Room.prototype.clearLoadedMembersIfNeeded = async function() { * called when sync receives this room in the leave section * to do cleanup after leaving a room. Possibly called multiple times. */ -Room.prototype.onLeft = function() { +Room.prototype._cleanupAfterLeaving = function() { this.clearLoadedMembersIfNeeded().catch((err) => { console.error(`error after clearing loaded members from ` + `room ${this.roomId} after leaving`); diff --git a/src/sync.js b/src/sync.js index bcb131c59..39e82abe4 100644 --- a/src/sync.js +++ b/src/sync.js @@ -123,6 +123,7 @@ SyncApi.prototype.createRoom = function(roomId) { "Room.timelineReset", "Room.localEchoUpdated", "Room.accountData", + "Room.myMembership", ]); this._registerStateListeners(room); return room; @@ -976,9 +977,10 @@ SyncApi.prototype._processSyncResponse = async function( // Handle invites inviteRooms.forEach(function(inviteObj) { const room = inviteObj.room; - room.setSyncedMembership("invite"); const stateEvents = self._mapSyncEventsFormat(inviteObj.invite_state, room); + + room.updateMyMembership("invite"); self._processRoomEvents(room, stateEvents); if (inviteObj.isBrandNewRoom) { room.recalculate(); @@ -993,7 +995,6 @@ SyncApi.prototype._processSyncResponse = async function( // Handle joins await Promise.mapSeries(joinRooms, async function(joinObj) { const room = joinObj.room; - room.setSyncedMembership("join"); const stateEvents = self._mapSyncEventsFormat(joinObj.state, room); const timelineEvents = self._mapSyncEventsFormat(joinObj.timeline, room); const ephemeralEvents = self._mapSyncEventsFormat(joinObj.ephemeral); @@ -1009,6 +1010,8 @@ SyncApi.prototype._processSyncResponse = async function( ); } + room.updateMyMembership("join"); + joinObj.timeline = joinObj.timeline || {}; if (joinObj.isBrandNewRoom) { @@ -1116,8 +1119,6 @@ SyncApi.prototype._processSyncResponse = async function( // Handle leaves (e.g. kicked rooms) leaveRooms.forEach(function(leaveObj) { const room = leaveObj.room; - room.setSyncedMembership("leave"); - const stateEvents = self._mapSyncEventsFormat(leaveObj.state, room); const timelineEvents = @@ -1125,6 +1126,8 @@ SyncApi.prototype._processSyncResponse = async function( const accountDataEvents = self._mapSyncEventsFormat(leaveObj.account_data); + room.updateMyMembership("leave"); + self._processRoomEvents(room, stateEvents, timelineEvents); room.addAccountData(accountDataEvents); @@ -1145,8 +1148,6 @@ SyncApi.prototype._processSyncResponse = async function( accountDataEvents.forEach(function(e) { client.emit("event", e); }); - - room.onLeft(); }); // update the notification timeline, if appropriate.