Merge Whisper.Messages into Whisper Threads

Eliminates the global Whisper.Messages object and consolidates shared
send/receive logic in Whisper.Threads.

To the latter end, note that the decrypted array buffer on an attachment
pointer is now named data instead of decrypted, in order to match the
format of outgoing attachments presented by
FileReader.readAsArrayBuffers and let us use the same handler to base64
encode them.
pull/749/head
lilia 11 years ago
parent 5a0e199fc5
commit 735737f0bc

@ -24,7 +24,7 @@
} else { } else {
if (textsecure.registration.isDone()) { if (textsecure.registration.isDone()) {
textsecure.subscribeToPush(function(message) { textsecure.subscribeToPush(function(message) {
Whisper.Messages.addIncomingMessage(message).then(function() { Whisper.Threads.addIncomingMessage(message).then(function() {
console.log("Got message from " + message.pushMessage.source + "." + message.pushMessage.sourceDevice + console.log("Got message from " + message.pushMessage.source + "." + message.pushMessage.sourceDevice +
': "' + getString(message.message.body) + '"'); ': "' + getString(message.message.body) + '"');
var newUnreadCount = textsecure.storage.getUnencrypted("unreadCount", 0) + 1; var newUnreadCount = textsecure.storage.getUnencrypted("unreadCount", 0) + 1;

@ -269,7 +269,7 @@ window.textsecure.subscribeToPush = function(message_callback) {
var handleAttachment = function(attachment) { var handleAttachment = function(attachment) {
return textsecure.api.getAttachment(attachment.id.toString()).then(function(encryptedBin) { return textsecure.api.getAttachment(attachment.id.toString()).then(function(encryptedBin) {
return textsecure.protocol.decryptAttachment(encryptedBin, attachment.key.toArrayBuffer()).then(function(decryptedBin) { return textsecure.protocol.decryptAttachment(encryptedBin, attachment.key.toArrayBuffer()).then(function(decryptedBin) {
attachment.decrypted = decryptedBin; attachment.data = decryptedBin;
}); });
}); });
}; };

@ -22,45 +22,4 @@ var Whisper = Whisper || {};
this.localStorage = new Backbone.LocalStorage("Messages-" + options.threadId); this.localStorage = new Backbone.LocalStorage("Messages-" + options.threadId);
} }
}); });
Whisper.Messages = new (Backbone.Collection.extend({
localStorage: new Backbone.LocalStorage("Messages"),
model: Message,
comparator: 'timestamp',
addIncomingMessage: function(decrypted) {
//TODO: The data in decrypted (from subscribeToPush) should already be cleaned up
return Promise.all(decrypted.message.attachments.map(function(a) {
return new Promise(function(resolve, reject) {
var dataView = new DataView(a.decrypted);
var blob = new Blob([dataView], { type: a.contentType });
var FR = new FileReader();
FR.onload = function(e) {
resolve(e.target.result);
};
FR.onerror = reject;
FR.readAsDataURL(blob);
});
})).then(function(base64_attachments) {
var thread = Whisper.Threads.findOrCreateForIncomingMessage(decrypted);
var timestamp = decrypted.pushMessage.timestamp.toNumber();
var m = thread.messages().add({
person: decrypted.pushMessage.source,
threadId: thread.id,
body: decrypted.message.body,
attachments: base64_attachments,
type: 'incoming',
timestamp: timestamp
});
m.save();
if (timestamp > thread.get('timestamp')) {
thread.set('timestamp', timestamp);
}
thread.save({unreadCount: thread.get('unreadCount') + 1, active: true});
return m;
});
}
}))();
})() })()

@ -3,6 +3,20 @@ var Whisper = Whisper || {};
(function () { (function () {
'use strict'; 'use strict';
function encodeAttachments (attachments) {
return Promise.all(attachments.map(function(a) {
return new Promise(function(resolve, reject) {
var dataView = new DataView(a.data);
var blob = new Blob([dataView], { type: a.contentType });
var FR = new FileReader();
FR.onload = function(e) {
resolve(e.target.result);
};
FR.onerror = reject;
FR.readAsDataURL(blob);
});
}));
};
var Thread = Backbone.Model.extend({ var Thread = Backbone.Model.extend({
defaults: function() { defaults: function() {
@ -22,20 +36,8 @@ var Whisper = Whisper || {};
}, },
sendMessage: function(message, attachments) { sendMessage: function(message, attachments) {
return Promise.all(attachments.map(function(a) { encodeAttachments(attachments).then(function(base64_attachments) {
return new Promise(function(resolve, reject) {
var dataView = new DataView(a.data);
var blob = new Blob([dataView], { type: a.contentType });
var FR = new FileReader();
FR.onload = function(e) {
resolve(e.target.result);
};
FR.onerror = reject;
FR.readAsDataURL(blob);
});
})).then(function(base64_attachments) {
var timestamp = Date.now(); var timestamp = Date.now();
this.messages().add({ type: 'outgoing', this.messages().add({ type: 'outgoing',
body: message, body: message,
threadId: this.id, threadId: this.id,
@ -59,6 +61,28 @@ var Whisper = Whisper || {};
}); });
}, },
receiveMessage: function(decrypted) {
var thread = this;
encodeAttachments(decrypted.message.attachments).then(function(base64_attachments) {
var timestamp = decrypted.pushMessage.timestamp.toNumber();
var m = this.messages().add({
person: decrypted.pushMessage.source,
threadId: this.id,
body: decrypted.message.body,
attachments: base64_attachments,
type: 'incoming',
timestamp: timestamp
});
m.save();
if (timestamp > this.get('timestamp')) {
this.set('timestamp', timestamp);
}
this.save({unreadCount: this.get('unreadCount') + 1, active: true});
return m;
}.bind(this));
},
messages: function() { messages: function() {
if (!this.messageCollection) { if (!this.messageCollection) {
this.messageCollection = new Whisper.MessageCollection([], {threadId: this.id}); this.messageCollection = new Whisper.MessageCollection([], {threadId: this.id});
@ -124,7 +148,11 @@ var Whisper = Whisper || {};
}; };
} }
return this.findOrCreate(attributes); return this.findOrCreate(attributes);
} },
addIncomingMessage: function(decrypted) {
var thread = Whisper.Threads.findOrCreateForIncomingMessage(decrypted);
thread.receiveMessage(decrypted);
}
}))(); }))();
})(); })();

Loading…
Cancel
Save