Skip to content

Commit 767cd62

Browse files
authored
Consider the unthreaded read receipt for Unread dot state (matrix-org#11117)
* Consider the unthreaded read receipt for Unread dot state also * Add tests * Fix strict types
1 parent 9b5b053 commit 767cd62

File tree

2 files changed

+83
-12
lines changed

2 files changed

+83
-12
lines changed

src/Unread.ts

+8-10
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,13 @@ function makeHasReceipt(
159159
// If we found an event matching our receipt, then it's easy: this event
160160
// has a receipt if its ID is the same as the one in the receipt.
161161
return (ev) => ev.getId() == readUpToId;
162-
} else {
163-
// If we didn't, we have to guess by saying if this event is before the
164-
// receipt's ts, then it we pretend it has a receipt.
165-
const receipt = roomOrThread.getReadReceiptForUserId(myUserId);
166-
if (receipt) {
167-
const receiptTimestamp = receipt.data.ts;
168-
return (ev) => ev.getTs() < receiptTimestamp;
169-
} else {
170-
return (_ev) => false;
171-
}
172162
}
163+
164+
// If we didn't, we have to guess by saying if this event is before the
165+
// receipt's ts, then it we pretend it has a receipt.
166+
const receiptTs = roomOrThread.getReadReceiptForUserId(myUserId)?.data.ts ?? 0;
167+
const unthreadedReceiptTs = roomOrThread.getLastUnthreadedReceiptFor(myUserId)?.ts ?? 0;
168+
// We pick the more recent of the two receipts as the latest
169+
const receiptTimestamp = Math.max(receiptTs, unthreadedReceiptTs);
170+
return (ev) => ev.getTs() < receiptTimestamp;
173171
}

test/Unread-test.ts

+75-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ import { logger } from "matrix-js-sdk/src/logger";
2222
import { haveRendererForEvent } from "../src/events/EventTileFactory";
2323
import { makeBeaconEvent, mkEvent, stubClient } from "./test-utils";
2424
import { mkThread } from "./test-utils/threads";
25-
import { doesRoomHaveUnreadMessages, eventTriggersUnreadCount } from "../src/Unread";
25+
import {
26+
doesRoomHaveUnreadMessages,
27+
doesRoomOrThreadHaveUnreadMessages,
28+
eventTriggersUnreadCount,
29+
} from "../src/Unread";
2630
import { MatrixClientPeg } from "../src/MatrixClientPeg";
2731

2832
jest.mock("../src/events/EventTileFactory", () => ({
@@ -122,7 +126,7 @@ describe("Unread", () => {
122126
let room: Room;
123127
let event: MatrixEvent;
124128
const roomId = "!abc:server.org";
125-
const myId = client.getUserId()!;
129+
const myId = client.getSafeUserId();
126130

127131
beforeAll(() => {
128132
client.supportsThreads = () => true;
@@ -429,4 +433,73 @@ describe("Unread", () => {
429433
);
430434
});
431435
});
436+
437+
describe("doesRoomOrThreadHaveUnreadMessages()", () => {
438+
let room: Room;
439+
let event: MatrixEvent;
440+
const roomId = "!abc:server.org";
441+
const myId = client.getSafeUserId();
442+
443+
beforeAll(() => {
444+
client.supportsThreads = () => true;
445+
});
446+
447+
beforeEach(() => {
448+
room = new Room(roomId, client, myId);
449+
jest.spyOn(logger, "warn");
450+
event = mkEvent({
451+
event: true,
452+
type: "m.room.message",
453+
user: aliceId,
454+
room: roomId,
455+
content: {},
456+
});
457+
room.addLiveEvents([event]);
458+
459+
// Don't care about the code path of hidden events.
460+
mocked(haveRendererForEvent).mockClear().mockReturnValue(true);
461+
});
462+
463+
it("should consider unthreaded read receipts for main timeline", () => {
464+
// Send unthreaded receipt into room pointing at the latest event
465+
room.addReceipt(
466+
new MatrixEvent({
467+
type: "m.receipt",
468+
room_id: "!foo:bar",
469+
content: {
470+
[event.getId()!]: {
471+
[ReceiptType.Read]: {
472+
[myId]: { ts: 1 },
473+
},
474+
},
475+
},
476+
}),
477+
);
478+
479+
expect(doesRoomOrThreadHaveUnreadMessages(room)).toBe(false);
480+
});
481+
482+
it("should consider unthreaded read receipts for thread timelines", () => {
483+
// Provide an unthreaded read receipt with ts greater than the latest thread event
484+
const receipt = new MatrixEvent({
485+
type: "m.receipt",
486+
room_id: "!foo:bar",
487+
content: {
488+
[event.getId()!]: {
489+
[ReceiptType.Read]: {
490+
[myId]: { ts: 10000000000 },
491+
},
492+
},
493+
},
494+
});
495+
room.addReceipt(receipt);
496+
497+
const { thread } = mkThread({ room, client, authorId: myId, participantUserIds: [aliceId] });
498+
499+
expect(thread.replyToEvent!.getTs()).toBeLessThan(
500+
receipt.getContent()[event.getId()!][ReceiptType.Read][myId].ts,
501+
);
502+
expect(doesRoomOrThreadHaveUnreadMessages(thread)).toBe(false);
503+
});
504+
});
432505
});

0 commit comments

Comments
 (0)