From 5949ca9e366135d9765a9ddc15a0a81ccfa1e535 Mon Sep 17 00:00:00 2001 From: JC Brand Date: Mon, 5 Jun 2017 14:50:29 +0200 Subject: [PATCH] Show number of unread messages on the "Rooms" tab --- css/converse.css | 31 +++++++++---------- dev.html | 10 +++---- sass/_controlbox.scss | 14 +++++++++ sass/_roomslist.scss | 8 +---- sass/_roster.scss | 11 ++----- spec/chatbox.js | 10 +++---- spec/chatroom.js | 39 ++++++++++++++++++++++++ spec/controlbox.js | 2 +- spec/roomslist.js | 6 ++-- src/converse-muc.js | 48 +++++++++++++++++------------- src/templates/chatrooms_tab.html | 9 ++++-- src/templates/rooms_list_item.html | 2 +- src/templates/roster_item.html | 2 +- 13 files changed, 120 insertions(+), 72 deletions(-) diff --git a/css/converse.css b/css/converse.css index e8bf3e47c..250438867 100644 --- a/css/converse.css +++ b/css/converse.css @@ -1905,6 +1905,14 @@ padding: 0 0 5px 5px; } #conversejs #controlbox form.search-xmpp-contact input { width: 8em; } + #conversejs #controlbox .msgs-indicator { + background-color: #D24E2B; + color: white; + font-size: 12px; + float: right; + font-weight: normal; + padding: 0 4px; + text-shadow: none; } #conversejs #controlbox a.subscribe-to-user { padding-left: 2em; font-weight: bold; } @@ -2091,6 +2099,8 @@ height: 55px; cursor: default; color: #818479; } + #conversejs #controlbox #controlbox-tabs li a .msgs-indicator { + border-top-right-radius: 4px; } #conversejs #controlbox .fancy-dropdown { border: 1px solid #B1BFC4; height: 25px; @@ -2193,14 +2203,8 @@ #conversejs #controlbox .available-chatroom .pulse { padding: 0; margin: 0; } -#conversejs #controlbox .available-chatroom.unread-msgs .msgs-indicactor { - background-color: #D24E2B; - color: white; - border-radius: 10%; - font-size: 12px; - font-weight: normal; - padding: 0 4px; - text-shadow: none; } +#conversejs #controlbox .available-chatroom.unread-msgs .msgs-indicator { + border-radius: 10%; } #conversejs #converse-roster { text-align: left; @@ -2328,16 +2332,9 @@ opacity: 0; } #conversejs #converse-roster .roster-contacts dd .open-chat.unread-msgs .avatar.avatar-online .pulse { border: 0.7em solid #2A9D8F; } - #conversejs #converse-roster .roster-contacts dd .open-chat .msgs-indicactor { - background-color: #D24E2B; - color: white; - border-radius: 10%; - float: right; - font-size: 11px; + #conversejs #converse-roster .roster-contacts dd .open-chat .msgs-indicator { margin-left: -3em; - font-weight: normal; - padding: 0 4px; - text-shadow: none; } + border-radius: 10%; } #conversejs #converse-roster .roster-contacts dd .open-chat .contact-name { padding: 0; margin: 0; diff --git a/dev.html b/dev.html index 58c52a55a..f5cc1df74 100644 --- a/dev.html +++ b/dev.html @@ -55,11 +55,11 @@ converse.initialize({ auto_away: 300, i18n: locales['af'], - auto_join_rooms: [ - 'discuss@conference.conversejs.org', - 'prosody@conference.prosody.im', - 'jdev@conference.jabber.org' - ], + // auto_join_rooms: [ + // 'discuss@conference.conversejs.org', + // 'prosody@conference.prosody.im', + // 'jdev@conference.jabber.org' + // ], notify_all_room_messages: [ 'discuss@conference.conversejs.org' ], diff --git a/sass/_controlbox.scss b/sass/_controlbox.scss index bb6fee6bd..c12bd9da0 100644 --- a/sass/_controlbox.scss +++ b/sass/_controlbox.scss @@ -32,6 +32,17 @@ width: 8em; } } + + .msgs-indicator { + background-color: $warning-color; + color: white; + font-size: $font-size-small; + float: right; + font-weight: normal; + padding: 0 4px; + text-shadow: none; + } + a.subscribe-to-user { padding-left: 2em; font-weight: bold; @@ -288,6 +299,9 @@ cursor: default; color: $text-color; } + .msgs-indicator { + border-top-right-radius: $chatbox-border-radius; + } } } } diff --git a/sass/_roomslist.scss b/sass/_roomslist.scss index 663a19c67..22006d38f 100644 --- a/sass/_roomslist.scss +++ b/sass/_roomslist.scss @@ -6,14 +6,8 @@ margin: 0; } &.unread-msgs { - .msgs-indicactor { - background-color: $warning-color; - color: white; + .msgs-indicator { border-radius: 10%; - font-size: $font-size-small; - font-weight: normal; - padding: 0 4px; - text-shadow: none; } } } diff --git a/sass/_roster.scss b/sass/_roster.scss index 911e840dd..613a3ca9b 100644 --- a/sass/_roster.scss +++ b/sass/_roster.scss @@ -154,16 +154,9 @@ } } - .msgs-indicactor { - background-color: $warning-color; - color: white; - border-radius: 10%; - float: right; - font-size: 11px; + .msgs-indicator { margin-left: -3em; - font-weight: normal; - padding: 0 4px; - text-shadow: none; + border-radius: 10%; } .contact-name { diff --git a/spec/chatbox.js b/spec/chatbox.js index d6c47d1bc..097bae69b 100644 --- a/spec/chatbox.js +++ b/spec/chatbox.js @@ -1995,7 +1995,7 @@ var msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread'); _converse.chatboxes.onMessage(msg); - var msgIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicactor', + var msgIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator', $msgIndicator = $(_converse.rosterview.$el.find(msgIndicatorSelector)); expect($msgIndicator.text()).toBe('1'); @@ -2026,7 +2026,7 @@ var msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread'); _converse.chatboxes.onMessage(msg); - var msgIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicactor', + var msgIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator', $msgIndicator = $(_converse.rosterview.$el.find(msgIndicatorSelector)); expect($msgIndicator.text()).toBe('1'); @@ -2052,7 +2052,7 @@ test_utils.openChatBoxFor(_converse, sender_jid); var chatbox = _converse.chatboxes.get(sender_jid); var chatboxview = _converse.chatboxviews.get(sender_jid); - var msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicactor'; + var msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator'; var selectMsgsIndicator = function () { return $(_converse.rosterview.$el.find(msgsIndicatorSelector)); }; var msgFactory = function () { return test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read'); @@ -2087,7 +2087,7 @@ var msgFactory = function () { return test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read'); }; - var msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicactor', + var msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator', selectMsgsIndicator = function () { return $(_converse.rosterview.$el.find(msgsIndicatorSelector)); }; chatbox.save('scrolled', true); @@ -2117,7 +2117,7 @@ var msgFactory = function () { return test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read'); }; - var msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicactor', + var msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator', selectMsgsIndicator = function () { return $(_converse.rosterview.$el.find(msgsIndicatorSelector)); }; chatbox.save('scrolled', true); diff --git a/spec/chatroom.js b/spec/chatroom.js index e2d645a0d..671d082d7 100644 --- a/spec/chatroom.js +++ b/spec/chatroom.js @@ -2061,5 +2061,44 @@ expect(delta.length).toBe(0); })); }); + + describe("The \"Rooms\" Panel", function () { + + it("shows the number of unread mentions received", mock.initConverse(function (_converse) { + var room_jid = 'kitchen@conference.shakespeare.lit'; + test_utils.openAndEnterChatRoom( + _converse, 'kitchen', 'conference.shakespeare.lit', 'fires'); + test_utils.openContactsPanel(_converse); + var roomspanel = _converse.chatboxviews.get('controlbox').roomspanel; + var view = _converse.chatboxviews.get(room_jid); + view.model.set({'minimized': true}); + + var contact_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost'; + var message = 'fires: Your attention is required'; + var nick = mock.chatroom_names[0], + msg = $msg({ + from: room_jid+'/'+nick, + id: (new Date()).getTime(), + to: 'dummy@localhost', + type: 'groupchat' + }).c('body').t(message).tree(); + view.handleMUCMessage(msg); + + expect(_.includes(roomspanel.tab_el.firstChild.classList, 'unread-msgs')).toBeTruthy(); + expect(roomspanel.tab_el.querySelector('.msgs-indicator').textContent).toBe('1'); + + msg = $msg({ + from: room_jid+'/'+nick, + id: (new Date()).getTime(), + to: 'dummy@localhost', + type: 'groupchat' + }).c('body').t(message).tree(); + view.handleMUCMessage(msg); + expect(roomspanel.tab_el.querySelector('.msgs-indicator').textContent).toBe('2'); + + view.model.set({'minimized': false}); + expect(_.includes(roomspanel.tab_el.firstChild.classList, 'unread-msgs')).toBeFalsy(); + })); + }); }); })); diff --git a/spec/controlbox.js b/spec/controlbox.js index 1e6b99763..0b972602d 100644 --- a/spec/controlbox.js +++ b/spec/controlbox.js @@ -1172,7 +1172,7 @@ it("can list rooms publically available on the server", mock.initConverse(function (_converse) { test_utils.openControlBox(); var panel = _converse.chatboxviews.get('controlbox').roomspanel; - panel.$tabs.find('li').last().find('a').click(); // Click the chatrooms tab + $(panel.tabs).find('li').last().find('a').click(); // Click the chatrooms tab panel.model.set({'muc_domain': 'muc.localhost'}); // Make sure the domain is set // See: http://xmpp.org/extensions/xep-0045.html#disco-rooms expect($('#available-chatrooms').children('dt').length).toBe(0); diff --git a/spec/roomslist.js b/spec/roomslist.js index 33a6db228..797484b31 100644 --- a/spec/roomslist.js +++ b/spec/roomslist.js @@ -112,7 +112,7 @@ type: 'groupchat' }).c('body').t('romeo: Your attention is required').tree() ); - var indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicactor"); + var indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator"); expect(indicator_el.textContent).toBe('1'); view.handleMUCMessage( @@ -123,12 +123,12 @@ type: 'groupchat' }).c('body').t('romeo: and another thing...').tree() ); - indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicactor"); + indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator"); expect(indicator_el.textContent).toBe('2'); // When the chat gets maximized again, the unread indicators are removed view.model.set({'minimized': false}); - indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicactor"); + indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator"); expect(_.isNull(indicator_el)); room_el = _converse.rooms_list_view.el.querySelector(".available-chatroom"); expect(_.includes(room_el.classList, 'unread-msgs')).toBeFalsy(); diff --git a/src/converse-muc.js b/src/converse-muc.js index b20807496..95bcf27fd 100755 --- a/src/converse-muc.js +++ b/src/converse-muc.js @@ -164,7 +164,7 @@ b64_sha1('converse.roomspanel'+_converse.bare_jid)) }))() }); - this.roomspanel.render().model.fetch(); + this.roomspanel.insertIntoDOM().model.fetch(); if (!this.roomspanel.model.get('nick')) { this.roomspanel.model.save({ nick: Strophe.getNodeFromJid(_converse.bare_jid) @@ -2375,37 +2375,43 @@ }, initialize: function (cfg) { - this.$parent = cfg.$parent; + this.parent_el = cfg.$parent[0]; + this.tab_el = document.createElement('li'); this.model.on('change:muc_domain', this.onDomainChange, this); this.model.on('change:nick', this.onNickChange, this); + _converse.chatboxes.on('change:num_unread', this.render, this); }, render: function () { - this.$parent.append( - this.$el.html( - tpl_room_panel({ - 'server_input_type': _converse.hide_muc_server && 'hidden' || 'text', - 'server_label_global_attr': _converse.hide_muc_server && ' hidden' || '', - 'label_room_name': __('Room name'), - 'label_nickname': __('Nickname'), - 'label_server': __('Server'), - 'label_join': __('Join Room'), - 'label_show_rooms': __('Show rooms') - }) - )); - this.$tabs = this.$parent.parent().find('#controlbox-tabs'); - + this.el.innerHTML = tpl_room_panel({ + 'server_input_type': _converse.hide_muc_server && 'hidden' || 'text', + 'server_label_global_attr': _converse.hide_muc_server && ' hidden' || '', + 'label_room_name': __('Room name'), + 'label_nickname': __('Nickname'), + 'label_server': __('Server'), + 'label_join': __('Join Room'), + 'label_show_rooms': __('Show rooms') + }); var controlbox = _converse.chatboxes.get('controlbox'); - this.$tabs.append(tpl_chatrooms_tab({ + var is_current = controlbox.get('active-panel') === ROOMS_PANEL_ID; + this.tab_el.innerHTML = tpl_chatrooms_tab({ 'label_rooms': __('Rooms'), - 'is_current': controlbox.get('active-panel') === ROOMS_PANEL_ID - })); - if (controlbox.get('active-panel') !== ROOMS_PANEL_ID) { - this.$el.addClass('hidden'); + 'is_current': is_current, + 'num_unread': _.sum(_converse.chatboxes.pluck('num_unread')) + }); + if (!is_current) { + this.el.classList.add('hidden'); } return this; }, + insertIntoDOM: function () { + this.parent_el.appendChild(this.render().el); + this.tabs = this.parent_el.parentNode.querySelector('#controlbox-tabs'); + this.tabs.appendChild(this.tab_el); + return this; + }, + onDomainChange: function (model) { var $server = this.$el.find('input.new-chatroom-server'); $server.val(model.get('muc_domain')); diff --git a/src/templates/chatrooms_tab.html b/src/templates/chatrooms_tab.html index cc754cca6..9180e19dc 100644 --- a/src/templates/chatrooms_tab.html +++ b/src/templates/chatrooms_tab.html @@ -1,4 +1,9 @@ -
  • {{label_rooms}} -
  • + {[ if (num_unread) { ]} + {{{ num_unread }}} + {[ } ]} + diff --git a/src/templates/rooms_list_item.html b/src/templates/rooms_list_item.html index 5979e680a..e55a73273 100644 --- a/src/templates/rooms_list_item.html +++ b/src/templates/rooms_list_item.html @@ -1,6 +1,6 @@
    {[ if (num_unread) { ]} - {{{ num_unread }}} + {{{ num_unread }}} {[ } ]} {{{name}}} {{{fullname}}} {[ if (num_unread) { ]} - {{{ num_unread }}} + {{{ num_unread }}} {[ } ]} {[ if (allow_contact_removal) { ]}