diff --git a/src/components/structures/TimelinePanel.tsx b/src/components/structures/TimelinePanel.tsx index ab3c96b8f927..b2f8431d1834 100644 --- a/src/components/structures/TimelinePanel.tsx +++ b/src/components/structures/TimelinePanel.tsx @@ -979,7 +979,7 @@ class TimelinePanel extends React.Component { * Whether to send public or private receipts. */ private async determineReceiptType(client: MatrixClient): Promise { - const roomId = this.props.timelineSet.room.roomId; + const roomId = this.props.timelineSet.room?.roomId ?? null; const shouldSendPublicReadReceipts = SettingsStore.getValue("sendReadReceipts", roomId); if (shouldSendPublicReadReceipts) { @@ -1000,7 +1000,12 @@ class TimelinePanel extends React.Component { /** * Whether a fully_read marker should be send. */ - private shouldSendRM(): boolean { + private shouldSendRM(readMarkerEventId: string | null): readMarkerEventId is string { + if (!this.state.readMarkerEventId) { + // Nothing that can be send. + return false; + } + if (this.lastRRSentEventId && this.lastRMSentEventId === this.state.readMarkerEventId) { // Prevent sending the same receipt twice. return false; @@ -1082,9 +1087,10 @@ class TimelinePanel extends React.Component { lastReadEvent, lastReadEventIndex, ); - const shouldSendRM = this.shouldSendRM(); + const readMarkerEventId = this.state.readMarkerEventId; + const shouldSendRM = this.shouldSendRM(readMarkerEventId); - debuglog(`Sending Read Markers for ${this.props.timelineSet.room.roomId}: `, { + debuglog(`Sending Read Markers for ${this.props.timelineSet.room?.roomId}: `, { shouldSendRR, shouldSendRM, currentRREventId, @@ -1101,7 +1107,7 @@ class TimelinePanel extends React.Component { } if (shouldSendRM) { - const readMarkerEvent = this.props.timelineSet.findEventById(this.state.readMarkerEventId); + const readMarkerEvent = this.props.timelineSet.findEventById(readMarkerEventId); if (readMarkerEvent) { proms.push(await this.sendReadMarker(client, readMarkerEvent)); @@ -1126,7 +1132,7 @@ class TimelinePanel extends React.Component { this.lastRRSentEventId = undefined; logger.error("Error sending receipt", { - room: this.props.timelineSet.room.roomId, + room: this.props.timelineSet.room?.roomId, error: err, }); } @@ -1146,7 +1152,7 @@ class TimelinePanel extends React.Component { this.lastRMSentEventId = undefined; logger.error("Error sending fully_read", { - room: this.props.timelineSet.room.roomId, + room: this.props.timelineSet.room?.roomId, error: err, }); } diff --git a/test/components/structures/TimelinePanel-test.tsx b/test/components/structures/TimelinePanel-test.tsx index 1fb0572b17c7..7d09c0ae711b 100644 --- a/test/components/structures/TimelinePanel-test.tsx +++ b/test/components/structures/TimelinePanel-test.tsx @@ -144,14 +144,14 @@ describe("TimelinePanel", () => { />, ); await flushPromises(); - timelinePanel = ref.current; + timelinePanel = ref.current!; }; const setUpTimelineSet = (threadRoot?: MatrixEvent) => { let thread: Thread | undefined = undefined; if (threadRoot) { - thread = new Thread(threadRoot.getId(), threadRoot, { + thread = new Thread(threadRoot.getId()!, threadRoot, { client: client, room, }); @@ -211,7 +211,7 @@ describe("TimelinePanel", () => { it("and forgetting the read markers, should send the stored marker again", async () => { timelineSet.addLiveEvent(ev2, {}); - room.addEphemeralEvents([newReceipt(ev2.getId(), userId, 222, 200)]); + room.addEphemeralEvents([newReceipt(ev2.getId()!, userId, 222, 200)]); timelinePanel.forgetReadMarker(); await flushPromises(); expect(client.sendReadReceipt).toHaveBeenCalledWith(ev2, ReceiptType.FullyRead, true);