From f67ccc18f4f9fef56a6ad674ef269ce281634ec2 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 8 Apr 2021 12:57:10 +0200 Subject: [PATCH] take most recent member rather than first in timeline for inline lookup noticed this while inspecting the code, looks related to #269 --- .../room/timeline/persistence/MemberWriter.js | 30 +++++++++++++++---- .../room/timeline/persistence/SyncWriter.js | 2 +- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/matrix/room/timeline/persistence/MemberWriter.js b/src/matrix/room/timeline/persistence/MemberWriter.js index dc6f621d..73da64cd 100644 --- a/src/matrix/room/timeline/persistence/MemberWriter.js +++ b/src/matrix/room/timeline/persistence/MemberWriter.js @@ -73,7 +73,8 @@ export class MemberWriter { } } - async lookupMember(userId, timelineEvents, txn) { + async lookupSenderMember(event, timelineEvents, txn) { + const userId = event.sender; let member = this._cache.get(userId); if (!member) { const memberData = await txn.roomMembers.get(this._roomId, userId); @@ -83,12 +84,21 @@ export class MemberWriter { } } if (!member) { + let memberEvent; // sometimes the member event isn't included in state, but rather in the timeline, - // even if it is not the first event in the timeline. In this case, go look for the - // first occurence - const memberEvent = timelineEvents.find(e => { - return e.type === MEMBER_EVENT_TYPE && e.state_key === userId; - }); + // even if it is not the first event in the timeline. In this case, go look for + // the last one before the event + let foundEvent = false; + for (let i = timelineEvents.length - 1; i >= 0; i -= 1) { + const e = timelineEvents[i]; + if (!foundEvent && e.event_id === event.event_id) { + foundEvent = true; + } + if (foundEvent && e.type === MEMBER_EVENT_TYPE && e.state_key === userId) { + memberEvent = e; + break; + } + } if (memberEvent) { member = RoomMember.fromMemberEvent(this._roomId, memberEvent); } @@ -228,5 +238,13 @@ export function tests() { const change = await writer.writeTimelineMemberEvent(event, txn); assert(change); }, + "lookupSenderMember returns closest member in the past": async assert => { + const event1 = createMemberEvent("join", alice, "Alice"); + const event2 = createMemberEvent("join", alice, "Alies"); + const writer = new MemberWriter(roomId); + const txn = createStorage(); + const member = await writer.lookupSenderMember(event2, [event1, event2], txn); + assert.equal(member.displayName, "Alies"); + }, }; } diff --git a/src/matrix/room/timeline/persistence/SyncWriter.js b/src/matrix/room/timeline/persistence/SyncWriter.js index a7675993..1f251fce 100644 --- a/src/matrix/room/timeline/persistence/SyncWriter.js +++ b/src/matrix/room/timeline/persistence/SyncWriter.js @@ -162,7 +162,7 @@ export class SyncWriter { // store event in timeline currentKey = currentKey.nextKey(); const entry = createEventEntry(currentKey, this._roomId, event); - let member = await this._memberWriter.lookupMember(event.sender, events, txn); + let member = await this._memberWriter.lookupSenderMember(event, events, txn); if (member) { entry.displayName = member.displayName; entry.avatarUrl = member.avatarUrl;