From 81b58388ee177672a0b55fcac8e5294529c12065 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 Jan 2024 15:20:11 +0000 Subject: [PATCH] Fix new threads not appearing. (#4009) * Fix new threads not appearing. We try to update the thread roots when creating a thread, but a thread can take some time to be ready after being created so we were calling it too soon. Add a listener for the Update event to update the thread roots once it's ready. Fixes https://github.com/element-hq/element-web/issues/26799 * Don't recreate the event when we update and also add a comment to the test * Hopefully make sonarcloud happy --- .../matrix-client-event-timeline.spec.ts | 2 +- src/models/room.ts | 9 +- src/models/thread.ts | 112 ++++++++++-------- 3 files changed, 70 insertions(+), 53 deletions(-) diff --git a/spec/integ/matrix-client-event-timeline.spec.ts b/spec/integ/matrix-client-event-timeline.spec.ts index 1d80cdd98d5..fe7823d448f 100644 --- a/spec/integ/matrix-client-event-timeline.spec.ts +++ b/spec/integ/matrix-client-event-timeline.spec.ts @@ -1555,7 +1555,7 @@ describe("MatrixClient event timelines", function () { expect(threadIds).toContain(THREAD2_ROOT.event_id); const [allThreads] = timelineSets!; const timeline = allThreads.getLiveTimeline()!; - // Test threads are in chronological order + // Test threads are in chronological order (first thread should be first because it has a more recent reply) expect(timeline.getEvents().map((it) => it.event.event_id)).toEqual([ THREAD_ROOT.event_id, THREAD2_ROOT.event_id, diff --git a/src/models/room.ts b/src/models/room.ts index 48fabcfce46..3d1f727da67 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -1979,6 +1979,7 @@ export class Room extends ReadReceipt { } this.on(ThreadEvent.NewReply, this.onThreadReply); + this.on(ThreadEvent.Update, this.onThreadUpdate); this.on(ThreadEvent.Delete, this.onThreadDelete); this.threadsReady = true; } @@ -2082,6 +2083,10 @@ export class Room extends ReadReceipt { } } + private onThreadUpdate(thread: Thread): void { + this.updateThreadRootEvents(thread, false, false); + } + private onThreadReply(thread: Thread): void { this.updateThreadRootEvents(thread, false, true); } @@ -2329,7 +2334,9 @@ export class Room extends ReadReceipt { this.lastThread = thread; } - if (this.threadsReady) { + // We need to update the thread root events, but the thread may not be ready yet. + // If it isn't, it will fire ThreadEvent.Update when it is and we'll call updateThreadRootEvents then. + if (this.threadsReady && thread.initialEventsFetched) { this.updateThreadRootEvents(thread, toStartOfTimeline, false); } this.emit(ThreadEvent.New, thread, toStartOfTimeline); diff --git a/src/models/thread.ts b/src/models/thread.ts index 855febb1ab2..96cea941b3c 100644 --- a/src/models/thread.ts +++ b/src/models/thread.ts @@ -133,7 +133,13 @@ export class Thread extends ReadReceipt; + /** + * Whether or not we need to fetch the initial set of events for the thread. We can + * only do this if the server has support for it, so if it doesn't we just pretend + * that we've already fetched them. + */ public initialEventsFetched = !Thread.hasServerSideSupport; + /** * An array of events to add to the timeline once the thread has been initialised * with server suppport. @@ -363,7 +369,7 @@ export class Thread extends ReadReceipt { + public addEvent(event: MatrixEvent, toStartOfTimeline: boolean, emit = true): void { // Modify this event to point at our room's state, and mark its thread // as this. this.setEventMetadata(event); @@ -382,56 +388,7 @@ export class Thread extends ReadReceipt): Promise { if (event) { this.setEventMetadata(event);