diff --git a/background.html b/background.html index 04f61ac8..a715e64e 100644 --- a/background.html +++ b/background.html @@ -394,6 +394,7 @@ + diff --git a/js/background.js b/js/background.js index 4b010a20..828131de 100644 --- a/js/background.js +++ b/js/background.js @@ -278,43 +278,14 @@ function onDeliveryReceipt(ev) { var pushMessage = ev.proto; var timestamp = pushMessage.timestamp.toNumber(); - var messages = new Whisper.MessageCollection(); - var groups = new Whisper.ConversationCollection(); console.log( 'delivery receipt from', pushMessage.source + '.' + pushMessage.sourceDevice, timestamp ); - groups.fetchGroups(pushMessage.source).then(function() { - messages.fetchSentAt(timestamp).then(function() { - var ids = groups.pluck('id'); - ids.push(pushMessage.source); - var message = messages.find(function(message) { - return (!message.isIncoming() && - _.contains(ids, message.get('conversationId'))); - }); - if (message) { - var deliveries = message.get('delivered') || 0; - message.save({delivered: deliveries + 1}).then(function() { - // notify frontend listeners - var conversation = ConversationController.get( - message.get('conversationId') - ); - if (conversation) { - conversation.trigger('newmessage', message); - } - }); - // TODO: consider keeping a list of numbers we've - // successfully delivered to? - return; - } - // if we get here, we didn't find a matching message. - // keep the receipt in memory in case it shows up later - // as a sync message. - receipts.add({ timestamp: timestamp, source: pushMessage.source }); - return; - }); + Whisper.DeliveryReceipts.add({ + timestamp: timestamp, source: pushMessage.source }); } })(); diff --git a/js/delivery_receipts.js b/js/delivery_receipts.js new file mode 100644 index 00000000..5d642119 --- /dev/null +++ b/js/delivery_receipts.js @@ -0,0 +1,58 @@ +/* + * vim: ts=4:sw=4:expandtab + */ +;(function() { + 'use strict'; + window.Whisper = window.Whisper || {}; + Whisper.DeliveryReceipts = new (Backbone.Collection.extend({ + initialize: function() { + this.on('add', this.onReceipt); + }, + forMessage: function(conversation, message) { + var recipients; + if (conversation.isPrivate()) { + recipients = [ conversation.id ]; + } else { + recipients = conversation.get('members') || []; + } + var receipts = this.filter(function(receipt) { + return (receipt.get('timestamp') === message.get('sent_at')) && + (recipients.indexOf(receipt.get('source')) > -1); + }); + this.remove(receipts); + return receipts; + }, + onReceipt: function(receipt) { + var messages = new Whisper.MessageCollection(); + var groups = new Whisper.ConversationCollection(); + Promise.all([ + groups.fetchGroups(receipt.get('source')), + messages.fetchSentAt(receipt.get('timestamp')) + ]).then(function() { + var ids = groups.pluck('id'); + ids.push(receipt.get('source')); + var message = messages.find(function(message) { + return (!message.isIncoming() && + _.contains(ids, message.get('conversationId'))); + }); + if (message) { + this.remove(receipt); + var deliveries = message.get('delivered') || 0; + message.save({ + delivered: deliveries + 1 + }).then(function() { + // notify frontend listeners + var conversation = ConversationController.get( + message.get('conversationId') + ); + if (conversation) { + conversation.trigger('newmessage', message); + } + }); + // TODO: consider keeping a list of numbers we've + // successfully delivered to? + } + }.bind(this)); + } + }))(); +})(); diff --git a/js/models/conversations.js b/js/models/conversations.js index df1c331e..8cf21613 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -509,12 +509,14 @@ }, fetchGroups: function(number) { - return this.fetch({ - index: { - name: 'group', - only: number - } - }); + return new Promise(function(resolve) { + this.fetch({ + index: { + name: 'group', + only: number + } + }).always(resolve); + }.bind(this)); }, fetchActive: function() { diff --git a/js/models/messages.js b/js/models/messages.js index 67588a2d..6e6b4fe9 100644 --- a/js/models/messages.js +++ b/js/models/messages.js @@ -317,18 +317,8 @@ } } if (type === 'outgoing') { - // lazy hack - check for receipts that arrived early. - var recipients; - if (dataMessage.group && dataMessage.group.id) { // group sync - recipients = conversation.get('members') || []; - } else { - recipients = [ conversation.id ]; - } - window.receipts.filter(function(receipt) { - return (receipt.get('timestamp') === timestamp) && - (recipients.indexOf(receipt.get('source')) > -1); - }).forEach(function(receipt) { - window.receipts.remove(receipt); + var receipts = Whisper.DeliveryReceipts.forMessage(conversation, message); + receipts.forEach(function(receipt) { message.set({ delivered: (message.get('delivered') || 0) + 1 }); @@ -402,13 +392,15 @@ }, fetchSentAt: function(timestamp) { - return this.fetch({ - index: { - // 'receipt' index on sent_at - name: 'receipt', - only: timestamp - } - }); + return new Promise(function(resolve) { + return this.fetch({ + index: { + // 'receipt' index on sent_at + name: 'receipt', + only: timestamp + } + }).always(resolve); + }.bind(this)); }, fetchConversation: function(conversationId, limit) {