Bläddra i källkod

Add a counter to show unread msgs when chat is minimized

JC Brand 11 år sedan
förälder
incheckning
bb0f49cf4d
6 ändrade filer med 78 tillägg och 25 borttagningar
  1. 1 0
      converse.css
  2. 33 11
      converse.js
  3. 2 2
      mockup/minimized.html
  4. 40 12
      spec/chatbox.js
  5. 1 0
      src/templates/chatbox.html
  6. 1 0
      src/templates/chatroom.html

+ 1 - 0
converse.css

@@ -672,6 +672,7 @@ form.search-xmpp-contact input {
     padding: 2px 10px;
     font-size: 18px;
     text-align: center;
+    display: none;
 }
 
 .chat-head-chatroom .chat-head-message-count {

+ 33 - 11
converse.js

@@ -655,6 +655,7 @@
                         'box_id' : hex_sha1(this.get('jid')),
                         'otr_status': this.get('otr_status') || UNENCRYPTED,
                         'minimized': this.get('minimized') || false,
+                        'time_minimized': this.get('time_minimized') || converse.toISOString(new Date()),
                         'height': height
                     });
                 } else {
@@ -892,7 +893,6 @@
                 this.model.on('showReceivedOTRMessage', function (text) {
                     this.showMessage({'message': text, 'sender': 'them'});
                 }, this);
-
                 this.updateVCard();
                 this.$el.appendTo(converse.chatboxviews.$el);
                 this.render().show().focus().model.messages.fetch({add: true});
@@ -938,23 +938,35 @@
                 this.scrollDown();
             },
 
+            updateUnreadMessagesCounter: function () {
+                /* If the chatbox is minimized, we show a counter with the
+                 * number of unread messages.
+                 */
+                var $count = this.$el.find('.chat-head-message-count');
+                var count = parseInt($count.data('count') || 0, 10) + 1;
+                $count.html(count).data('count', count);
+                if (!$count.is(':visible')) { $count.show('fast'); }
+                return this;
+            },
+
             showMessage: function (msg_dict) {
-                var $el = this.$el.find('.chat-content'),
-                    msg_date = msg_dict.time ? converse.parseISO8601(msg_dict.time) : new Date(),
+                var $content = this.$el.find('.chat-content'),
+                    iso_time = msg_dict.time || converse.toISOString(new Date()),
+                    msg_date = converse.parseISO8601(iso_time),
                     text = msg_dict.message,
                     match = text.match(/^\/(.*?)(?: (.*))?$/),
-                    fullname = msg_dict.fullname || this.model.get('fullname'),
+                    fullname = msg_dict.fullname || this.model.get('fullname'), // XXX Perhaps always use model's?
                     template, username;
 
                 if ((match) && (match[1] === 'me')) {
                     text = text.replace(/^\/me/, '');
-                    template = converse.templates.action_template;
+                    template = converse.templates.action;
                     username = fullname;
                 } else  {
                     template = converse.templates.message;
                     username = msg_dict.sender === 'me' && __('me') || fullname;
                 }
-                $el.find('div.chat-event').remove();
+                $content.find('div.chat-event').remove();
                 var message = template({
                     'sender': msg_dict.sender,
                     'time': msg_date.toTimeString().substring(0,5),
@@ -962,8 +974,11 @@
                     'message': '',
                     'extra_classes': msg_dict.delayed && 'delayed' || ''
                 });
-                $el.append($(message).children('.chat-message-content').first().text(text).addHyperlinks().addEmoticons().parent());
-                return this.scrollDown();
+                $content.append($(message).children('.chat-message-content').first().text(text).addHyperlinks().addEmoticons().parent());
+                if (this.model.get('minimized') && (iso_time > this.model.get('time_minimized'))) {
+                    this.updateUnreadMessagesCounter();
+                }
+                this.scrollDown();
             },
 
             showHelpMessages: function (msgs, type, spinner) {
@@ -1284,19 +1299,26 @@
                     this.model.save({'minimized': false});
                 } else {
                     flyout.addClass('minimized');
-                    this.model.save({'minimized': true});
+                    this.model.save({
+                        'minimized': true,
+                        'time_minimized': converse.toISOString(new Date())
+                    });
                 }
+                return this;
             },
 
             toggleChatBox: function (ev) {
-                this.$el.children('.box-flyout').attr('style', '');
+                var $target = $(ev.target), $count;
                 this.saveToggleState();
+                this.$el.children('.box-flyout').attr('style', '');
                 this.$el.find('div.chat-body').slideToggle('fast');
-                var $target = $(ev.target);
                 if ($target.hasClass('icon-minus')) {
                     $target.removeClass('icon-minus').addClass('icon-plus');
                 } else {
                     $target.removeClass('icon-plus').addClass('icon-minus');
+                    $count = this.$el.find('.chat-head-message-count');
+                    $count.html(0).data('count', 0);
+                    if ($count.is(':visible')) { $count.hide('fast'); }
                 }
                 // Toggle drag resize ability
                 this.$el.find('.dragresize-tm').toggle();

+ 2 - 2
mockup/minimized.html

@@ -24,7 +24,7 @@
         <div class="box-flyout minimized">
             <div class="dragresize dragresize-tm"></div>
             <div class="chat-head chat-head-chatbox">
-                <div class="chat-head-message-count">3</div>
+                <div class="chat-head-message-count" style="display:block">3</div>
                 <a class="close-chatbox-button icon-close"></a>
                 <a class="toggle-chatbox-button icon-minus"></a>
                 <canvas height="33px" width="33px" class="avatar" style="background-color: black"></canvas>
@@ -105,7 +105,7 @@
         <div class="box-flyout minimized">
             <div class="dragresize dragresize-tm"></div>
             <div class="chat-head chat-head-chatroom">
-                <div class="chat-head-message-count">42</div>
+                <div class="chat-head-message-count" style="display:block">42</div>
                 <a class="close-chatbox-button icon-close"></a>
                 <a class="toggle-chatbox-button icon-minus"></a>
                 <a class="configure-chatroom-button icon-wrench" style=""></a>

+ 40 - 12
spec/chatbox.js

@@ -343,8 +343,7 @@
                     }, converse));
                 }, converse));
 
