diff --git a/js/models/conversations.js b/js/models/conversations.js index 8641dfd4..fc53d7f8 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -112,36 +112,51 @@ this.set({tokens: tokens}); }, + queueJob: function(callback) { + var previous = this.pending || Promise.resolve(); + var current = this.pending = previous.then(callback, callback); + + current.then(function() { + if (this.pending === current) { + delete this.pending; + } + }.bind(this)); + + return current; + }, + sendMessage: function(body, attachments) { - var now = Date.now(); - var message = this.messageCollection.add({ - body : body, - conversationId : this.id, - type : 'outgoing', - attachments : attachments, - sent_at : now, - received_at : now - }); - if (this.isPrivate()) { - message.set({destination: this.id}); - } - message.save(); + this.queueJob(function() { + var now = Date.now(); + var message = this.messageCollection.add({ + body : body, + conversationId : this.id, + type : 'outgoing', + attachments : attachments, + sent_at : now, + received_at : now + }); + if (this.isPrivate()) { + message.set({destination: this.id}); + } + message.save(); - this.save({ - unreadCount : 0, - active_at : now, - timestamp : now, - lastMessage : message.getNotificationText() - }); + this.save({ + unreadCount : 0, + active_at : now, + timestamp : now, + lastMessage : message.getNotificationText() + }); - var sendFunc; - if (this.get('type') == 'private') { - sendFunc = textsecure.messaging.sendMessageToNumber; - } - else { - sendFunc = textsecure.messaging.sendMessageToGroup; - } - message.send(sendFunc(this.get('id'), body, attachments, now)); + var sendFunc; + if (this.get('type') == 'private') { + sendFunc = textsecure.messaging.sendMessageToNumber; + } + else { + sendFunc = textsecure.messaging.sendMessageToGroup; + } + message.send(sendFunc(this.get('id'), body, attachments, now)); + }.bind(this)); }, isSearchable: function() { diff --git a/js/models/messages.js b/js/models/messages.js index deb10655..413c204c 100644 --- a/js/models/messages.js +++ b/js/models/messages.js @@ -267,92 +267,97 @@ conversationId = dataMessage.group.id; } var conversation = ConversationController.create({id: conversationId}); - conversation.fetch().always(function() { - var now = new Date().getTime(); - var attributes = { type: 'private' }; - if (dataMessage.group) { - var group_update = null; - attributes = { - type: 'group', - groupId: dataMessage.group.id, - }; - if (dataMessage.group.type === textsecure.protobuf.GroupContext.Type.UPDATE) { - attributes = { - type : 'group', - groupId : dataMessage.group.id, - name : dataMessage.group.name, - avatar : dataMessage.group.avatar, - members : dataMessage.group.members, - }; - group_update = conversation.changedAttributes(_.pick(dataMessage.group, 'name', 'avatar')) || {}; - var difference = _.difference(dataMessage.group.members, conversation.get('members')); - if (difference.length > 0) { - group_update.joined = difference; - } - } - else if (dataMessage.group.type === textsecure.protobuf.GroupContext.Type.QUIT) { - if (source == textsecure.storage.user.getNumber()) { - group_update = { left: "You" }; - } else { - group_update = { left: source }; - } - attributes.members = _.without(conversation.get('members'), source); - } + conversation.queueJob(function() { + return new Promise(function(resolve) { + conversation.fetch().always(function() { + var now = new Date().getTime(); + var attributes = { type: 'private' }; + if (dataMessage.group) { + var group_update = null; + attributes = { + type: 'group', + groupId: dataMessage.group.id, + }; + if (dataMessage.group.type === textsecure.protobuf.GroupContext.Type.UPDATE) { + attributes = { + type : 'group', + groupId : dataMessage.group.id, + name : dataMessage.group.name, + avatar : dataMessage.group.avatar, + members : dataMessage.group.members, + }; + group_update = conversation.changedAttributes(_.pick(dataMessage.group, 'name', 'avatar')) || {}; + var difference = _.difference(dataMessage.group.members, conversation.get('members')); + if (difference.length > 0) { + group_update.joined = difference; + } + } + else if (dataMessage.group.type === textsecure.protobuf.GroupContext.Type.QUIT) { + if (source == textsecure.storage.user.getNumber()) { + group_update = { left: "You" }; + } else { + group_update = { left: source }; + } + attributes.members = _.without(conversation.get('members'), source); + } + + if (group_update !== null) { + message.set({group_update: group_update}); + } + } + 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); + message.set({ + delivered: (message.get('delivered') || 0) + 1 + }); + }); + } + attributes.active_at = now; + if (type === 'incoming') { + attributes.unreadCount = conversation.get('unreadCount') + 1; + } + conversation.set(attributes); - if (group_update !== null) { - message.set({group_update: group_update}); - } - } - 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); message.set({ - delivered: (message.get('delivered') || 0) + 1 + body : dataMessage.body, + conversationId : conversation.id, + attachments : dataMessage.attachments, + decrypted_at : now, + flags : dataMessage.flags, + errors : [] }); - }); - } - attributes.active_at = now; - if (type === 'incoming') { - attributes.unreadCount = conversation.get('unreadCount') + 1; - } - conversation.set(attributes); - message.set({ - body : dataMessage.body, - conversationId : conversation.id, - attachments : dataMessage.attachments, - decrypted_at : now, - flags : dataMessage.flags, - errors : [] - }); + var conversation_timestamp = conversation.get('timestamp'); + if (!conversation_timestamp || message.get('sent_at') > conversation_timestamp) { + conversation.set({ + timestamp: message.get('sent_at'), + lastMessage: message.getNotificationText() + }); + } + else if (!conversation.get('lastMessage')) { + conversation.set({ + lastMessage: message.getNotificationText() + }); + } - var conversation_timestamp = conversation.get('timestamp'); - if (!conversation_timestamp || message.get('sent_at') > conversation_timestamp) { - conversation.set({ - timestamp: message.get('sent_at'), - lastMessage: message.getNotificationText() - }); - } - else if (!conversation.get('lastMessage')) { - conversation.set({ - lastMessage: message.getNotificationText() - }); - } - - message.save().then(function() { - conversation.save().then(function() { - conversation.trigger('newmessage', message); - conversation.notify(message); + message.save().then(function() { + conversation.save().then(function() { + conversation.trigger('newmessage', message); + conversation.notify(message); + resolve(); + }); + }); }); }); });