Skip to content

Commit

Permalink
Add ability to send unthreaded receipt (#2878)
Browse files Browse the repository at this point in the history
  • Loading branch information
Germain authored Nov 14, 2022
1 parent 0e32284 commit d43e664
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 19 deletions.
38 changes: 25 additions & 13 deletions spec/unit/read-receipt.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import MockHttpBackend from 'matrix-mock-request';

import { ReceiptType } from '../../src/@types/read_receipts';
import { MatrixClient } from "../../src/client";
import { Feature, ServerSupport } from '../../src/feature';
import { EventType } from '../../src/matrix';
import { MAIN_ROOM_TIMELINE } from '../../src/models/read-receipt';
import { encodeUri } from '../../src/utils';
Expand Down Expand Up @@ -69,15 +70,8 @@ const roomEvent = utils.mkEvent({
},
});

function mockServerSideSupport(client, hasServerSideSupport) {
const doesServerSupportUnstableFeature = client.doesServerSupportUnstableFeature;
client.doesServerSupportUnstableFeature = (unstableFeature) => {
if (unstableFeature === "org.matrix.msc3771") {
return Promise.resolve(hasServerSideSupport);
} else {
return doesServerSupportUnstableFeature(unstableFeature);
}
};
function mockServerSideSupport(client, serverSideSupport: ServerSupport) {
client.canSupport.set(Feature.ThreadUnreadNotifications, serverSideSupport);
}

describe("Read receipt", () => {
Expand All @@ -103,13 +97,31 @@ describe("Read receipt", () => {
expect(request.data.thread_id).toEqual(THREAD_ID);
}).respond(200, {});

mockServerSideSupport(client, true);
mockServerSideSupport(client, ServerSupport.Stable);
client.sendReceipt(threadEvent, ReceiptType.Read, {});

await httpBackend.flushAllExpected();
await flushPromises();
});

it("sends an unthreaded receipt", async () => {
httpBackend.when(
"POST", encodeUri("/rooms/$roomId/receipt/$receiptType/$eventId", {
$roomId: ROOM_ID,
$receiptType: ReceiptType.Read,
$eventId: threadEvent.getId()!,
}),
).check((request) => {
expect(request.data.thread_id).toBeUndefined();
}).respond(200, {});

mockServerSideSupport(client, ServerSupport.Stable);
client.sendReadReceipt(threadEvent, ReceiptType.Read, true);

await httpBackend.flushAllExpected();
await flushPromises();
});

it("sends a room read receipt", async () => {
httpBackend.when(
"POST", encodeUri("/rooms/$roomId/receipt/$receiptType/$eventId", {
Expand All @@ -121,7 +133,7 @@ describe("Read receipt", () => {
expect(request.data.thread_id).toEqual(MAIN_ROOM_TIMELINE);
}).respond(200, {});

mockServerSideSupport(client, true);
mockServerSideSupport(client, ServerSupport.Stable);
client.sendReceipt(roomEvent, ReceiptType.Read, {});

await httpBackend.flushAllExpected();
Expand All @@ -139,7 +151,7 @@ describe("Read receipt", () => {
expect(request.data.thread_id).toBeUndefined();
}).respond(200, {});

mockServerSideSupport(client, false);
mockServerSideSupport(client, ServerSupport.Unsupported);
client.sendReceipt(threadEvent, ReceiptType.Read, {});

await httpBackend.flushAllExpected();
Expand All @@ -157,7 +169,7 @@ describe("Read receipt", () => {
expect(request.data).toEqual({});
}).respond(200, {});

mockServerSideSupport(client, false);
mockServerSideSupport(client, ServerSupport.Unsupported);
client.sendReceipt(threadEvent, ReceiptType.Read, undefined);

await httpBackend.flushAllExpected();
Expand Down
18 changes: 12 additions & 6 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4588,13 +4588,15 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* @param {ReceiptType} receiptType The kind of receipt e.g. "m.read". Other than
* ReceiptType.Read are experimental!
* @param {object} body Additional content to send alongside the receipt.
* @param {boolean} unthreaded An unthreaded receipt will clear room+thread notifications
* @return {Promise} Resolves: to an empty object {}
* @return {module:http-api.MatrixError} Rejects: with an error response.
*/
public async sendReceipt(
event: MatrixEvent,
receiptType: ReceiptType,
body: any,
unthreaded = false,
): Promise<{}> {
if (this.isGuest()) {
return Promise.resolve({}); // guests cannot send receipts so don't bother.
Expand All @@ -4606,12 +4608,15 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
$eventId: event.getId()!,
});

// TODO: Add a check for which spec version this will be released in
if (await this.doesServerSupportUnstableFeature("org.matrix.msc3771")) {
const supportsThreadRR = this.canSupport.get(Feature.ThreadUnreadNotifications) !== ServerSupport.Unsupported;
if (supportsThreadRR && !unthreaded) {
const isThread = !!event.threadRootId;
body.thread_id = isThread
? event.threadRootId
: MAIN_ROOM_TIMELINE;
body = {
...body,
thread_id: isThread
? event.threadRootId
: MAIN_ROOM_TIMELINE,
};
}

const promise = this.http.authedRequest<{}>(Method.Post, path, undefined, body || {});
Expand All @@ -4633,6 +4638,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
public async sendReadReceipt(
event: MatrixEvent | null,
receiptType = ReceiptType.Read,
unthreaded = false,
): Promise<{} | undefined> {
if (!event) return;
const eventId = event.getId()!;
Expand All @@ -4641,7 +4647,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
throw new Error(`Cannot set read receipt to a pending event (${eventId})`);
}

return this.sendReceipt(event, receiptType, {});
return this.sendReceipt(event, receiptType, {}, unthreaded);
}

/**
Expand Down

0 comments on commit d43e664

Please sign in to comment.