From d52db8fe6fe66a646bf7107df6b56841ffa783c6 Mon Sep 17 00:00:00 2001 From: lilia Date: Fri, 9 Jan 2015 12:53:39 -1000 Subject: [PATCH] Render group updates Not pretty, but it works. Also allows for later localization. Copy/behavior is borrowed from the Android client. Closes #104 Fixes #65 --- index.html | 1 + js/background.js | 8 ++++ js/views/group_update_view.js | 40 +++++++++++++++++++ js/views/message_view.js | 60 ++++++++++++++++------------ test/index.html | 2 + test/views/group_update_view_test.js | 16 ++++++++ 6 files changed, 102 insertions(+), 25 deletions(-) create mode 100644 js/views/group_update_view.js create mode 100644 test/views/group_update_view_test.js diff --git a/index.html b/index.html index 5ddea75e..1f1ea90f 100644 --- a/index.html +++ b/index.html @@ -155,6 +155,7 @@ + diff --git a/js/background.js b/js/background.js index 63caefcf..94bdc9f0 100644 --- a/js/background.js +++ b/js/background.js @@ -138,6 +138,14 @@ avatar : pushMessageContent.group.avatar, members : pushMessageContent.group.members, }; + var 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; + } + if (_.keys(group_update).length > 0) { + message.set({group_update: group_update}); + } } attributes.active_at = now; conversation.set(attributes); diff --git a/js/views/group_update_view.js b/js/views/group_update_view.js new file mode 100644 index 00000000..7f3bde17 --- /dev/null +++ b/js/views/group_update_view.js @@ -0,0 +1,40 @@ +/* vim: ts=4:sw=4:expandtab + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +(function () { + 'use strict'; + + window.Whisper = window.Whisper || {}; + + Whisper.GroupUpdateView = Backbone.View.extend({ + tagName: "div", + className: "group-update", + render: function() { + //TODO l10n + var messages = ['Updated the group.']; + if (this.model.name) { + messages.push("Title is now '" + this.model.name + "'."); + } + if (this.model.joined) { + messages.push(this.model.joined + ' joined the group'); + } + + this.$el.text(messages.join(' ')); + + return this; + } + }); + +})(); diff --git a/js/views/message_view.js b/js/views/message_view.js index a64cf8d5..ab9d1c0e 100644 --- a/js/views/message_view.js +++ b/js/views/message_view.js @@ -61,7 +61,13 @@ initialize: function() { this.$el.addClass(this.model.get('type')); - this.template = $('#message').html(); + if (this.model.get('group_update')) { + this.group_update_view = new Whisper.GroupUpdateView({ + model: this.model.get('group_update') + }).render(); + } else { + this.template = $('#message').html(); + } Mustache.parse(this.template); this.listenTo(this.model, 'change', this.render); // auto update @@ -70,32 +76,36 @@ }, render: function() { - this.$el.html( - Mustache.render(this.template, { - message: this.model.get('body'), - timestamp: moment(this.model.get('received_at')).fromNow(), - bubble_class: this.model.get('type') === 'outgoing' ? 'sent' : 'incoming', - sender: this.model.get('source') - }) - ); - - this.$el.find('.attachments').append( - this.model.get('attachments').map(function(attachment) { - return new AttachmentView({model: attachment}).render().el; - }) - ); - - if (this.model.get('delivered')) { - this.$el.addClass('delivered'); - } - - var errors = this.model.get('errors'); - if (errors && errors.length) { - this.$el.find('.message').append( - errors.map(function(error) { - return new ErrorView({model: error}).render().el; + if (this.group_update_view) { + this.$el.append(this.group_update_view.$el); + } else { + this.$el.html( + Mustache.render(this.template, { + message: this.model.get('body'), + timestamp: moment(this.model.get('received_at')).fromNow(), + bubble_class: this.model.get('type') === 'outgoing' ? 'sent' : 'incoming', + sender: this.model.get('source') }) ); + + this.$el.find('.attachments').append( + this.model.get('attachments').map(function(attachment) { + return new AttachmentView({model: attachment}).render().el; + }) + ); + + if (this.model.get('delivered')) { + this.$el.addClass('delivered'); + } + + var errors = this.model.get('errors'); + if (errors && errors.length) { + this.$el.find('.message').append( + errors.map(function(error) { + return new ErrorView({model: error}).render().el; + }) + ); + } } return this; diff --git a/test/index.html b/test/index.html index 15bc3e98..b97d1f1b 100644 --- a/test/index.html +++ b/test/index.html @@ -149,6 +149,7 @@ + @@ -164,6 +165,7 @@ + diff --git a/test/views/group_update_view_test.js b/test/views/group_update_view_test.js new file mode 100644 index 00000000..e49eeed6 --- /dev/null +++ b/test/views/group_update_view_test.js @@ -0,0 +1,16 @@ +describe('GroupUpdateView', function() { + it('should show new group members', function() { + var view = new Whisper.GroupUpdateView({model: {joined: ['Alice', 'Bob']}}).render(); + assert.match(view.$el.text(), /Alice.*Bob.*joined the group/); + }); + + it('should note updates to the title', function() { + var view = new Whisper.GroupUpdateView({model: {name: 'New name'}}).render(); + assert.match(view.$el.text(), /Title is now 'New name'/); + }); + + it('should say "Updated the group"', function() { + var view = new Whisper.GroupUpdateView({model: {avatar: 'New avatar'}}).render(); + assert.match(view.$el.text(), /Updated the group/); + }); +});