diff --git a/src/matrix/room/BaseRoom.js b/src/matrix/room/BaseRoom.js index 3314e9b1..47e4b390 100644 --- a/src/matrix/room/BaseRoom.js +++ b/src/matrix/room/BaseRoom.js @@ -21,7 +21,7 @@ import {RelationWriter} from "./timeline/persistence/RelationWriter.js"; import {Timeline} from "./timeline/Timeline.js"; import {FragmentIdComparer} from "./timeline/FragmentIdComparer.js"; import {WrappedError} from "../error.js" -import {fetchOrLoadMembers, loadMember} from "./members/load.js"; +import {fetchOrLoadMembers, fetchOrLoadMember} from "./members/load.js"; import {MemberList} from "./members/MemberList.js"; import {Heroes} from "./members/Heroes.js"; import {EventEntry} from "./timeline/entries/EventEntry.js"; @@ -224,8 +224,14 @@ export class BaseRoom extends EventEmitter { // Hit, we're already observing this member return mapMember; } - // Miss, load from storage and set in map - const member = await loadMember({roomId: this._roomId, userId, storage: this._storage}); + // Miss, load from storage/hs and set in map + const member = await fetchOrLoadMember({ + summary: this._summary, + roomId: this._roomId, + userId, + storage: this._storage, + hsApi: this._hsApi + }, this._platform.logger); if (!member) { return false; } diff --git a/src/matrix/room/members/load.js b/src/matrix/room/members/load.js index a7b2e641..8bd6c761 100644 --- a/src/matrix/room/members/load.js +++ b/src/matrix/room/members/load.js @@ -91,8 +91,39 @@ export async function fetchOrLoadMembers(options, logger) { } } -export async function loadMember({roomId, userId, storage}) { +export async function fetchOrLoadMember(options, logger) { + const member = await loadMember(options); + const {summary} = options; + if (!summary.data.hasFetchedMembers && !member) { + // We haven't fetched the memberlist yet; so ping the hs to see if this member does exist + return logger.wrapOrRun(options.log, "fetchMember", log => fetchMember(options, log)); + } + return member; +} + +async function loadMember({roomId, userId, storage}) { const txn = await storage.readTxn([storage.storeNames.roomMembers,]); const member = await txn.roomMembers.get(roomId, userId); return member? new RoomMember(member) : undefined; } + +async function fetchMember({roomId, userId, hsApi, storage}, log) { + const memberData = await hsApi.state(roomId, "m.room.member", userId, {log}).response(); + const member = new RoomMember({ + roomId, + userId, + membership: memberData.membership, + avatarUrl: memberData.avatar_url, + displayName: memberData.displayname, + }); + const txn = await storage.readWriteTxn([storage.storeNames.roomMembers]); + try { + txn.roomMembers.set(member.serialize()); + } + catch(e) { + txn.abort(); + throw e; + } + await txn.complete(); + return member; +}