From 019a9d1fbc01ace3772b1d86fd14a52ce8bb1d1e Mon Sep 17 00:00:00 2001 From: lilia Date: Wed, 11 Mar 2015 12:06:19 -0700 Subject: [PATCH] Unread counts Update unreadCounts per-conversation on incoming messages. Render unread conversations with font-weigh: bold in the inbox view. To ensure that the inbox and conversation views remain in sync, the background page now ensures that the same models objects are used for both views. --- js/background.js | 3 +++ js/inbox_controller.js | 3 ++- js/models/conversations.js | 6 ++++++ js/panel_controller.js | 3 ++- js/views/conversation_list_item_view.js | 15 +++++++++++---- js/views/conversation_view.js | 11 ++++++++++- js/views/inbox_view.js | 2 ++ stylesheets/_index.scss | 8 ++++++++ stylesheets/manifest.css | 5 +++++ 9 files changed, 49 insertions(+), 7 deletions(-) diff --git a/js/background.js b/js/background.js index 8eea93b11b..441cc22440 100644 --- a/js/background.js +++ b/js/background.js @@ -194,6 +194,9 @@ } } attributes.active_at = now; + if (type === 'incoming') { + attributes.unreadCount = conversation.get('unreadCount') + 1; + } conversation.set(attributes); message.set({ diff --git a/js/inbox_controller.js b/js/inbox_controller.js index 86bbd6f509..77dfa22e97 100644 --- a/js/inbox_controller.js +++ b/js/inbox_controller.js @@ -29,9 +29,10 @@ } }); + inbox.on('change:active_at', inbox.sort); + function fetch() { window.inbox.fetch({ - reset: true, index: { name: 'inbox', // 'inbox' index on active_at order: 'desc' // ORDER timestamp DESC diff --git a/js/models/conversations.js b/js/models/conversations.js index b21af2018a..2fd7902ea3 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -139,6 +139,12 @@ return new Promise(function (resolve) { m.save().then(resolve(m)); }); }, + markRead: function() { + if (this.get('unreadCount') > 0) { + this.save({unreadCount: 0}); + } + }, + fetchMessages: function(options) { return this.messageCollection.fetchConversation(this.id, options); }, diff --git a/js/panel_controller.js b/js/panel_controller.js index e95d466b11..6ba5214741 100644 --- a/js/panel_controller.js +++ b/js/panel_controller.js @@ -42,7 +42,8 @@ } window.openConversation = function openConversation (modelId) { - var conversation = conversations.add({id: modelId}); + var conversation = window.inbox.get(modelId) || {id: modelId}; + conversation = conversations.add(conversation); conversation.fetch().then(function() { conversation.fetchContacts(); }); diff --git a/js/views/conversation_list_item_view.js b/js/views/conversation_list_item_view.js index a8452a42a3..b887183491 100644 --- a/js/views/conversation_list_item_view.js +++ b/js/views/conversation_list_item_view.js @@ -38,15 +38,22 @@ render: function() { this.$el.html( Mustache.render(this.template, { - contact_name: this.model.getTitle(), - last_message: this.model.get('lastMessage'), - last_message_timestamp: moment(this.model.get('timestamp')).format('MMM D'), - number: this.model.getNumber() + contact_name: this.model.getTitle(), + last_message: this.model.get('lastMessage'), + last_message_timestamp: moment(this.model.get('timestamp')).format('MMM D'), + number: this.model.getNumber() }) ); twemoji.parse(this.el, { base: '/components/twemoji/', size: 16 }); + var unread = this.model.get('unreadCount'); + if (unread > 0) { + this.$el.addClass('unread'); + } else { + this.$el.removeClass('unread'); + } + if (this.model.get('avatar')) { this.$el.find('.avatar').append( new Whisper.AttachmentView({model: this.model.get('avatar')}).render().el diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js index 8490c501a4..ec0d7f2448 100644 --- a/js/views/conversation_view.js +++ b/js/views/conversation_view.js @@ -56,10 +56,19 @@ 'click .new-group-update': 'newGroupUpdate', 'click .verify-identity': 'verifyIdentity', 'click .hamburger': 'toggleMenu', - 'click' : 'closeMenu', + 'click' : 'onClick', 'select .entry': 'messageDetail' }, + onClick: function(e) { + this.closeMenu(e); + this.markRead(e); + }, + + markRead: function(e) { + this.model.markRead(); + }, + verifyIdentity: function() { if (this.model.isPrivate()) { var number = this.model.id; diff --git a/js/views/inbox_view.js b/js/views/inbox_view.js index f4901b250c..89f2b68ee1 100644 --- a/js/views/inbox_view.js +++ b/js/views/inbox_view.js @@ -69,6 +69,8 @@ collection : bg.inbox }).render(); + this.inbox.listenTo(bg.inbox, 'sort', this.inbox.render); + new SocketView().render().$el.appendTo(this.$el.find('.socket-status')); window.addEventListener('beforeunload', function () { diff --git a/stylesheets/_index.scss b/stylesheets/_index.scss index 49f147d400..b4ec47e639 100644 --- a/stylesheets/_index.scss +++ b/stylesheets/_index.scss @@ -233,3 +233,11 @@ input.new-message { display: block; } } + +.conversations .unread .contact-details { + .contact-name, + .last-message, + .last-timestamp { + font-weight: bold; + } +} diff --git a/stylesheets/manifest.css b/stylesheets/manifest.css index e3c3cd3662..db9414df90 100644 --- a/stylesheets/manifest.css +++ b/stylesheets/manifest.css @@ -300,6 +300,11 @@ input.new-message { .settings-open .settings { display: block; } +.conversations .unread .contact-details .contact-name, +.conversations .unread .contact-details .last-message, +.conversations .unread .contact-details .last-timestamp { + font-weight: bold; } + .conversation { padding: 36px 0; }