diff --git a/spec/unit/room.spec.ts b/spec/unit/room.spec.ts index 7464faa41..a70e993ae 100644 --- a/spec/unit/room.spec.ts +++ b/spec/unit/room.spec.ts @@ -3018,6 +3018,14 @@ describe("Room", function () { expect(responseRelations![0][1].size).toEqual(1); expect(responseRelations![0][1].has(threadReaction)).toBeTruthy(); }); + + it("a non-thread reply to an unknown parent event should live in the main timeline only", async () => { + const message = mkMessage(); // we do not add this message to any timelines + const reply = mkReply(message); + + expect(room.eventShouldLiveIn(reply).shouldLiveInRoom).toBeTruthy(); + expect(room.eventShouldLiveIn(reply).shouldLiveInThread).toBeFalsy(); + }); }); describe("getEventReadUpTo()", () => { diff --git a/src/models/event-timeline-set.ts b/src/models/event-timeline-set.ts index cc41e543c..0427967fd 100644 --- a/src/models/event-timeline-set.ts +++ b/src/models/event-timeline-set.ts @@ -984,11 +984,20 @@ export class EventTimelineSet extends TypedEventEmitter { }; } - if (!parentEventId) { + // Due to replies not being typical relations and being used as fallbacks for threads relations + // If we bypass the if case above then we know we are not a thread, so if we are still a reply + // then we know that we must be in the main timeline. Same goes if we have no associated parent event. + if (!parentEventId || !!event.replyEventId) { return { shouldLiveInRoom: true, shouldLiveInThread: false,