-                // TODO: This feature is not yet implemented
-                xit("received for a minimized chat box will increment a counter on its header", $.proxy(function () {
+                it("received for a minimized chat box will increment a counter on its header", $.proxy(function () {
                     var contact_name = mock.cur_names[0];
                     var contact_jid = contact_name.replace(' ','.').toLowerCase() + '@localhost';
                     spyOn(this, 'emit');
@@ -361,25 +360,54 @@
                     runs($.proxy(function () {
                         var chatview = this.chatboxviews.get(contact_jid);
                         expect(chatview.model.get('minimized')).toBeTruthy();
-
                         var message = 'This message is sent to a minimized chatbox';
                         var sender_jid = mock.cur_names[0].replace(' ','.').toLowerCase() + '@localhost';
-                            msg = $msg({
-                                from: sender_jid,
-                                to: this.connection.jid,
-                                type: 'chat',
-                                id: (new Date()).getTime()
-                            }).c('body').t(message).up()
-                            .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
-
+                        msg = $msg({
+                            from: sender_jid,
+                            to: this.connection.jid,
+                            type: 'chat',
+                            id: (new Date()).getTime()
+                        }).c('body').t(message).up()
+                        .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
                         this.chatboxes.onMessage(msg);
                         expect(this.emit).toHaveBeenCalledWith('onMessage', msg);
                     }, converse));
                     waits(250);
                     runs($.proxy(function () {
                         var chatview = this.chatboxviews.get(contact_jid);
+                        var $count = chatview.$el.find('.chat-head-message-count');
+                        expect(chatview.model.get('minimized')).toBeTruthy();
+                        expect($count.is(':visible')).toBeTruthy();
+                        expect($count.data('count')).toBe(1);
+                        expect($count.html()).toBe('1');
+                        this.chatboxes.onMessage(
+                            $msg({
+                                from: mock.cur_names[0].replace(' ','.').toLowerCase() + '@localhost',
+                                to: this.connection.jid,
+                                type: 'chat',
+                                id: (new Date()).getTime()
+                            }).c('body').t('This message is also sent to a minimized chatbox').up()
+                            .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree()
+                        );
+                    }, converse));
+                    waits(100);
+                    runs($.proxy(function () {
+                        var chatview = this.chatboxviews.get(contact_jid);
+                        var $count = chatview.$el.find('.chat-head-message-count');
                         expect(chatview.model.get('minimized')).toBeTruthy();
-                        expect(chatview.$el.find('.chat-head-message-count').length).toBe(1);
+                        expect($count.is(':visible')).toBeTruthy();
+                        expect($count.data('count')).toBe(2);
+                        expect($count.html()).toBe('2');
+                        chatview.$el.find('.toggle-chatbox-button').click();
+                    }, converse));
+                    waits(250);
+                    runs($.proxy(function () {
+                        var chatview = this.chatboxviews.get(contact_jid);
+                        var $count = chatview.$el.find('.chat-head-message-count');
+                        expect(chatview.model.get('minimized')).toBeFalsy();
+                        expect($count.is(':visible')).toBeFalsy();
+                        expect($count.data('count')).toBe(0);
+                        expect($count.html()).toBe('0');
                     }, converse));
                 }, converse));
 

+ 1 - 0
src/templates/chatbox.html

@@ -2,6 +2,7 @@
     {[if (!minimized) {]} style="height: {{height}}px" {[}]}>
     <div class="dragresize dragresize-tm" {[ if (minimized) { ]} style="display:none" {[ } ]}></div>
     <div class="chat-head chat-head-chatbox">
+        <div class="chat-head-message-count">0</div>
         <a class="close-chatbox-button icon-close"></a>
         <a class="toggle-chatbox-button
                   {[ if (minimized) { ]} icon-plus {[ } ]}

+ 1 - 0
src/templates/chatroom.html

@@ -2,6 +2,7 @@
     {[if (!minimized) {]} style="height: {{height}}px" {[}]}>
     <div class="dragresize dragresize-tm" {[ if (minimized) { ]} style="display:none" {[ } ]}></div>
     <div class="chat-head chat-head-chatroom">
+        <div class="chat-head-message-count">0</div>
         <a class="close-chatbox-button icon-close"></a>
         <a class="toggle-chatbox-button
                   {[ if (minimized) { ]} icon-plus {[ } ]}