From ccc98d2f3d15a8ddf4f385f5af10ecc7d22ffed3 Mon Sep 17 00:00:00 2001 From: lilia Date: Sun, 21 Dec 2014 21:01:21 -0800 Subject: [PATCH] Fixup delivery receipts Uses app-level timestamps for outgoing messages. Adds timestamp property to the outgoing jsonData. Triggers a runtime event to notify frontend on delivery receipts. Renders delivered messages with a 'delivered' class. --- js/api.js | 1 + js/background.js | 9 ++++++--- js/models/conversations.js | 2 +- js/sendmessage.js | 25 +++++++++++++------------ js/views/message_view.js | 4 ++++ 5 files changed, 25 insertions(+), 16 deletions(-) diff --git a/js/api.js b/js/api.js index 02f336c2f654..d3096d84030b 100644 --- a/js/api.js +++ b/js/api.js @@ -215,6 +215,7 @@ window.textsecure.api = function () { var jsonData = { messages: messageArray }; if (messageArray[0].relay !== undefined) jsonData.relay = messageArray[0].relay; + jsonData.timestamp = messageArray[0].timestamp; return doAjax({ call : 'messages', diff --git a/js/background.js b/js/background.js index 7d440df7bb8d..63c6e20c3adc 100644 --- a/js/background.js +++ b/js/background.js @@ -157,17 +157,20 @@ } function onDeliveryReceipt(pushMessage) { - console.log('delivery receipt', pushMessage.source, timestamp); var timestamp = pushMessage.timestamp.toNumber(); var messages = new Whisper.MessageCollection(); var groups = new Whisper.ConversationCollection(); + console.log('delivery receipt', pushMessage.source, timestamp); messages.fetchSentAt(timestamp).then(function() { groups.fetchGroups(pushMessage.source).then(function() { - for (var message in messages.where({type: 'outgoing'})) { + for (var i in messages.where({type: 'outgoing'})) { + var message = messages.at(i); var deliveries = message.get('delivered') || 0; var conversationId = message.get('conversationId'); if (conversationId === pushMessage.source || groups.get(conversationId)) { - message.save({delivered: deliveries + 1}); + message.save({delivered: deliveries + 1}).then(function() { + extension.trigger('message', message); // notify frontend listeners + }); return; // TODO: consider keeping a list of numbers we've // successfully delivered to? diff --git a/js/models/conversations.js b/js/models/conversations.js index 0fb49dc156e9..fd6add195ccd 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -66,7 +66,7 @@ else { sendFunc = textsecure.messaging.sendMessageToGroup; } - sendFunc(this.get('id'), body, attachments).catch(function(e) { + sendFunc(this.get('id'), body, attachments, now).catch(function(e) { if (e.name === 'OutgoingIdentityKeyError') { e.args.push(message.id); message.save({ errors : [e] }).then(function() { diff --git a/js/sendmessage.js b/js/sendmessage.js index 519b643e6b98..8657c1e6d82f 100644 --- a/js/sendmessage.js +++ b/js/sendmessage.js @@ -47,7 +47,7 @@ window.textsecure.messaging = function() { // success_callback(server success/failure map), error_callback(error_msg) // message == PushMessageContentProto (NOT STRING) - function sendMessageToDevices(number, deviceObjectList, message, success_callback, error_callback) { + function sendMessageToDevices(timestamp, number, deviceObjectList, message, success_callback, error_callback) { var jsonData = []; var relay = undefined; var promises = []; @@ -71,7 +71,7 @@ window.textsecure.messaging = function() { destinationDeviceId: textsecure.utils.unencodeNumber(deviceObjectList[i].encodedNumber)[1], destinationRegistrationId: deviceObjectList[i].registrationId, body: encryptedMsg.body, - timestamp: new Date().getTime() + timestamp: timestamp }; if (deviceObjectList[i].relay !== undefined) @@ -136,7 +136,7 @@ window.textsecure.messaging = function() { }; textsecure.replay.registerFunction(tryMessageAgain, textsecure.replay.Type.SEND_MESSAGE); - var sendMessageProto = function(numbers, message, callback) { + var sendMessageProto = function(timestamp, numbers, message, callback) { var numbersCompleted = 0; var errors = []; var successfulNumbers = []; @@ -170,7 +170,7 @@ window.textsecure.messaging = function() { } doSendMessage = function(number, devicesForNumber, recurse) { - return sendMessageToDevices(number, devicesForNumber, message).then(function(result) { + return sendMessageToDevices(timestamp, number, devicesForNumber, message).then(function(result) { successfulNumbers[successfulNumbers.length] = number; numberCompleted(); }).catch(function(error) { @@ -234,9 +234,9 @@ window.textsecure.messaging = function() { }); } - var sendIndividualProto = function(number, proto) { + var sendIndividualProto = function(number, proto, timestamp) { return new Promise(function(resolve, reject) { - sendMessageProto([number], proto, function(res) { + sendMessageProto(timestamp, [number], proto, function(res) { if (res.failure.length > 0) reject(res.failure[0].error); else @@ -245,12 +245,13 @@ window.textsecure.messaging = function() { }); } - sendGroupProto = function(numbers, proto) { + sendGroupProto = function(numbers, proto, timestamp) { + timestamp = timestamp || Date.now(); var me = textsecure.utils.unencodeNumber(textsecure.storage.getUnencrypted("number_id"))[0]; numbers = numbers.filter(function(number) { return number != me; }); return new Promise(function(resolve, reject) { - sendMessageProto(numbers, proto, function(res) { + sendMessageProto(timestamp, numbers, proto, function(res) { if (res.failure.length > 0) reject(res.failure); else @@ -259,7 +260,7 @@ window.textsecure.messaging = function() { }); } - self.sendMessageToNumber = function(number, messageText, attachments) { + self.sendMessageToNumber = function(number, messageText, attachments, timestamp) { var proto = new textsecure.protobuf.PushMessageContent(); proto.body = messageText; @@ -268,7 +269,7 @@ window.textsecure.messaging = function() { promises.push(makeAttachmentPointer(attachments[i])); return Promise.all(promises).then(function(attachmentsArray) { proto.attachments = attachmentsArray; - return sendIndividualProto(number, proto); + return sendIndividualProto(number, proto, timestamp); }); } @@ -285,7 +286,7 @@ window.textsecure.messaging = function() { }); } - self.sendMessageToGroup = function(groupId, messageText, attachments) { + self.sendMessageToGroup = function(groupId, messageText, attachments, timestamp) { var proto = new textsecure.protobuf.PushMessageContent(); proto.body = messageText; proto.group = new textsecure.protobuf.PushMessageContent.GroupContext(); @@ -301,7 +302,7 @@ window.textsecure.messaging = function() { promises.push(makeAttachmentPointer(attachments[i])); return Promise.all(promises).then(function(attachmentsArray) { proto.attachments = attachmentsArray; - return sendGroupProto(numbers, proto); + return sendGroupProto(numbers, proto, timestamp); }); } diff --git a/js/views/message_view.js b/js/views/message_view.js index 04d51a0ecfc1..a64cf8d5c5bd 100644 --- a/js/views/message_view.js +++ b/js/views/message_view.js @@ -85,6 +85,10 @@ }) ); + if (this.model.get('delivered')) { + this.$el.addClass('delivered'); + } + var errors = this.model.get('errors'); if (errors && errors.length) { this.$el.find('.message').append(