diff --git a/src/models/room-state.js b/src/models/room-state.js index 4fe608bbf..2ed858ab8 100644 --- a/src/models/room-state.js +++ b/src/models/room-state.js @@ -102,6 +102,10 @@ RoomState.prototype.getJoinedMemberCount = function() { return this._joinedMemberCount; }; +RoomState.prototype.setJoinedMemberCount = function(count) { + this._joinedMemberCount = count; +} + /** * Get all RoomMembers in this room. * @return {Array} A list of RoomMembers. diff --git a/src/models/room.js b/src/models/room.js index 51da8d391..7f546c946 100644 --- a/src/models/room.js +++ b/src/models/room.js @@ -172,6 +172,7 @@ function Room(roomId, opts) { // read by megolm; boolean value - null indicates "use global value" this._blacklistUnverifiedDevices = null; this._syncedMembership = null; + this._summaryHeroes = null; } utils.inherits(Room, EventEmitter); @@ -377,6 +378,22 @@ Room.prototype.setUnreadNotificationCount = function(type, count) { this._notificationCounts[type] = count; }; +Room.prototype.setSummary = function(summary) { + const heros = summary["m.heros"]; + const count = summary["m.joined_member_count"]; + if (Number.isInteger(count)) { + this.currentState.setJoinedMemberCount(count); + } + this._summaryHeroes = heros; + + const oldName = this.name; + this.name = calculateRoomName(this, userId); + + if (oldName !== this.name) { + this.emit("Room.name", this); + } +} + /** * Whether to send encrypted messages to devices within this room. * @param {Boolean} value true to blacklist unverified devices, null diff --git a/src/sync-accumulator.js b/src/sync-accumulator.js index 7369c9b8a..add58adb1 100644 --- a/src/sync-accumulator.js +++ b/src/sync-accumulator.js @@ -63,6 +63,7 @@ class SyncAccumulator { // { event: $event, token: null|token }, // ... // ], + // _summary: { m.heros: [ $user_id ], m.joined_member_count: $count } // _accountData: { $event_type: json }, // _unreadNotifications: { ... unread_notifications JSON ... }, // _readReceipts: { $user_id: { data: $json, eventId: $event_id }} @@ -242,6 +243,7 @@ class SyncAccumulator { _timeline: [], _accountData: Object.create(null), _unreadNotifications: {}, + _summary: {}, _readReceipts: {}, }; } @@ -258,6 +260,9 @@ class SyncAccumulator { if (data.unread_notifications) { currentData._unreadNotifications = data.unread_notifications; } + if (data.summary) { + currentData._summary = data.summary; + } if (data.ephemeral && data.ephemeral.events) { data.ephemeral.events.forEach((e) => { @@ -428,6 +433,7 @@ class SyncAccumulator { prev_batch: null, }, unread_notifications: roomData._unreadNotifications, + summary: roomData._summary, }; // Add account data Object.keys(roomData._accountData).forEach((evType) => { diff --git a/src/sync.js b/src/sync.js index 2cd190bd4..8e348b6f3 100644 --- a/src/sync.js +++ b/src/sync.js @@ -823,6 +823,7 @@ SyncApi.prototype._processSyncResponse = async function( // state: { events: [] }, // timeline: { events: [], prev_batch: $token, limited: true }, // ephemeral: { events: [] }, + // summary: { m.heros: [ $userId ], m.joined_member_count: $count } // account_data: { events: [] }, // unread_notifications: { // highlight_count: 0, @@ -1056,6 +1057,13 @@ SyncApi.prototype._processSyncResponse = async function( self._processRoomEvents(room, stateEvents, timelineEvents); + // set summary after processing events, + // because it will trigger a name calculation + // which needs the room state to be up to date + if (joinObj.summary) { + room.setSummary(joinObj.summary); + } + // XXX: should we be adding ephemeralEvents to the timeline? // It feels like that for symmetry with room.addAccountData() // there should be a room.addEphemeralEvents() or similar.