From a52740ed1b4fd7fcacc8bd2f9a9c78ceb17b3d9f Mon Sep 17 00:00:00 2001 From: Bruno Windels <274386+bwindels@users.noreply.github.com> Date: Thu, 2 Jun 2022 15:55:08 +0200 Subject: [PATCH] give room state handler access to member sync to get sender profile info --- src/matrix/room/Room.js | 14 ++++++++------ src/matrix/room/state/RoomStateHandlerSet.ts | 7 +++++-- src/matrix/room/state/types.ts | 5 +++-- .../room/timeline/persistence/MemberWriter.js | 6 +++++- src/matrix/room/timeline/persistence/SyncWriter.js | 2 +- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/matrix/room/Room.js b/src/matrix/room/Room.js index 38982786..425401d8 100644 --- a/src/matrix/room/Room.js +++ b/src/matrix/room/Room.js @@ -123,7 +123,7 @@ export class Room extends BaseRoom { txn.roomState.removeAllForRoom(this.id); txn.roomMembers.removeAllForRoom(this.id); } - const {entries: newEntries, updatedEntries, newLiveKey, memberChanges} = + const {entries: newEntries, updatedEntries, newLiveKey, memberChanges, memberSync} = await log.wrap("syncWriter", log => this._syncWriter.writeSync( roomResponse, isRejoin, summaryChanges.hasFetchedMembers, txn, log), log.level.Detail); if (decryptChanges) { @@ -180,7 +180,7 @@ export class Room extends BaseRoom { removedPendingEvents = await this._sendQueue.removeRemoteEchos(roomResponse.timeline.events, txn, log); } const powerLevelsEvent = this._getPowerLevelsEvent(roomResponse); - this._runRoomStateHandlers(roomResponse, txn, log); + await this._runRoomStateHandlers(roomResponse, memberSync, txn, log); return { roomResponse, summaryChanges, @@ -453,14 +453,16 @@ export class Room extends BaseRoom { return this._sendQueue.pendingEvents; } - /** global room state handlers, run during write sync step */ - _runRoomStateHandlers(roomResponse, txn, log) { + /** global room state handlers, run during writeSync step */ + _runRoomStateHandlers(roomResponse, memberSync, txn, log) { + const promises = []; iterateResponseStateEvents(roomResponse, event => { - this._roomStateHandler.handleRoomState(this, event, txn, log); + promises.push(this._roomStateHandler.handleRoomState(this, event, memberSync, txn, log)); }); + return Promise.all(promises); } - /** local room state observers, run during after sync step */ + /** local room state observers, run during afterSync step */ _emitSyncRoomState(roomResponse) { iterateResponseStateEvents(roomResponse, event => { for (const handler of this._roomStateObservers) { diff --git a/src/matrix/room/state/RoomStateHandlerSet.ts b/src/matrix/room/state/RoomStateHandlerSet.ts index 986cb0f9..491b02ce 100644 --- a/src/matrix/room/state/RoomStateHandlerSet.ts +++ b/src/matrix/room/state/RoomStateHandlerSet.ts @@ -20,14 +20,17 @@ import type {Transaction} from "../../storage/idb/Transaction"; import type {Room} from "../Room"; import type {MemberChange} from "../members/RoomMember"; import type {RoomStateHandler} from "./types"; +import type {MemberSync} from "../timeline/persistence/MemberWriter.js"; import {BaseObservable} from "../../../observable/BaseObservable"; /** keeps track of all handlers registered with Session.observeRoomState */ export class RoomStateHandlerSet extends BaseObservable implements RoomStateHandler { - handleRoomState(room: Room, stateEvent: StateEvent, txn: Transaction, log: ILogItem) { + async handleRoomState(room: Room, stateEvent: StateEvent, memberSync: MemberSync, txn: Transaction, log: ILogItem): Promise { + const promises: Promise[] = []; for(let h of this._handlers) { - h.handleRoomState(room, stateEvent, txn, log); + promises.push(h.handleRoomState(room, stateEvent, memberSync, txn, log)); } + await Promise.all(promises); } updateRoomMembers(room: Room, memberChanges: Map) { for(let h of this._handlers) { diff --git a/src/matrix/room/state/types.ts b/src/matrix/room/state/types.ts index ef99c727..2e7167d2 100644 --- a/src/matrix/room/state/types.ts +++ b/src/matrix/room/state/types.ts @@ -19,12 +19,13 @@ import type {StateEvent} from "../../storage/types"; import type {Transaction} from "../../storage/idb/Transaction"; import type {ILogItem} from "../../../logging/types"; import type {MemberChange} from "../members/RoomMember"; +import type {MemberSync} from "../timeline/persistence/MemberWriter"; /** used for Session.observeRoomState, which observes in all room, but without loading from storage * It receives the sync write transaction, so other stores can be updated as part of the same transaction. */ export interface RoomStateHandler { - handleRoomState(room: Room, stateEvent: StateEvent, syncWriteTxn: Transaction, log: ILogItem); - updateRoomMembers(room: Room, memberChanges: Map); + handleRoomState(room: Room, stateEvent: StateEvent, memberSync: MemberSync, syncWriteTxn: Transaction, log: ILogItem): Promise; + updateRoomMembers(room: Room, memberChanges: Map): void; } /** diff --git a/src/matrix/room/timeline/persistence/MemberWriter.js b/src/matrix/room/timeline/persistence/MemberWriter.js index 1cdcb7d5..9345324e 100644 --- a/src/matrix/room/timeline/persistence/MemberWriter.js +++ b/src/matrix/room/timeline/persistence/MemberWriter.js @@ -56,7 +56,11 @@ export class MemberWriter { } } -class MemberSync { +/** Represents the member changes in a given sync. + * Used to write the changes to storage and historical member + * information for events in the same sync. + **/ +export class MemberSync { constructor(memberWriter, stateEvents, timelineEvents, hasFetchedMembers) { this._memberWriter = memberWriter; this._timelineEvents = timelineEvents; diff --git a/src/matrix/room/timeline/persistence/SyncWriter.js b/src/matrix/room/timeline/persistence/SyncWriter.js index dc5ae3a8..76c7bec7 100644 --- a/src/matrix/room/timeline/persistence/SyncWriter.js +++ b/src/matrix/room/timeline/persistence/SyncWriter.js @@ -244,7 +244,7 @@ export class SyncWriter { const {currentKey, entries, updatedEntries} = await this._writeTimeline(timelineEvents, timeline, memberSync, this._lastLiveKey, txn, log); const memberChanges = await memberSync.write(txn); - return {entries, updatedEntries, newLiveKey: currentKey, memberChanges}; + return {entries, updatedEntries, newLiveKey: currentKey, memberChanges, memberSync}; } afterSync(newLiveKey) {