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 8eea93b11b0f..441cc224402f 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 86bbd6f509be..77dfa22e97d4 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 b21af2018aed..2fd7902ea306 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 e95d466b1138..6ba521474136 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 a8452a42a3ec..b8871834910c 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 8490c501a412..ec0d7f24480a 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 f4901b250cc4..89f2b68ee193 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 49f147d4001d..b4ec47e639e1 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 e3c3cd36623e..db9414df9093 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; }