Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
95ac01b860
4
dev.html
4
dev.html
@ -64,8 +64,8 @@
|
|||||||
'discuss@conference.conversejs.org'
|
'discuss@conference.conversejs.org'
|
||||||
],
|
],
|
||||||
auto_reconnect: true,
|
auto_reconnect: true,
|
||||||
// bosh_service_url: 'http://chat.example.org:5280/http-bind/',
|
bosh_service_url: 'http://chat.example.org:5280/http-bind/',
|
||||||
bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
|
// bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
|
||||||
message_archiving: 'always',
|
message_archiving: 'always',
|
||||||
show_controlbox_by_default: true,
|
show_controlbox_by_default: true,
|
||||||
strict_plugin_dependencies: false,
|
strict_plugin_dependencies: false,
|
||||||
|
@ -63,9 +63,13 @@
|
|||||||
expect(_converse.minimized_chats.$('.minimized-chats-flyout').is(':visible')).toBeTruthy();
|
expect(_converse.minimized_chats.$('.minimized-chats-flyout').is(':visible')).toBeTruthy();
|
||||||
expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeFalsy();
|
expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeFalsy();
|
||||||
_converse.minimized_chats.$('#toggle-minimized-chats').click();
|
_converse.minimized_chats.$('#toggle-minimized-chats').click();
|
||||||
expect(_converse.minimized_chats.$('.minimized-chats-flyout').is(':visible')).toBeFalsy();
|
|
||||||
|
return test_utils.waitUntil(function () {
|
||||||
|
return _converse.minimized_chats.$('.minimized-chats-flyout').is(':visible');
|
||||||
|
}, 500).then(function () {
|
||||||
expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeTruthy();
|
expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeTruthy();
|
||||||
done();
|
done();
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("shows the number messages received to minimized chats",
|
it("shows the number messages received to minimized chats",
|
||||||
|
@ -7,8 +7,7 @@
|
|||||||
/*global define, window */
|
/*global define, window */
|
||||||
|
|
||||||
(function (root, factory) {
|
(function (root, factory) {
|
||||||
define(["jquery.noconflict",
|
define(["converse-core",
|
||||||
"converse-core",
|
|
||||||
"tpl!chatbox_minimize",
|
"tpl!chatbox_minimize",
|
||||||
"tpl!toggle_chats",
|
"tpl!toggle_chats",
|
||||||
"tpl!trimmed_chat",
|
"tpl!trimmed_chat",
|
||||||
@ -16,7 +15,6 @@
|
|||||||
"converse-chatview"
|
"converse-chatview"
|
||||||
], factory);
|
], factory);
|
||||||
}(this, function (
|
}(this, function (
|
||||||
$,
|
|
||||||
converse,
|
converse,
|
||||||
tpl_chatbox_minimize,
|
tpl_chatbox_minimize,
|
||||||
tpl_toggle_chats,
|
tpl_toggle_chats,
|
||||||
@ -25,7 +23,8 @@
|
|||||||
) {
|
) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { _ , utils, Backbone, Promise, Strophe, b64_sha1, moment } = converse.env;
|
const { _ , Backbone, Promise, Strophe, b64_sha1, moment } = converse.env;
|
||||||
|
const u = converse.env.utils;
|
||||||
|
|
||||||
converse.plugins.add('converse-minimize', {
|
converse.plugins.add('converse-minimize', {
|
||||||
/* Optional dependencies are other plugins which might be
|
/* Optional dependencies are other plugins which might be
|
||||||
@ -55,7 +54,7 @@
|
|||||||
|
|
||||||
registerGlobalEventHandlers () {
|
registerGlobalEventHandlers () {
|
||||||
const { _converse } = this.__super__;
|
const { _converse } = this.__super__;
|
||||||
$(window).on("resize", _.debounce(function (ev) {
|
window.addEventListener("resize", _.debounce(function (ev) {
|
||||||
if (_converse.connection.connected) {
|
if (_converse.connection.connected) {
|
||||||
_converse.chatboxviews.trimChats();
|
_converse.chatboxviews.trimChats();
|
||||||
}
|
}
|
||||||
@ -76,14 +75,14 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
maximize () {
|
maximize () {
|
||||||
utils.safeSave(this, {
|
u.safeSave(this, {
|
||||||
'minimized': false,
|
'minimized': false,
|
||||||
'time_opened': moment().valueOf()
|
'time_opened': moment().valueOf()
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
minimize () {
|
minimize () {
|
||||||
utils.safeSave(this, {
|
u.safeSave(this, {
|
||||||
'minimized': true,
|
'minimized': true,
|
||||||
'time_minimized': moment().format()
|
'time_minimized': moment().format()
|
||||||
});
|
});
|
||||||
@ -224,8 +223,8 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
getChatBoxWidth (view) {
|
getChatBoxWidth (view) {
|
||||||
if (!view.model.get('minimized') && view.$el.is(':visible')) {
|
if (!view.model.get('minimized') && u.isVisible(view.el)) {
|
||||||
return view.$el.outerWidth(true);
|
return u.getOuterWidth(view.el, true);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
@ -237,7 +236,7 @@
|
|||||||
// the 'closed' state.
|
// the 'closed' state.
|
||||||
!view.model.get('minimized') &&
|
!view.model.get('minimized') &&
|
||||||
!view.model.get('closed') &&
|
!view.model.get('closed') &&
|
||||||
view.$el.is(':visible')
|
u.isVisible(view.el)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -249,28 +248,33 @@
|
|||||||
* another chat box. Otherwise it minimizes the oldest chat box
|
* another chat box. Otherwise it minimizes the oldest chat box
|
||||||
* to create space.
|
* to create space.
|
||||||
*/
|
*/
|
||||||
const { _converse } = this.__super__;
|
const { _converse } = this.__super__,
|
||||||
const shown_chats = this.getShownChats();
|
shown_chats = this.getShownChats(),
|
||||||
|
body_width = u.getOuterWidth(document.querySelector('body'), true);
|
||||||
|
|
||||||
if (_converse.no_trimming || shown_chats.length <= 1) {
|
if (_converse.no_trimming || shown_chats.length <= 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.getChatBoxWidth(shown_chats[0]) === $('body').outerWidth(true)) {
|
if (this.getChatBoxWidth(shown_chats[0]) === body_width) {
|
||||||
// If the chats shown are the same width as the body,
|
// If the chats shown are the same width as the body,
|
||||||
// then we're in responsive mode and the chats are
|
// then we're in responsive mode and the chats are
|
||||||
// fullscreen. In this case we don't trim.
|
// fullscreen. In this case we don't trim.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_converse.api.waitUntil('minimizedChatsInitialized').then(() => {
|
_converse.api.waitUntil('minimizedChatsInitialized').then(() => {
|
||||||
const $minimized = _.get(_converse.minimized_chats, '$el'),
|
const minimized_el = _.get(_converse.minimized_chats, 'el'),
|
||||||
minimized_width = _.includes(this.model.pluck('minimized'), true) ? $minimized.outerWidth(true) : 0,
|
|
||||||
new_id = newchat ? newchat.model.get('id') : null;
|
new_id = newchat ? newchat.model.get('id') : null;
|
||||||
|
|
||||||
|
if (minimized_el) {
|
||||||
|
const minimized_width = _.includes(this.model.pluck('minimized'), true) ?
|
||||||
|
u.getOuterWidth(minimized_el, true) : 0;
|
||||||
|
|
||||||
const boxes_width = _.reduce(
|
const boxes_width = _.reduce(
|
||||||
this.xget(new_id),
|
this.xget(new_id),
|
||||||
(memo, view) => memo + this.getChatBoxWidth(view),
|
(memo, view) => memo + this.getChatBoxWidth(view),
|
||||||
newchat ? newchat.$el.outerWidth(true) : 0);
|
newchat ? u.getOuterWidth(newchat.el, true) : 0
|
||||||
|
);
|
||||||
if ((minimized_width + boxes_width) > $('body').outerWidth(true)) {
|
if ((minimized_width + boxes_width) > body_width) {
|
||||||
const oldest_chat = this.getOldestMaximizedChat([new_id]);
|
const oldest_chat = this.getOldestMaximizedChat([new_id]);
|
||||||
if (oldest_chat) {
|
if (oldest_chat) {
|
||||||
// We hide the chat immediately, because waiting
|
// We hide the chat immediately, because waiting
|
||||||
@ -284,6 +288,7 @@
|
|||||||
oldest_chat.minimize();
|
oldest_chat.minimize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -344,12 +349,13 @@
|
|||||||
);
|
);
|
||||||
if (this.model.get('type') === 'chatroom') {
|
if (this.model.get('type') === 'chatroom') {
|
||||||
data.title = this.model.get('name');
|
data.title = this.model.get('name');
|
||||||
this.$el.addClass('chat-head-chatroom');
|
u.addClass(this.el, 'chat-head-chatroom');
|
||||||
} else {
|
} else {
|
||||||
data.title = this.model.get('fullname');
|
data.title = this.model.get('fullname');
|
||||||
this.$el.addClass('chat-head-chatbox');
|
u.addClass(this.el, 'chat-head-chatbox');
|
||||||
}
|
}
|
||||||
return this.$el.html(tpl_trimmed_chat(data));
|
this.el.innerHTML = tpl_trimmed_chat(data);
|
||||||
|
return this.el;
|
||||||
},
|
},
|
||||||
|
|
||||||
close (ev) {
|
close (ev) {
|
||||||
@ -401,11 +407,11 @@
|
|||||||
}
|
}
|
||||||
if (this.keys().length === 0) {
|
if (this.keys().length === 0) {
|
||||||
this.el.classList.add('hidden');
|
this.el.classList.add('hidden');
|
||||||
} else if (this.keys().length > 0 && !this.$el.is(':visible')) {
|
} else if (this.keys().length > 0 && !u.isVisible(this.el)) {
|
||||||
this.el.classList.remove('hidden');
|
this.el.classList.remove('hidden');
|
||||||
_converse.chatboxviews.trimChats();
|
_converse.chatboxviews.trimChats();
|
||||||
}
|
}
|
||||||
return this.$el;
|
return this.el;
|
||||||
},
|
},
|
||||||
|
|
||||||
tearDown () {
|
tearDown () {
|
||||||
@ -429,7 +435,7 @@
|
|||||||
toggle (ev) {
|
toggle (ev) {
|
||||||
if (ev && ev.preventDefault) { ev.preventDefault(); }
|
if (ev && ev.preventDefault) { ev.preventDefault(); }
|
||||||
this.toggleview.model.save({'collapsed': !this.toggleview.model.get('collapsed')});
|
this.toggleview.model.save({'collapsed': !this.toggleview.model.get('collapsed')});
|
||||||
this.$('.minimized-chats-flyout').toggle();
|
u.slideToggleElement(this.el.querySelector('.minimized-chats-flyout'), 200);
|
||||||
},
|
},
|
||||||
|
|
||||||
onChanged (item) {
|
onChanged (item) {
|
||||||
@ -444,28 +450,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
addMultipleChats (items) {
|
addChatView (item) {
|
||||||
_.each(items, (item) => {
|
|
||||||
const existing = this.get(item.get('id'));
|
const existing = this.get(item.get('id'));
|
||||||
if (existing && existing.$el.parent().length !== 0) {
|
if (existing && existing.el.parentNode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const view = new _converse.MinimizedChatBoxView({model: item});
|
const view = new _converse.MinimizedChatBoxView({model: item});
|
||||||
this.$('.minimized-chats-flyout').append(view.render());
|
this.el.querySelector('.minimized-chats-flyout').insertAdjacentElement('beforeEnd', view.render());
|
||||||
this.add(item.get('id'), view);
|
this.add(item.get('id'), view);
|
||||||
});
|
},
|
||||||
|
|
||||||
|
addMultipleChats (items) {
|
||||||
|
_.each(items, this.addChatView.bind(this));
|
||||||
this.toggleview.model.set({'num_minimized': this.keys().length});
|
this.toggleview.model.set({'num_minimized': this.keys().length});
|
||||||
this.render();
|
this.render();
|
||||||
},
|
},
|
||||||
|
|
||||||
addChat (item) {
|
addChat (item) {
|
||||||
const existing = this.get(item.get('id'));
|
this.addChatView(item);
|
||||||
if (existing && existing.$el.parent().length !== 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const view = new _converse.MinimizedChatBoxView({model: item});
|
|
||||||
this.$('.minimized-chats-flyout').append(view.render());
|
|
||||||
this.add(item.get('id'), view);
|
|
||||||
this.toggleview.model.set({'num_minimized': this.keys().length});
|
this.toggleview.model.set({'num_minimized': this.keys().length});
|
||||||
this.render();
|
this.render();
|
||||||
},
|
},
|
||||||
@ -501,21 +503,21 @@
|
|||||||
initialize () {
|
initialize () {
|
||||||
this.model.on('change:num_minimized', this.render, this);
|
this.model.on('change:num_minimized', this.render, this);
|
||||||
this.model.on('change:num_unread', this.render, this);
|
this.model.on('change:num_unread', this.render, this);
|
||||||
this.$flyout = this.$el.siblings('.minimized-chats-flyout');
|
this.flyout = this.el.parentElement.querySelector('.minimized-chats-flyout');
|
||||||
},
|
},
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
this.$el.html(tpl_toggle_chats(
|
this.el.innerHTML = tpl_toggle_chats(
|
||||||
_.extend(this.model.toJSON(), {
|
_.extend(this.model.toJSON(), {
|
||||||
'Minimized': __('Minimized')
|
'Minimized': __('Minimized')
|
||||||
})
|
})
|
||||||
));
|
);
|
||||||
if (this.model.get('collapsed')) {
|
if (this.model.get('collapsed')) {
|
||||||
this.$flyout.hide();
|
u.hideElement(this.flyout);
|
||||||
} else {
|
} else {
|
||||||
this.$flyout.show();
|
u.showElement(this.flyout);
|
||||||
}
|
}
|
||||||
return this.$el;
|
return this.el;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -531,14 +533,16 @@
|
|||||||
|
|
||||||
_converse.on('chatBoxOpened', function renderMinimizeButton (view) {
|
_converse.on('chatBoxOpened', function renderMinimizeButton (view) {
|
||||||
// Inserts a "minimize" button in the chatview's header
|
// Inserts a "minimize" button in the chatview's header
|
||||||
const $el = view.$el.find('.toggle-chatbox-button');
|
const new_html = tpl_chatbox_minimize(
|
||||||
const $new_el = tpl_chatbox_minimize(
|
|
||||||
{info_minimize: __('Minimize this chat box')}
|
{info_minimize: __('Minimize this chat box')}
|
||||||
);
|
);
|
||||||
if ($el.length) {
|
|
||||||
$el.replaceWith($new_el);
|
const el = view.el.querySelector('.toggle-chatbox-button');
|
||||||
|
if (el) {
|
||||||
|
el.outerHTML = new_html;
|
||||||
} else {
|
} else {
|
||||||
view.$el.find('.close-chatbox-button').after($new_el);
|
const button = view.el.querySelector('.close-chatbox-button');
|
||||||
|
button.insertAdjacentHTML('afterEnd', new_html);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -389,10 +389,7 @@
|
|||||||
[menu]
|
[menu]
|
||||||
);
|
);
|
||||||
utils.slideInAllElements(elements).then(
|
utils.slideInAllElements(elements).then(
|
||||||
_.partial(
|
_.partial(utils.slideToggleElement, menu)
|
||||||
utils.slideToggleElement,
|
|
||||||
menu
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
32
src/utils.js
32
src/utils.js
@ -87,8 +87,14 @@
|
|||||||
|
|
||||||
var u = {};
|
var u = {};
|
||||||
|
|
||||||
|
u.addClass = function (el, className) {
|
||||||
|
if (el instanceof Element) {
|
||||||
|
el.classList.add(className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u.removeClass = function (klass, el) {
|
u.removeClass = function (klass, el) {
|
||||||
if (!_.isNil(el)) {
|
if (el instanceof Element) {
|
||||||
el.classList.remove(klass);
|
el.classList.remove(klass);
|
||||||
}
|
}
|
||||||
return el;
|
return el;
|
||||||
@ -163,11 +169,12 @@
|
|||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
u.slideToggleElement = function (el) {
|
u.slideToggleElement = function (el, duration) {
|
||||||
if (_.includes(el.classList, 'collapsed')) {
|
if (_.includes(el.classList, 'collapsed') ||
|
||||||
return u.slideOut(el);
|
_.includes(el.classList, 'hidden')) {
|
||||||
|
return u.slideOut(el, duration);
|
||||||
} else {
|
} else {
|
||||||
return u.slideIn(el);
|
return u.slideIn(el, duration);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -331,9 +338,10 @@
|
|||||||
* message, i.e. not a MAM archived one.
|
* message, i.e. not a MAM archived one.
|
||||||
*/
|
*/
|
||||||
if (message instanceof Element) {
|
if (message instanceof Element) {
|
||||||
return !(sizzle('result[xmlns="'+Strophe.NS.MAM+'"]', message).length);
|
return !sizzle('result[xmlns="'+Strophe.NS.MAM+'"]', message).length &&
|
||||||
|
!sizzle('delay[xmlns="'+Strophe.NS.DELAY+'"]', message).length;
|
||||||
} else {
|
} else {
|
||||||
return !message.get('archive_id');
|
return !message.get('archive_id') && !message.get('delayed');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -415,6 +423,16 @@
|
|||||||
return div.firstChild;
|
return div.firstChild;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
u.getOuterWidth = function (el, include_margin=false) {
|
||||||
|
var width = el.offsetWidth;
|
||||||
|
if (!include_margin) {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
var style = window.getComputedStyle(el);
|
||||||
|
width += parseInt(style.marginLeft, 10) + parseInt(style.marginRight, 10);
|
||||||
|
return width;
|
||||||
|
};
|
||||||
|
|
||||||
u.stringToElement = function (s) {
|
u.stringToElement = function (s) {
|
||||||
/* Converts an HTML string into a DOM element.
|
/* Converts an HTML string into a DOM element.
|
||||||
* Expects that the HTML string has only one top-level element,
|
* Expects that the HTML string has only one top-level element,
|
||||||
|
Loading…
Reference in New Issue
Block a user