Serialize sending and adding messages to a convo
Previously, if a message was sent in between the receive time of an incoming message and the time it is actually added to the conversation's message collection (which only occurs later after several async callbacks), the incoming message would be inserted not-at-the-end of the collection since it is ordered by receive time. This tricked the front end into assuming the message was an older message instead of a new one. Fixes #490 // FREEBIE
This commit is contained in:
parent
f9a3c7817e
commit
762cb68721
2 changed files with 128 additions and 108 deletions
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue