Commit bb0f49cf authored by JC Brand's avatar JC Brand

Add a counter to show unread msgs when chat is minimized

parent 9849daac
......@@ -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 {
......
......@@ -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();
......
......@@ -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>
......
......@@ -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));
......
......@@ -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 {[ } ]}
......
......@@ -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 {[ } ]}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment