Add the logic for toggling minimized chats

This commit is contained in:
JC Brand 2014-06-08 21:43:00 +02:00
parent 5f7ec3fca0
commit 7d6595435e
10 changed files with 234 additions and 143 deletions

View File

@ -569,6 +569,7 @@
}
this.bare_jid = Strophe.getBareJidFromJid(this.connection.jid);
this.domain = Strophe.getDomainFromJid(this.connection.jid);
this.minimized_chats = new converse.MinimizedChats({model: this.chatboxes});
this.features = new this.Features();
this.enableCarbons();
this.initStatus($.proxy(function () {
@ -653,17 +654,31 @@
'otr_status': this.get('otr_status') || UNENCRYPTED,
'minimized': this.get('minimized') || false,
'time_minimized': this.get('time_minimized') || moment(),
'time_opened': this.get('time_opened') || moment().format(),
'time_opened': this.get('time_opened') || moment().valueOf(),
'height': height
});
} else {
this.set({
'height': height,
'time_opened': moment(0).format()
'time_opened': moment(0).valueOf()
});
}
},
maximize: function () {
this.save({
'minimized': false,
'time_opened': moment().valueOf()
});
},
minimize: function () {
this.save({
'minimized': true,
'time_minimized': moment().format()
});
},
getSession: function (callback) {
var cipher = CryptoJS.lib.PasswordBasedCipher;
var result, pass, instance_tag, saved_key, pass_check;
@ -1305,22 +1320,18 @@
},
maximize: function () {
/* Restores a minimized chat box
*/
this.$el.insertAfter(converse.chatboxviews.get("controlbox").$el).show();
this.focus();
converse.refreshWebkit();
converse.emit('onChatBoxMaximized', this);
// Restores a minimized chat box
this.model.trigger('maximized', this.model);
this.$el.insertAfter(converse.chatboxviews.get("controlbox").$el).show('fast', $.proxy(function () {
converse.refreshWebkit();
this.focus();
converse.emit('onChatBoxMaximized', this);
}, this));
},
minimize: function (ev) {
/* Minimizes a chat box
*/
this.model.save({
'minimized': true,
'time_minimized': moment().format()
});
// Minimizes a chat box
this.model.minimize();
this.$el.hide('fast', converse.refreshwebkit);
converse.emit('onChatBoxMinimized', this);
},
@ -2478,18 +2489,12 @@
this.ChatBoxViews = Backbone.Overview.extend({
initialize: function () {
this.trimmed_chatboxes_view = new converse.MinimizedChatBoxesView({model: this.model});
this.render();
this.model.on("add", this.onChatAdded, this);
this.model.on("maximized", function (item) {
this.trimChats(this.get(item.get('id')));
}, this);
},
render: function () {
this.$el.html(this.trimmed_chatboxes_view.render());
},
_ensureElement: function() {
/* Override method from backbone.js
* If the #conversejs element doesn't exist, create it.
@ -2500,6 +2505,7 @@
$el = $('<div id="conversejs">');
$('body').append($el);
}
$el.html(converse.templates.chats_panel());
this.setElement($el, false);
} else {
this.setElement(_.result(this, 'el'), false);
@ -2525,34 +2531,38 @@
this.trimChats(view);
},
trimChats: function (view) {
/* This method is called before a new chat box will be opened.
trimChats: function (newchat) {
/* This method is called when a newly created chat box will
* be shown.
*
* Check whether there is enough space in the page to show
* another chat box. Otherwise, close the oldest chat box.
* It checks whether there is enough space on the page to show
* another chat box. Otherwise it minimize the oldest chat box
* to create space.
*/
if (converse.no_trimming) {
if (converse.no_trimming || (this.model.length <= 1)) {
return;
}
var toggle_width = 0,
trimmed_chats_width,
boxes_width = view.$el.outerWidth(true),
var controlbox_width = 0,
$minimized = converse.minimized_chats.$el,
minimized_width = $minimized.is(':visible') ? $minimized.outerWidth(true) : 0,
boxes_width = newchat.$el.outerWidth(true),
controlbox = this.get('controlbox');
if (!controlbox || !controlbox.$el.is(':visible')) {
toggle_width = converse.controlboxtoggle.$el.width();
controlbox_width = converse.controlboxtoggle.$el.outerWidth(true);
} else {
controlbox_width = controlbox.$el.outerWidth(true);
}
this.$el.find('.chatbox').addBack('.chatroom').each(function (idx, el) {
var $el = $(el);
if ($el.is(':visible')) {
boxes_width += $el.outerWidth(true);
_.each(this.getAll(), function (view) {
var id = view.model.get('id');
if (view.$el.is(':visible') && (id !== 'controlbox') && (id !== newchat.model.get('id'))) {
boxes_width += view.$el.outerWidth(true);
}
});
if (this.model.length <= 1) {
return;
}
trimmed_chats_width = this.trimmed_chatboxes_view.$('.box-flyout').outerWidth(true) || 0;
if ((trimmed_chats_width + boxes_width + toggle_width) > this.$el.width()) {
this.getOldestMaximizedChat().set('minimized', true);
if ((minimized_width + boxes_width + controlbox_width) > this.$el.outerWidth(true)) {
this.getOldestMaximizedChat().minimize();
}
},
@ -2560,6 +2570,9 @@
// Get oldest view (which is not controlbox)
var i = 0;
var model = this.model.sort().at(i);
console.log(this.model.pluck('time_opened'));
console.log(this.model.pluck('id'));
console.log(this.model.pluck('minimized'));
while (model.get('id') === 'controlbox' || model.get('minimized') === true) {
i++;
model = this.model.at(i);
@ -2571,7 +2584,7 @@
var chatbox = this.model.get(attrs.jid);
if (chatbox) {
if (chatbox.get('minimized')) {
chatbox.set({'minimized': false});
chatbox.maximize();
} else {
chatbox.trigger('show');
}
@ -2605,7 +2618,10 @@
},
render: function () {
var data = this.model.toJSON();
var data = _.extend(
this.model.toJSON(),
{ 'tooltip': __('Click to restore this chat') }
);
if (this.model.get('chatroom')) {
data.title = this.model.get('name');
this.$el.addClass('chat-head-chatroom');
@ -2650,60 +2666,102 @@
ev.preventDefault();
}
this.$el.remove();
this.model.set({
'time_opened': moment().format(),
'minimized': false
});
this.model.maximize();
return this;
}
});
this.MinimizedChatBoxesView = Backbone.Overview.extend({
this.MinimizedChats = Backbone.Overview.extend({
el: "#minimized-chats",
events: {
"click #toggle-minimized-chats": "toggle"
},
initialize: function () {
this.chats_toggle = new converse.MinimizedChatsToggle();
this.chats_toggle_view = new converse.MinimizedChatsToggleView({model: this.chats_toggle});
this.model.on("add", function (item) {
if (item.get('minimized')) {
this.addChat(item);
}
}, this);
this.model.on("destroy", function (item) {
this.remove(item.get('id'));
this.render();
}, this);
this.model.on("change:minimized", function (item) {
this.onChanged(item);
}, this);
},
render: function () {
if (this.keys().length === 0) {
this.$el.hide('fast');
} else if (this.keys().length === 1) {
this.$el.show('fast');
}
return this.$el;
},
_ensureElement: function () {
/* Override method from backbone.js
* Make sure that the el and $el attributes point to a DOM snippet
* from src/templates/trimmed_chats.html
*/
if (!this.el) {
var $el = $(converse.templates.trimmed_chats());
this.setElement($el, false);
} else {
this.setElement(_.result(this, 'el'), false);
}
toggle: function () {
this.chats_toggle.set({'visible': !this.chats_toggle.get('visible')})
this.$('.minimized-chats-flyout').toggle();
},
onChanged: function (item) {
var view;
if (item.get('minimized')) {
this.addChat(item);
} else {
view = this.get(item.get('id'));
view.restore();
this.removeChat(item);
}
},
addChat: function (item) {
if (this.get(item.get('id'))) {
return;
}
var view = new converse.MinimizedChatBoxView({model: item});
this.$('.box-flyout').append(view.render());
this.$('.minimized-chats-flyout').append(view.render());
this.add(item.get('id'), view);
}
this.chats_toggle.set({'num_minimized': this.keys().length});
this.render();
},
removeChat: function (item) {
this.remove(item.get('id')).restore();
this.chats_toggle.set({'num_minimized': this.keys().length});
this.render();
}
});
this.MinimizedChatsToggle = Backbone.Model.extend({
localStorage: new Backbone.LocalStorage(
b64_sha1('converse.minimized-chats-toggle'+converse.bare_jid)),
initialize: function () {
this.set({
'visible': this.get('visible') || false,
'num_minimized': 0
});
}
});
this.MinimizedChatsToggleView = Backbone.View.extend({
el: '#toggle-minimized-chats',
initialize: function () {
this.model.on('change:num_minimized', this.render, this);
},
render: function () {
this.$el.html(converse.templates.toggle_chats({
'Minimized': __('Minimized'),
'num_minimized': this.model.get('num_minimized')
}));
return this.$el;
},
});
this.RosterItem = Backbone.Model.extend({
@ -3461,7 +3519,7 @@
}
});
this.Feature = Backbone.Model.extend();
this.Feature = Backbone.Model;
this.Features = Backbone.Collection.extend({
/* Service Discovery
* -----------------

View File

@ -559,14 +559,14 @@ span.spinner.centered {
span.spinner.hor_centered {
text-align: center;
}
#conversejs #trimmed-chatboxes .box-flyout {
#conversejs #minimized-chats .box-flyout {
position: absolute;
display: block;
height: auto;
bottom: 25px;
margin-left: 0;
}
#conversejs #trimmed-chatboxes .box-flyout .chat-head {
#conversejs #minimized-chats .box-flyout .chat-head {
font-size: 100%;
border-radius: 4px;
padding: 3px 0 0 5px;
@ -575,10 +575,7 @@ span.spinner.hor_centered {
height: 24px;
width: 130px;
}
#conversejs #trimmed-chatboxes .chat-head-chatroom {
width: 100px;
}
#conversejs #trimmed-chatboxes,
#conversejs #minimized-chats,
#conversejs .toggle-controlbox {
float: right;
font-size: 90%;
@ -591,7 +588,12 @@ span.spinner.hor_centered {
font-weight: bold;
height: 100%;
}
#conversejs .toggle-minimized-chats {
#conversejs #minimized-chats {
width: 130px;
padding: 0;
display: none;
}
#conversejs #toggle-minimized-chats {
position: relative;
padding: 4px 0 0 4px;
display: block;
@ -599,6 +601,10 @@ span.spinner.hor_centered {
height: 100%;
color: #0f0f0f;
}
#conversejs #toggle-minimized-chats .unread-message-count {
right: 5px;
bottom: 5px;
}
#conversejs .chat-head {
color: #ffffff;
font-size: 100%;
@ -838,10 +844,6 @@ dl.add-converse-contact {
background-color: #2D617A;
padding: 3px 0 0 0;
}
#conversejs .toggle-minimized-chats .unread-message-count {
right: 5px;
bottom: 5px;
}
#conversejs .unread-message-count,
#conversejs .chat-head-message-count {
font-weight: bold;
@ -1054,11 +1056,6 @@ dl.add-converse-contact {
margin-right: 15px;
display: block;
}
#conversejs #trimmed-chatboxes {
width: 130px;
padding: 0;
display: none;
}
#conversejs .chatbox {
width: 200px;
}
@ -1377,6 +1374,7 @@ input.custom-xmpp-status {
#conversejs .set-xmpp-status .dropdown dd ul {
z-index: 22;
}
#conversejs .minimized-chats-flyout,
#conversejs .box-flyout {
border-radius: 4px;
bottom: 6px;
@ -1385,11 +1383,24 @@ input.custom-xmpp-status {
height: 324px;
position: absolute;
}
#conversejs .box-flyout.minimized {
#conversejs .minimized-chats-flyout {
border-radius: 4px;
bottom: 25px;
box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
display: block;
position: absolute;
height: auto;
width: 130px;
}
#conversejs .minimized-chats-flyout.minimized {
height: auto;
}
#conversejs .box-flyout.minimized .chat-head {
#conversejs .minimized-chats-flyout .chat-head-chatroom,
#conversejs .minimized-chats-flyout .chat-head {
border-radius: 4px;
width: 130px;
height: 25px;
margin-bottom: 1px;
}
#conversejs .chatbox .box-flyout {
width: 200px;

View File

@ -588,7 +588,7 @@ span.spinner.hor_centered {
text-align: center;
}
#conversejs #trimmed-chatboxes .box-flyout {
#conversejs #minimized-chats .box-flyout {
position: absolute;
display: block;
height: auto;
@ -596,7 +596,7 @@ span.spinner.hor_centered {
margin-left: 0;
}
#conversejs #trimmed-chatboxes .box-flyout .chat-head {
#conversejs #minimized-chats .box-flyout .chat-head {
font-size: 100%;
border-radius: 4px;
padding: 3px 0 0 5px;
@ -606,11 +606,7 @@ span.spinner.hor_centered {
width: 130px;
}
#conversejs #trimmed-chatboxes .chat-head-chatroom {
width: 100px;
}
#conversejs #trimmed-chatboxes,
#conversejs #minimized-chats,
#conversejs .toggle-controlbox {
float: right;
font-size: 90%;
@ -624,7 +620,13 @@ span.spinner.hor_centered {
height: 100%;
}
#conversejs .toggle-minimized-chats {
#conversejs #minimized-chats {
width: 130px;
padding: 0;
display: none;
}
#conversejs #toggle-minimized-chats {
position: relative;
padding: 4px 0 0 4px;
display: block;
@ -633,6 +635,11 @@ span.spinner.hor_centered {
color: #0f0f0f;
}
#conversejs #toggle-minimized-chats .unread-message-count {
right: 5px;
bottom: 5px;
}
#conversejs .chat-head {
color: #ffffff;
font-size: 100%;
@ -917,11 +924,6 @@ dl.add-converse-contact {
padding: 3px 0 0 0;
}
#conversejs .toggle-minimized-chats .unread-message-count {
right: 5px;
bottom: 5px;
}
#conversejs .unread-message-count,
#conversejs .chat-head-message-count {
font-weight: bold;
@ -1166,12 +1168,6 @@ dl.add-converse-contact {
display: block;
}
#conversejs #trimmed-chatboxes {
width: 130px;
padding: 0;
display: none;
}
#conversejs .chatbox {
width: 200px;
}
@ -1551,6 +1547,7 @@ input.custom-xmpp-status {
z-index: 22;
}
#conversejs .minimized-chats-flyout,
#conversejs .box-flyout {
border-radius: 4px;
bottom: 6px;
@ -1560,12 +1557,26 @@ input.custom-xmpp-status {
position: absolute;
}
#conversejs .box-flyout.minimized {
#conversejs .minimized-chats-flyout {
border-radius: 4px;
bottom: 25px;
box-shadow: 1px 3px 5px 3px rgba(0,0,0,0.4);
display: block;
position: absolute;
height: auto;
width: 130px;
}
#conversejs .minimized-chats-flyout.minimized {
height: auto;
}
#conversejs .box-flyout.minimized .chat-head {
#conversejs .minimized-chats-flyout .chat-head-chatroom,
#conversejs .minimized-chats-flyout .chat-head {
border-radius: 4px;
width: 130px;
height: 25px;
margin-bottom: 1px;
}
#conversejs .chatbox .box-flyout {

View File

@ -373,11 +373,12 @@
</div>
</div>
<div id="trimmed-chatboxes">
<a class="toggle-minimized-chats" href="#">
<div id="minimized-chats">
<a id="toggle-minimized-chats" href="#">
<span class="conn-feedback">Minimized</span> <span id="online-count">(0)</span>
<span class="unread-message-count" href="#" style="display:block">322</span>
</a>
<div class="box-flyout minimized-chats">
<div class="minimized-chats-flyout">
<div class="chat-head chat-head-chatroom">
<a class="close-chatbox-button icon-close"></a>
<a class="chat-head-message-count" href="#" style="display:block">3</a>

View File

@ -45,12 +45,12 @@
</div>
<div id="trimmed-chatboxes">
<a class="toggle-minimized-chats" href="#">
<span class="conn-feedback">Minimized</span> <span id="online-count">(0)</span>
<div id="minimized-chats" style="display: block">
<a id="toggle-minimized-chats" href="#">
<span>Minimized <span id="minimized-count">(0)</span>
<span class="unread-message-count" href="#" style="display:block">322</span>
</a>
<div class="box-flyout minimized-chats">
<div class="minimized-chats-flyout">
<div class="chat-head chat-head-chatroom">
<a class="close-chatbox-button icon-close"></a>
<a class="chat-head-message-count" href="#" style="display:block">3</a>
@ -194,7 +194,7 @@ $(document).ready(function () {
});
$('.toggle-minimized-chats').click(function(ev) {
$('.minimized-chats').toggle();
$('.minimized-chats-flyout').toggle();
});
// Clickable Dropdown

View File

@ -8,6 +8,7 @@ define("converse-templates", [
"tpl!src/templates/chatbox",
"tpl!src/templates/chatroom",
"tpl!src/templates/chatrooms_tab",
"tpl!src/templates/chats_panel",
"tpl!src/templates/choose_status",
"tpl!src/templates/contacts",
"tpl!src/templates/contacts_panel",
@ -36,7 +37,7 @@ define("converse-templates", [
"tpl!src/templates/status_option",
"tpl!src/templates/toolbar",
"tpl!src/templates/trimmed_chat",
"tpl!src/templates/trimmed_chats"
"tpl!src/templates/toggle_chats"
], function () {
return {
action: arguments[0],
@ -48,34 +49,35 @@ define("converse-templates", [
chatbox: arguments[6],
chatroom: arguments[7],
chatrooms_tab: arguments[8],
choose_status: arguments[9],
contacts: arguments[10],
contacts_panel: arguments[11],
contacts_tab: arguments[12],
controlbox: arguments[13],
controlbox_toggle: arguments[14],
field: arguments[15],
form_checkbox: arguments[16],
form_input: arguments[17],
form_select: arguments[18],
info: arguments[19],
login_panel: arguments[20],
login_tab: arguments[21],
message: arguments[22],
new_day: arguments[23],
occupant: arguments[24],
pending_contact: arguments[25],
pending_contacts: arguments[26],
requesting_contact: arguments[27],
requesting_contacts: arguments[28],
room_description: arguments[29],
room_item: arguments[30],
room_panel: arguments[31],
roster_item: arguments[32],
select_option: arguments[33],
status_option: arguments[34],
toolbar: arguments[35],
trimmed_chat: arguments[36],
trimmed_chats: arguments[37]
chats_panel: arguments[9],
choose_status: arguments[10],
contacts: arguments[11],
contacts_panel: arguments[12],
contacts_tab: arguments[13],
controlbox: arguments[14],
controlbox_toggle: arguments[15],
field: arguments[16],
form_checkbox: arguments[17],
form_input: arguments[18],
form_select: arguments[19],
info: arguments[20],
login_panel: arguments[21],
login_tab: arguments[22],
message: arguments[23],
new_day: arguments[24],
occupant: arguments[25],
pending_contact: arguments[26],
pending_contacts: arguments[27],
requesting_contact: arguments[28],
requesting_contacts: arguments[29],
room_description: arguments[30],
room_item: arguments[31],
room_panel: arguments[32],
roster_item: arguments[33],
select_option: arguments[34],
status_option: arguments[35],
toolbar: arguments[36],
trimmed_chat: arguments[37],
toggle_chats: arguments[38]
};
});

View File

@ -0,0 +1,7 @@
<div id="minimized-chats">
<a id="toggle-minimized-chats" href="#">
<span>Minimized <span id="minimized-count">(0)</span>
<span class="unread-message-count" href="#">0</span>
</a>
<div class="minimized-chats-flyout"></div>
</div>

View File

@ -0,0 +1,2 @@
{{Minimized}} <span id="minimized-count">({{num_minimized}})</span>
<span class="unread-message-count" href="#">0</span>

View File

@ -1,7 +1,7 @@
<a class="close-chatbox-button icon-close"></a>
<a class="chat-head-message-count" href="#">0</a>
<div class="chat-title">
<a href="#" class="restore-chat">
<div class="chat-head-message-count">0</div>
<a href="#" class="restore-chat" title="{{tooltip}}">
{{ title }}
</a>
</div>

View File

@ -1 +0,0 @@
<div id="trimmed-chatboxes"><div class="box-flyout"></div></div>