From 8c85f6e3a6ad4397a1af5af7747e7f5f11e715ba Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Thu, 24 May 2018 18:54:06 -0700 Subject: [PATCH] When marking message read, ensure that peers have same read_at When we mark a message as read, we go to the database to ensure that older messages in this conversation are marked read as well. That optimization was missing the read_at value provided to the starting message, so now it is piped along to all of them. --- js/models/conversations.js | 9 ++++++--- js/models/messages.js | 7 +++---- js/read_syncs.js | 9 ++++++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/js/models/conversations.js b/js/models/conversations.js index ff9ec684c..0af70ccf0 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -541,7 +541,7 @@ } }, - onReadMessage(message) { + onReadMessage(message, readAt) { if (this.messageCollection.get(message.id)) { this.messageCollection.get(message.id).fetch(); } @@ -558,7 +558,10 @@ // Lastly, we don't send read syncs for any message marked read due to a read // sync. That's a notification explosion we don't need. return this.queueJob(() => - this.markRead(message.get('received_at'), { sendReadReceipts: false }) + this.markRead(message.get('received_at'), { + sendReadReceipts: false, + readAt, + }) ); }, @@ -1018,7 +1021,7 @@ 'it was not in messageCollection.' ); } - promises.push(m.markRead()); + promises.push(m.markRead(options.readAt)); const errors = m.get('errors'); return { sender: m.get('source'), diff --git a/js/models/messages.js b/js/models/messages.js index e135def67..ed8ec6267 100644 --- a/js/models/messages.js +++ b/js/models/messages.js @@ -7,6 +7,7 @@ /* global Signal: false */ /* global textsecure: false */ /* global Whisper: false */ +/* global wrapDeferred: false */ /* eslint-disable more/no-then */ @@ -798,7 +799,7 @@ }) ); }, - markRead(readAt) { + async markRead(readAt) { this.unset('unread'); if (this.get('expireTimer') && !this.get('expirationStartTimestamp')) { this.set('expirationStartTimestamp', readAt || Date.now()); @@ -808,9 +809,7 @@ messageId: this.id, }) ); - return new Promise((resolve, reject) => { - this.save().then(resolve, reject); - }); + return wrapDeferred(this.save()); }, isExpiring() { return this.get('expireTimer') && this.get('expirationStartTimestamp'); diff --git a/js/read_syncs.js b/js/read_syncs.js index 3a248fd2e..55f1ce980 100644 --- a/js/read_syncs.js +++ b/js/read_syncs.js @@ -45,7 +45,10 @@ return message ? message.markRead(receipt.get('read_at')).then( function() { - this.notifyConversation(message); + // This notification may result in messages older than this one being + // marked read. We want those messages to have the same expire timer + // start time as this one, so we pass the read_at value through. + this.notifyConversation(message, receipt.get('read_at')); this.remove(receipt); }.bind(this) ) @@ -53,13 +56,13 @@ }.bind(this) ); }, - notifyConversation: function(message) { + notifyConversation: function(message, readAt) { var conversation = ConversationController.get({ id: message.get('conversationId'), }); if (conversation) { - conversation.onReadMessage(message); + conversation.onReadMessage(message, readAt); } }, }))();