From ed67d39456d2b85c7f40f66e9016944b786a9d5c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 5 Sep 2019 19:37:11 -0600 Subject: [PATCH 1/2] Support hidden read receipts --- src/base-apis.js | 6 +++++- src/client.js | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/base-apis.js b/src/base-apis.js index ad38b99c8e1..7c7a2fd6c0b 100644 --- a/src/base-apis.js +++ b/src/base-apis.js @@ -993,10 +993,13 @@ MatrixBaseApis.prototype.roomInitialSync = function(roomId, limit, callback) { * @param {string} rrEventId ID of the event tracked by the read receipt. This is here * for convenience because the RR and the RM are commonly updated at the same time as * each other. Optional. + * @param {object} opts Options for the read markers. + * @param {object} opts.hidden True to hide the read receipt from other users. This + * property is currently unstable and may change in the future. * @return {module:client.Promise} Resolves: the empty object, {}. */ MatrixBaseApis.prototype.setRoomReadMarkersHttpRequest = - function(roomId, rmEventId, rrEventId) { + function(roomId, rmEventId, rrEventId, opts) { const path = utils.encodeUri("/rooms/$roomId/read_markers", { $roomId: roomId, }); @@ -1004,6 +1007,7 @@ MatrixBaseApis.prototype.setRoomReadMarkersHttpRequest = const content = { "m.fully_read": rmEventId, "m.read": rrEventId, + "m.hidden": Boolean(opts ? opts.hidden : false) }; return this._http.authedRequest( diff --git a/src/client.js b/src/client.js index d4082877a87..a0e05a055d7 100644 --- a/src/client.js +++ b/src/client.js @@ -2192,11 +2192,17 @@ MatrixClient.prototype.sendHtmlEmote = function(roomId, body, htmlBody, callback * Send a receipt. * @param {Event} event The event being acknowledged * @param {string} receiptType The kind of receipt e.g. "m.read" + * @param {object} opts Additional content to send alongside the receipt. * @param {module:client.callback} callback Optional. * @return {module:client.Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ -MatrixClient.prototype.sendReceipt = function(event, receiptType, callback) { +MatrixClient.prototype.sendReceipt = function(event, receiptType, opts, callback) { + if (typeof(opts) === 'function') { + callback = opts; + opts = {}; + } + if (this.isGuest()) { return Promise.resolve({}); // guests cannot send receipts so don't bother. } @@ -2207,7 +2213,7 @@ MatrixClient.prototype.sendReceipt = function(event, receiptType, callback) { $eventId: event.getId(), }); const promise = this._http.authedRequest( - callback, "POST", path, undefined, {}, + callback, "POST", path, undefined, opts || {}, ); const room = this.getRoom(event.getRoomId()); @@ -2220,17 +2226,32 @@ MatrixClient.prototype.sendReceipt = function(event, receiptType, callback) { /** * Send a read receipt. * @param {Event} event The event that has been read. + * @param {object} opts The options for the read receipt. + * @param {boolean} opts.hidden True to prevent the receipt from being sent to + * other users and homeservers. Default false (send to everyone). This + * property is unstable and may change in the future. * @param {module:client.callback} callback Optional. * @return {module:client.Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ -MatrixClient.prototype.sendReadReceipt = async function(event, callback) { +MatrixClient.prototype.sendReadReceipt = async function(event, opts, callback) { + if (typeof(opts) === 'function') { + callback = opts; + opts = {}; + } + if (!opts) opts = {}; + const eventId = event.getId(); const room = this.getRoom(event.getRoomId()); if (room && room.hasPendingEvent(eventId)) { throw new Error(`Cannot set read receipt to a pending event (${eventId})`); } - return this.sendReceipt(event, "m.read", callback); + + const addlContent = { + "m.hidden": Boolean(opts.hidden), + }; + + return this.sendReceipt(event, "m.read", addlContent, callback); }; /** @@ -2243,9 +2264,12 @@ MatrixClient.prototype.sendReadReceipt = async function(event, callback) { * @param {string} rrEvent the event tracked by the read receipt. This is here for * convenience because the RR and the RM are commonly updated at the same time as each * other. The local echo of this receipt will be done if set. Optional. + * @param {object} opts Options for the read markers + * @param {object} opts.hidden True to hide the receipt from other users and homeservers. + * This property is unstable and may change in the future. * @return {module:client.Promise} Resolves: the empty object, {}. */ -MatrixClient.prototype.setRoomReadMarkers = async function(roomId, rmEventId, rrEvent) { +MatrixClient.prototype.setRoomReadMarkers = async function(roomId, rmEventId, rrEvent, opts) { const room = this.getRoom(roomId); if (room && room.hasPendingEvent(rmEventId)) { throw new Error(`Cannot set read marker to a pending event (${rmEventId})`); @@ -2263,7 +2287,7 @@ MatrixClient.prototype.setRoomReadMarkers = async function(roomId, rmEventId, rr } } - return this.setRoomReadMarkersHttpRequest(roomId, rmEventId, rrEventId); + return this.setRoomReadMarkersHttpRequest(roomId, rmEventId, rrEventId, opts); }; /** From 79bf64f07929da0d81d9fb252529cf5eb53ca995 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 5 Sep 2019 20:40:16 -0600 Subject: [PATCH 2/2] Appease the linter --- src/base-apis.js | 2 +- src/client.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/base-apis.js b/src/base-apis.js index 7c7a2fd6c0b..26ecd918052 100644 --- a/src/base-apis.js +++ b/src/base-apis.js @@ -1007,7 +1007,7 @@ MatrixBaseApis.prototype.setRoomReadMarkersHttpRequest = const content = { "m.fully_read": rmEventId, "m.read": rrEventId, - "m.hidden": Boolean(opts ? opts.hidden : false) + "m.hidden": Boolean(opts ? opts.hidden : false), }; return this._http.authedRequest( diff --git a/src/client.js b/src/client.js index a0e05a055d7..0c99c26313a 100644 --- a/src/client.js +++ b/src/client.js @@ -2269,7 +2269,9 @@ MatrixClient.prototype.sendReadReceipt = async function(event, opts, callback) { * This property is unstable and may change in the future. * @return {module:client.Promise} Resolves: the empty object, {}. */ -MatrixClient.prototype.setRoomReadMarkers = async function(roomId, rmEventId, rrEvent, opts) { +MatrixClient.prototype.setRoomReadMarkers = async function( + roomId, rmEventId, rrEvent, opts, +) { const room = this.getRoom(roomId); if (room && room.hasPendingEvent(rmEventId)) { throw new Error(`Cannot set read marker to a pending event (${rmEventId})`);