signal-desktop/js/delivery_receipts.js
lilia aed5735620 Improve keychange notice reliability/perf
Bind a single listener to keychange events from the storage interface,
which then looks up relevant conversations and adds notices to them,
with tests.

Previously we would need to instantiate a conversation model in order to
start listening to its key change events. In practice this usually
happens at startup but we shouldn't rely on it, and it incurs higher
overhead since it creates a different listener for each conversation.

// FREEBIE
2017-05-09 15:41:41 -07:00

65 lines
2.6 KiB
JavaScript

/*
* 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();
messages.fetchSentAt(receipt.get('timestamp')).then(function() {
if (messages.length === 0) { return; }
var message = messages.find(function(message) {
return (!message.isIncoming() && receipt.get('source') === message.get('conversationId'));
});
if (message) { return message; }
var groups = new Whisper.GroupCollection();
return groups.fetchGroups(receipt.get('source')).then(function() {
var ids = groups.pluck('id');
ids.push(receipt.get('source'));
return messages.find(function(message) {
return (!message.isIncoming() &&
_.contains(ids, message.get('conversationId')));
});
});
}).then(function(message) {
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('delivered', message);
}
});
// TODO: consider keeping a list of numbers we've
// successfully delivered to?
}
}.bind(this));
}
}))();
})();