diff --git a/js/background.js b/js/background.js
index cb533395e..8ac625d36 100644
--- a/js/background.js
+++ b/js/background.js
@@ -25,7 +25,9 @@
if (textsecure.registration.isDone()) {
var conversations = new Whisper.ConversationCollection();
textsecure.subscribeToPush(function(message) {
- conversations.addIncomingMessage(message);
+ conversations.addIncomingMessage(message).then(function(message) {
+ extension.trigger('message', message);
+ });
console.log("Got message from " + message.pushMessage.source + "." + message.pushMessage.sourceDevice +
': "' + getString(message.message.body) + '"');
var newUnreadCount = textsecure.storage.getUnencrypted("unreadCount", 0) + 1;
diff --git a/js/chromium.js b/js/chromium.js
index d03d08eb7..42ac9738c 100644
--- a/js/chromium.js
+++ b/js/chromium.js
@@ -16,6 +16,7 @@
*/
(function () {
'use strict';
+ // Browser specific functions for Chrom*
window.extension = window.extension || {};
window.extension.navigator = (function () {
@@ -33,7 +34,17 @@
return self;
}());
- // Random shared utilities that are used only by chromium things
+ window.extension.trigger = function (name, object) {
+ chrome.runtime.sendMessage(null, { name: name, data: object });
+ };
+
+ window.extension.onMessage = function (name, callback) {
+ chrome.runtime.onMessage.addListener(function(e) {
+ if (e.name === name) {
+ callback(e.data);
+ }
+ });
+ };
window.textsecure = window.textsecure || {};
window.textsecure.registration = {
diff --git a/js/models/conversations.js b/js/models/conversations.js
index 70d3cbd59..b83173122 100644
--- a/js/models/conversations.js
+++ b/js/models/conversations.js
@@ -86,7 +86,7 @@
receiveMessage: function(decrypted) {
var conversation = this;
- encodeAttachments(decrypted.message.attachments).then(function(base64_attachments) {
+ return encodeAttachments(decrypted.message.attachments).then(function(base64_attachments) {
var timestamp = decrypted.pushMessage.timestamp.toNumber();
var m = this.messages().add({
body: decrypted.message.body,
@@ -97,18 +97,20 @@
type: 'incoming',
sender: decrypted.pushMessage.source
});
- m.save();
if (timestamp > this.get('timestamp')) {
this.set('timestamp', timestamp);
}
this.save({unreadCount: this.get('unreadCount') + 1, active: true});
- return m;
+
+ return new Promise(function (resolve) { m.save().then(resolve) });
}.bind(this));
},
- fetch: function() {
- return this.messageCollection.fetch({conditions: {conversationId: this.id }});
+ fetch: function(options) {
+ options = options || {};
+ options.conditions = {conversationId: this.id };
+ return this.messageCollection.fetch(options);
},
messages: function() {
@@ -171,7 +173,7 @@
};
}
var conversation = this.add(attributes, {merge: true});
- conversation.receiveMessage(decrypted);
+ return conversation.receiveMessage(decrypted);
},
destroyAll: function () {
diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js
index 8cb3fde80..92ff5ec24 100644
--- a/js/views/conversation_view.js
+++ b/js/views/conversation_view.js
@@ -18,47 +18,50 @@ var Whisper = Whisper || {};
(function () {
'use strict';
- Whisper.ConversationView = Backbone.View.extend({
- className: 'conversation',
- initialize: function() {
- this.listenTo(this.model, 'destroy', this.stopListening); // auto update
- this.template = $('#conversation').html();
- Mustache.parse(this.template);
- this.$el.html(Mustache.render(this.template));
+ Whisper.ConversationView = Backbone.View.extend({
+ className: 'conversation',
+ initialize: function() {
+ this.listenTo(this.model, 'destroy', this.stopListening); // auto update
+ this.template = $('#conversation').html();
+ Mustache.parse(this.template);
+ this.$el.html(Mustache.render(this.template));
- this.view = new Whisper.MessageListView({collection: this.model.messages()});
+ this.fileInput = new Whisper.FileInputView({
+ el: this.$el.find('.attachments')
+ });
- this.fileInput = new Whisper.FileInputView({el: this.$el.find('.attachments')});
+ this.view = new Whisper.MessageListView({
+ collection: this.model.messages()
+ });
+ this.$el.find('.discussion-container').append(this.view.el);
- this.model.messages().fetch({reset: true});
- this.$el.find('.discussion-container').append(this.view.el);
- window.addEventListener('storage', (function(){
- this.model.messages().fetch();
- }).bind(this));
- },
- events: {
- 'submit .send': 'sendMessage',
- 'close': 'remove'
- },
+ this.model.fetch({reset: true});
+ extension.onMessage('message', this.model.fetch.bind(this.model));
+ },
- sendMessage: function(e) {
- e.preventDefault();
- var input = this.$el.find('.send input');
- var message = input.val();
- var convo = this.model;
+ events: {
+ 'submit .send': 'sendMessage',
+ 'close': 'remove'
+ },
- if (message.length > 0 || this.fileInput.hasFiles()) {
- this.fileInput.getFiles().then(function(attachments) {
- convo.sendMessage(message, attachments);
- });
- input.val("");
- }
- },
+ sendMessage: function(e) {
+ e.preventDefault();
+ var input = this.$el.find('.send input');
+ var message = input.val();
+ var convo = this.model;
- render: function() {
- Whisper.Layout.setContent(this.$el.show());
- this.view.scrollToBottom();
- return this;
- }
- });
+ if (message.length > 0 || this.fileInput.hasFiles()) {
+ this.fileInput.getFiles().then(function(attachments) {
+ convo.sendMessage(message, attachments);
+ });
+ input.val("");
+ }
+ },
+
+ render: function() {
+ Whisper.Layout.setContent(this.$el.show());
+ this.view.scrollToBottom();
+ return this;
+ }
+ });
})();
diff --git a/js/views/message_list_view.js b/js/views/message_list_view.js
index 8e754ee3c..18f727918 100644
--- a/js/views/message_list_view.js
+++ b/js/views/message_list_view.js
@@ -18,7 +18,7 @@ var Whisper = Whisper || {};
this.collection.each(function(model) {
var view = new this.itemView({model: model});
this.$el.prepend(view.render().el);
- });
+ }, this);
},
});
})();
diff --git a/test/_test.js b/test/_test.js
index 6c8233aea..a7386e316 100644
--- a/test/_test.js
+++ b/test/_test.js
@@ -83,3 +83,23 @@ function hexToArrayBuffer(str) {
array[i] = parseInt(str.substr(i*2, 2), 16);
return ret;
};
+
+function deleteDatabase(done) {
+ indexedDB.deleteDatabase('test').then(done);
+};
+
+function clearDatabase(done) {
+ var convos = new Whisper.ConversationCollection();
+ return convos.fetch().then(function() {
+ convos.destroyAll().then(function() {
+ var messages = new Whisper.MessageCollection();
+ return messages.fetch().then(function() {
+ messages.destroyAll().then(function() {
+ if (done) {
+ done();
+ }
+ });
+ });
+ });
+ });
+}
diff --git a/test/index.html b/test/index.html
index 9d07a348e..715a2ae58 100644
--- a/test/index.html
+++ b/test/index.html
@@ -135,8 +135,8 @@
-
-
+
+
@@ -162,6 +162,7 @@
+
diff --git a/test/models/conversations_test.js b/test/models/conversations_test.js
index c2e55e606..d5f3c175b 100644
--- a/test/models/conversations_test.js
+++ b/test/models/conversations_test.js
@@ -16,20 +16,6 @@
(function () {
'use strict';
- function clear(done) {
- var convos = new Whisper.ConversationCollection();
- return convos.fetch().then(function() {
- convos.destroyAll().then(function() {
- var messages = new Whisper.MessageCollection();
- return messages.fetch().then(function() {
- messages.destroyAll().then(function() {
- done();
- });
- });
- });
- });
- }
-
var attributes = { type: 'outgoing',
body: 'hi',
conversationId: 'foo',
@@ -37,8 +23,8 @@
timestamp: new Date().getTime() };
describe('ConversationCollection', function() {
- before(clear);
- after(clear);
+ before(clearDatabase);
+ after(clearDatabase);
it('adds without saving', function() {
var convos = new Whisper.ConversationCollection();
@@ -107,7 +93,7 @@
message.save().then(done)
});
});
- after(clear);
+ after(clearDatabase);
it('contains its own messages', function (done) {
var convo = new Whisper.ConversationCollection().add({id: 'foobar'});
@@ -124,26 +110,6 @@
done();
});
});
-
- it('has most recent messages first', function(done) {
- var convo = new Whisper.ConversationCollection().add({id: 'barfoo'});
- convo.messages().add({
- body: 'first message',
- conversationId: convo.id,
- timestamp: new Date().getTime() - 5000
- }).save().then(function() {
- convo.messages().add({
- body: 'second message',
- conversationId: convo.id
- }).save().then(function() {
- convo.fetch().then(function() {
- assert.strictEqual(convo.messages().at(0).get('body'), 'second message');
- assert.strictEqual(convo.messages().at(1).get('body'), 'first message');
- done();
- });
- });
- });
- });
});
})();;
diff --git a/test/test.js b/test/test.js
index 12ff306f0..fac62ce7c 100644
--- a/test/test.js
+++ b/test/test.js
@@ -10957,3 +10957,23 @@ function hexToArrayBuffer(str) {
array[i] = parseInt(str.substr(i*2, 2), 16);
return ret;
};
+
+function deleteDatabase(done) {
+ indexedDB.deleteDatabase('test').then(done);
+};
+
+function clearDatabase(done) {
+ var convos = new Whisper.ConversationCollection();
+ return convos.fetch().then(function() {
+ convos.destroyAll().then(function() {
+ var messages = new Whisper.MessageCollection();
+ return messages.fetch().then(function() {
+ messages.destroyAll().then(function() {
+ if (done) {
+ done();
+ }
+ });
+ });
+ });
+ });
+}