Move handlePushMessageContent to message model

And retool message handling flow to helps us avoid instantiating
duplicate message and conversation models.
This commit is contained in:
lilia 2015-03-18 16:26:55 -07:00
parent 897d391817
commit 9930937707
5 changed files with 98 additions and 112 deletions

View file

@ -17,8 +17,6 @@
;(function() {
'use strict';
var socket;
var conversations = new Whisper.ConversationCollection();
var messages = new Whisper.MessageCollection();
if (!localStorage.getItem('first_install_ran')) {
localStorage.setItem('first_install_ran', 1);
@ -80,13 +78,13 @@
var now = new Date().getTime();
var timestamp = pushMessage.timestamp.toNumber();
var conversation = conversations.add({
var conversation = getConversation({
id : pushMessage.source,
type : 'private'
}, { merge : true } );
});
conversation.fetch().always(function() {
var message = messages.add({
var message = conversation.messageCollection.add({
source : pushMessage.source,
sourceDevice : pushMessage.sourceDevice,
relay : pushMessage.relay,
@ -105,7 +103,7 @@
return new Promise(function(resolve) {
resolve(textsecure.protocol_wrapper.handleIncomingPushMessageProto(pushMessage).then(
function(pushMessageContent) {
handlePushMessageContent(pushMessageContent, message);
message.handlePushMessageContent(pushMessageContent);
}
));
}).catch(function(e) {
@ -129,101 +127,6 @@
});
}
extension.on('message:decrypted', function(options) {
var message = messages.add({id: options.message_id});
message.fetch().then(function() {
var pushMessageContent = handlePushMessageContent(
new textsecure.protobuf.PushMessageContent(options.data),
message
);
});
});
function getConversationId(pushMessageContent) {
if (pushMessageContent.sync) {
return pushMessageContent.sync.destination;
} else if (pushMessageContent.group) {
return pushMessageContent.group.id;
}
}
function handlePushMessageContent(pushMessageContent, message) {
// This function can be called from the background script on an
// incoming message or from the frontend after the user accepts an
// identity key change.
var source = message.get('source');
var timestamp = message.get('sent_at');
return textsecure.processDecrypted(pushMessageContent, source).then(function(pushMessageContent) {
var type = 'incoming';
if (pushMessageContent.sync) {
type = 'outgoing';
timestamp = pushMessageContent.sync.timestamp;
}
var now = new Date().getTime();
var conversationId = getConversationId(pushMessageContent) || source;
var conversation = new Whisper.Conversation({id: conversationId});
var attributes = {};
conversation.fetch().always(function() {
if (pushMessageContent.group) {
var group_update = {};
if (pushMessageContent.group.type === textsecure.protobuf.PushMessageContent.GroupContext.Type.UPDATE) {
attributes = {
type : 'group',
groupId : pushMessageContent.group.id,
name : pushMessageContent.group.name,
avatar : pushMessageContent.group.avatar,
members : pushMessageContent.group.members,
};
group_update = conversation.changedAttributes(_.pick(pushMessageContent.group, 'name', 'avatar'));
var difference = _.difference(pushMessageContent.group.members, conversation.get('members'));
if (difference.length > 0) {
group_update.joined = difference;
}
}
else if (pushMessageContent.group.type === textsecure.protobuf.PushMessageContent.GroupContext.Type.QUIT) {
group_update = { left: source };
attributes = { members: _.without(conversation.get('members'), source) };
}
if (_.keys(group_update).length > 0) {
message.set({group_update: group_update});
}
}
attributes.active_at = now;
if (type === 'incoming') {
attributes.unreadCount = conversation.get('unreadCount') + 1;
}
conversation.set(attributes);
message.set({
body : pushMessageContent.body,
conversationId : conversation.id,
attachments : pushMessageContent.attachments,
decrypted_at : now,
type : type,
sent_at : timestamp,
flags : pushMessageContent.flags,
errors : []
});
if (message.get('sent_at') > conversation.get('timestamp')) {
conversation.set({
timestamp: message.get('sent_at'),
lastMessage: message.get('body')
});
}
conversation.save().then(function() {
message.save().then(function() {
extension.trigger('message', message); // notify frontend listeners
notifyConversation(message);
});
});
});
});
}
function onDeliveryReceipt(pushMessage) {
var timestamp = pushMessage.timestamp.toNumber();
var messages = new Whisper.MessageCollection();

View file

@ -77,10 +77,7 @@
var promise = new textsecure.ReplayableError(error).replay();
if (this.isIncoming()) {
promise.then(function(pushMessageContent) {
extension.trigger('message:decrypted', {
message_id: this.id,
data: pushMessageContent
});
this.handlePushMessageContent(pushMessageContent);
this.save('errors', []);
}.bind(this)).catch(function(e) {
//this.save('errors', [_.pick(e, ['name', 'message'])]);
@ -98,7 +95,90 @@
}.bind(this));
}
}
},
handlePushMessageContent: function(pushMessageContent) {
// This function can be called from the background script on an
// incoming message or from the frontend after the user accepts an
// identity key change.
var message = this;
var source = message.get('source');
var timestamp = message.get('sent_at');
return textsecure.processDecrypted(pushMessageContent, source).then(function(pushMessageContent) {
var type = 'incoming';
if (pushMessageContent.sync) {
type = 'outgoing';
timestamp = pushMessageContent.sync.timestamp;
}
var now = new Date().getTime();
var conversationId = source;
if (pushMessageContent.sync) {
conversationId = pushMessageContent.sync.destination;
} else if (pushMessageContent.group) {
conversationId = pushMessageContent.group.id;
}
var conversation = new Whisper.Conversation({id: conversationId});
var attributes = {};
conversation.fetch().always(function() {
if (pushMessageContent.group) {
var group_update = {};
if (pushMessageContent.group.type === textsecure.protobuf.PushMessageContent.GroupContext.Type.UPDATE) {
attributes = {
type : 'group',
groupId : pushMessageContent.group.id,
name : pushMessageContent.group.name,
avatar : pushMessageContent.group.avatar,
members : pushMessageContent.group.members,
};
group_update = conversation.changedAttributes(_.pick(pushMessageContent.group, 'name', 'avatar'));
var difference = _.difference(pushMessageContent.group.members, conversation.get('members'));
if (difference.length > 0) {
group_update.joined = difference;
}
}
else if (pushMessageContent.group.type === textsecure.protobuf.PushMessageContent.GroupContext.Type.QUIT) {
group_update = { left: source };
attributes = { members: _.without(conversation.get('members'), source) };
}
if (_.keys(group_update).length > 0) {
message.set({group_update: group_update});
}
}
attributes.active_at = now;
if (type === 'incoming') {
attributes.unreadCount = conversation.get('unreadCount') + 1;
}
conversation.set(attributes);
message.set({
body : pushMessageContent.body,
conversationId : conversation.id,
attachments : pushMessageContent.attachments,
decrypted_at : now,
type : type,
sent_at : timestamp,
flags : pushMessageContent.flags,
errors : []
});
if (message.get('sent_at') > conversation.get('timestamp')) {
conversation.set({
timestamp: message.get('sent_at'),
lastMessage: message.get('body')
});
}
conversation.save().then(function() {
message.save().then(function() {
extension.trigger('message', message); // notify frontend listeners
notifyConversation(message);
});
});
});
});
}
});
Whisper.MessageCollection = Backbone.Collection.extend({

View file

@ -41,15 +41,15 @@
windowMap.remove('windowId', windowId);
}
function getConversation(modelId) {
var conversation = window.inbox.get(modelId) || {id: modelId};
conversation = conversations.add(conversation);
window.getConversation = function(attrs) {
var conversation = window.inbox.get(attrs.id) || attrs;
conversation = conversations.add(attrs);
return conversation;
}
};
window.notifyConversation = function(message) {
if (Whisper.Notifications.isEnabled()) {
var conversation = getConversation(message.get('conversationId'));
var conversation = getConversation({id: message.get('conversationId')});
conversation.fetch().then(function() {
var notification = new Notification(conversation.getTitle(), {
body: message.get('body'),
@ -60,13 +60,14 @@
openConversation(conversation.id);
};
});
conversation.fetchMessages();
} else {
openConversation(message.get('conversationId'));
}
};
window.openConversation = function openConversation (modelId) {
var conversation = getConversation(modelId);
var conversation = getConversation({id: modelId});
conversation.fetch().then(function() {
conversation.fetchContacts();
});

View file

@ -46,6 +46,8 @@
initialize: function(options) {
this.view = new Whisper.MessageView({model: this.model});
this.conversation = options.conversation;
this.listenTo(this.model, 'change', this.render);
},
events: {
'click .back': 'goBack',

View file

@ -21,7 +21,7 @@
tagName: 'div',
template: $('#message').html(),
initialize: function() {
this.listenTo(this.model, 'change:body', this.render);
this.listenTo(this.model, 'change:body change:errors', this.render);
this.listenTo(this.model, 'change:delivered', this.renderDelivered);
},
className: function() {