Commit 2e07ec9f authored by Weblate's avatar Weblate

Merge remote-tracking branch 'origin/master'

parents da2502ca c9913bf6
...@@ -4,8 +4,11 @@ ...@@ -4,8 +4,11 @@
### Bugfixes ### Bugfixes
- Various IE11 fixes. - Various IE11 fixes.
- Translations written as template literals [aren't parsed properly by xgettext](https://savannah.gnu.org/bugs/?50920). - #907 Unnecessary login validation error when `default_domain` or `locked_domain` are set.
- Fix regarding ChatRoomView.getDefaultNickName() and muc_nickname_from_jid - #908 Login form for inVerse is only 200px when `allow_registration` is set to `false`.
- #909 Translations written as template literals [aren't parsed properly by xgettext](https://savannah.gnu.org/bugs/?50920).
- #911 Use `getDefaultNickName` consistently to allow better overrides via plugins.
- #912 `maximize` method in `converse-minimize` fails if the `controlbox` is not there.
## 3.2.0 (2017-08-09) ## 3.2.0 (2017-08-09)
......
...@@ -1643,9 +1643,11 @@ ...@@ -1643,9 +1643,11 @@
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched'], {}, null, ['rosterGroupsFetched'], {},
function (done, _converse) { function (done, _converse) {
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy'); test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy');
var view = _converse.chatboxviews.get('lounge@localhost'), var view = _converse.chatboxviews.get('lounge@localhost'),
trimmed_chatboxes = _converse.minimized_chats; trimmed_chatboxes = _converse.minimized_chats;
spyOn(view, 'minimize').and.callThrough(); spyOn(view, 'minimize').and.callThrough();
spyOn(view, 'maximize').and.callThrough(); spyOn(view, 'maximize').and.callThrough();
spyOn(_converse, 'emit'); spyOn(_converse, 'emit');
...@@ -1659,18 +1661,11 @@ ...@@ -1659,18 +1661,11 @@
expect(view.minimize).toHaveBeenCalled(); expect(view.minimize).toHaveBeenCalled();
var trimmedview = trimmed_chatboxes.get(view.model.get('id')); var trimmedview = trimmed_chatboxes.get(view.model.get('id'));
trimmedview.$("a.restore-chat").click(); trimmedview.$("a.restore-chat").click();
expect(view.maximize).toHaveBeenCalled();
test_utils.waitUntil(function () { expect(_converse.emit).toHaveBeenCalledWith('chatBoxMaximized', jasmine.any(Object));
return view.$el.is(':visible'); expect(view.model.get('minimized')).toBeFalsy();
}, 300) expect(_converse.emit.calls.count(), 3);
.then(function () { done();
expect(view.maximize).toHaveBeenCalled();
expect(_converse.emit).toHaveBeenCalledWith('chatBoxMaximized', jasmine.any(Object));
expect(view.$el.is(':visible')).toBeTruthy();
expect(view.model.get('minimized')).toBeFalsy();
expect(_converse.emit.calls.count(), 3);
done();
});
})); }));
it("can be closed again by clicking a DOM element with class 'close-chatbox-button'", it("can be closed again by clicking a DOM element with class 'close-chatbox-button'",
......
...@@ -305,8 +305,9 @@ ...@@ -305,8 +305,9 @@
}, },
insertIntoDOM () { insertIntoDOM () {
/* This method gets overridden in src/converse-controlbox.js if /* This method gets overridden in src/converse-controlbox.js
* the controlbox plugin is active. * as well as src/converse-muc.js (if those plugins are
* enabled).
*/ */
const container = document.querySelector('#conversejs'); const container = document.querySelector('#conversejs');
if (this.el.parentNode !== container) { if (this.el.parentNode !== container) {
......
...@@ -159,8 +159,12 @@ ...@@ -159,8 +159,12 @@
ChatBoxView: { ChatBoxView: {
insertIntoDOM () { insertIntoDOM () {
const { _converse } = this.__super__; const view = this.__super__._converse.chatboxviews.get("controlbox");
this.$el.insertAfter(_converse.chatboxviews.get("controlbox").$el); if (view) {
view.el.insertAdjacentElement('afterend', this.el)
} else {
this.__super__.insertIntoDOM.apply(this, arguments);
}
return this; return this;
} }
} }
...@@ -204,8 +208,10 @@ ...@@ -204,8 +208,10 @@
}, },
initialize () { initialize () {
_converse.controlboxtoggle = new _converse.ControlBoxToggle(); if (_.isUndefined(_converse.controlboxtoggle)) {
this.$el.insertAfter(_converse.controlboxtoggle.$el); _converse.controlboxtoggle = new _converse.ControlBoxToggle();
this.$el.insertAfter(_converse.controlboxtoggle.$el);
}
this.model.on('change:connected', this.onConnected, this); this.model.on('change:connected', this.onConnected, this);
this.model.on('destroy', this.hide, this); this.model.on('destroy', this.hide, this);
this.model.on('hide', this.hide, this); this.model.on('hide', this.hide, this);
...@@ -405,6 +411,8 @@ ...@@ -405,6 +411,8 @@
}, },
authenticate (ev) { authenticate (ev) {
/* Authenticate the user based on a form submission event.
*/
if (ev && ev.preventDefault) { ev.preventDefault(); } if (ev && ev.preventDefault) { ev.preventDefault(); }
const $form = $(ev.target); const $form = $(ev.target);
if (_converse.authentication === _converse.ANONYMOUS) { if (_converse.authentication === _converse.ANONYMOUS) {
...@@ -418,10 +426,14 @@ ...@@ -418,10 +426,14 @@
let jid = $jid_input.val(), let jid = $jid_input.val(),
errors = false; errors = false;
if (!jid || _.filter(jid.split('@')).length < 2) { if (!jid || (
!_converse.locked_domain &&
!_converse.default_domain &&
_.filter(jid.split('@')).length < 2)) {
errors = true; errors = true;
$jid_input.addClass('error'); $jid_input.addClass('error');
} }
if (!password && _converse.authentication !== _converse.EXTERNAL) { if (!password && _converse.authentication !== _converse.EXTERNAL) {
errors = true; errors = true;
$pw_input.addClass('error'); $pw_input.addClass('error');
......
...@@ -188,6 +188,7 @@ ...@@ -188,6 +188,7 @@
// Looks like _converse.initialized was called again without logging // Looks like _converse.initialized was called again without logging
// out or disconnecting in the previous session. // out or disconnecting in the previous session.
// This happens in tests. We therefore first clean up. // This happens in tests. We therefore first clean up.
delete _converse.controlboxtoggle;
_converse.connection.reset(); _converse.connection.reset();
_converse.off(); _converse.off();
_converse.stopListening(); _converse.stopListening();
......
...@@ -65,16 +65,16 @@ ...@@ -65,16 +65,16 @@
renderRegistrationPanel () { renderRegistrationPanel () {
this.__super__.renderRegistrationPanel.apply(this, arguments); this.__super__.renderRegistrationPanel.apply(this, arguments);
if (this.__super__._converse.allow_registration) {
const el = document.getElementById('converse-register'); const el = document.getElementById('converse-register');
el.parentNode.insertBefore(createBrandHeadingElement(), el); el.parentNode.insertBefore(createBrandHeadingElement(), el);
}
return this; return this;
}, },
renderLoginPanel () { renderLoginPanel () {
this.__super__.renderLoginPanel.apply(this, arguments); this.__super__.renderLoginPanel.apply(this, arguments);
this.el.classList.add("fullscreen"); this.el.classList.add("fullscreen");
const el = document.getElementById('converse-login'); const el = document.getElementById('converse-login');
el.parentNode.insertBefore(createBrandHeadingElement(), el); el.parentNode.insertBefore(createBrandHeadingElement(), el);
return this; return this;
......
...@@ -13,9 +13,7 @@ ...@@ -13,9 +13,7 @@
"tpl!toggle_chats", "tpl!toggle_chats",
"tpl!trimmed_chat", "tpl!trimmed_chat",
"tpl!chats_panel", "tpl!chats_panel",
"converse-chatview", "converse-chatview"
"converse-controlbox",
"converse-muc"
], factory); ], factory);
}(this, function ( }(this, function (
$, $,
...@@ -30,6 +28,20 @@ ...@@ -30,6 +28,20 @@
const { _ , utils, Backbone, Promise, Strophe, b64_sha1, moment } = converse.env; const { _ , utils, Backbone, Promise, Strophe, b64_sha1, moment } = converse.env;
converse.plugins.add('converse-minimize', { converse.plugins.add('converse-minimize', {
/* Optional dependencies are other plugins which might be
* overridden or relied upon, and therefore need to be loaded before
* this plugin. They are called "optional" because they might not be
* available, in which case any overrides applicable to them will be
* ignored.
*
* It's possible however to make optional dependencies non-optional.
* If the setting "strict_plugin_dependencies" is set to true,
* an error will be raised if the plugin is not found.
*
* NB: These plugins need to have already been loaded via require.js.
*/
optional_dependencies: ["converse-controlbox", "converse-muc"],
overrides: { overrides: {
// Overrides mentioned here will be picked up by converse.js's // Overrides mentioned here will be picked up by converse.js's
// plugin architecture they will replace existing methods on the // plugin architecture they will replace existing methods on the
...@@ -127,12 +139,13 @@ ...@@ -127,12 +139,13 @@
maximize () { maximize () {
// Restores a minimized chat box // Restores a minimized chat box
const { _converse } = this.__super__; const { _converse } = this.__super__;
this.$el.insertAfter(_converse.chatboxviews.get("controlbox").$el); this.insertIntoDOM();
if (!this.model.isScrolledUp()) { if (!this.model.isScrolledUp()) {
this.model.clearUnreadMsgCounter(); this.model.clearUnreadMsgCounter();
} }
this.show(); this.show();
_converse.emit('chatBoxMaximized', this); this.__super__._converse.emit('chatBoxMaximized', this);
return this; return this;
}, },
...@@ -177,11 +190,12 @@ ...@@ -177,11 +190,12 @@
const html = this.__super__.generateHeadingHTML.apply(this, arguments); const html = this.__super__.generateHeadingHTML.apply(this, arguments);
const div = document.createElement('div'); const div = document.createElement('div');
div.innerHTML = html; div.innerHTML = html;
const el = tpl_chatbox_minimize(
{info_minimize: __('Minimize this chat box')}
);
const button = div.querySelector('.close-chatbox-button'); const button = div.querySelector('.close-chatbox-button');
button.insertAdjacentHTML('afterend', el); button.insertAdjacentHTML('afterend',
tpl_chatbox_minimize({
'info_minimize': __('Minimize this chat box')
})
);
return div.innerHTML; return div.innerHTML;
} }
}, },
...@@ -242,7 +256,7 @@ ...@@ -242,7 +256,7 @@
// fullscreen. In this case we don't trim. // fullscreen. In this case we don't trim.
return; return;
} }
_converse.api.waitUntil('chatBoxesInitialized').then(() => { _converse.api.waitUntil('minimizedChatsInitialized').then(() => {
const $minimized = _.get(_converse.minimized_chats, '$el'), const $minimized = _.get(_converse.minimized_chats, '$el'),
minimized_width = _.includes(this.model.pluck('minimized'), true) ? $minimized.outerWidth(true) : 0, 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;
...@@ -369,12 +383,27 @@ ...@@ -369,12 +383,27 @@
initialize () { initialize () {
this.render(); this.render();
this.initToggle(); this.initToggle();
this.addMultipleChats(this.model.where({'minimized': true}));
this.model.on("add", this.onChanged, this); this.model.on("add", this.onChanged, this);
this.model.on("destroy", this.removeChat, this); this.model.on("destroy", this.removeChat, this);
this.model.on("change:minimized", this.onChanged, this); this.model.on("change:minimized", this.onChanged, this);
this.model.on('change:num_unread', this.updateUnreadMessagesCounter, this); this.model.on('change:num_unread', this.updateUnreadMessagesCounter, this);
}, },
render () {
if (!this.el.parentElement) {
this.el.innerHTML = tpl_chats_panel();
_converse.chatboxviews.el.appendChild(this.el);
}
if (this.keys().length === 0) {
this.el.classList.add('hidden');
} else if (this.keys().length > 0 && !this.$el.is(':visible')) {
this.el.classList.remove('hidden');
_converse.chatboxviews.trimChats();
}
return this.$el;
},
tearDown () { tearDown () {
this.model.off("add", this.onChanged); this.model.off("add", this.onChanged);
this.model.off("destroy", this.removeChat); this.model.off("destroy", this.removeChat);
...@@ -393,21 +422,6 @@ ...@@ -393,21 +422,6 @@
this.toggleview.model.fetch(); this.toggleview.model.fetch();
}, },
render () {
if (!this.el.parentElement) {
this.el.innerHTML = tpl_chats_panel();
_converse.chatboxviews.el.appendChild(this.el);
}
if (this.keys().length === 0) {
this.el.classList.add('hidden');
_converse.chatboxviews.trimChats.bind(_converse.chatboxviews);
} else if (this.keys().length > 0 && !this.$el.is(':visible')) {
this.el.classList.remove('hidden');
_converse.chatboxviews.trimChats();
}
return this.$el;
},
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')});
...@@ -426,6 +440,20 @@ ...@@ -426,6 +440,20 @@
} }
}, },
addMultipleChats (items) {
_.each(items, (item) => {
const existing = this.get(item.get('id'));
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.render();
},
addChat (item) { addChat (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.parent().length !== 0) {
......
...@@ -525,19 +525,6 @@ ...@@ -525,19 +525,6 @@
return this; return this;
}, },
insertIntoDOM () {
if (document.querySelector('body').contains(this.el)) {
return;
}
const view = _converse.chatboxviews.get("controlbox");
if (view) {
this.$el.insertAfter(view.$el);
} else {
$('#conversejs').prepend(this.$el);
}
return this;
},
generateHeadingHTML () { generateHeadingHTML () {
/* Returns the heading HTML to be rendered. /* Returns the heading HTML to be rendered.
*/ */
......
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
}; };
_converse.onVCardError = function (jid, iq, errback) { _converse.onVCardError = function (jid, iq, errback) {
const contact = _converse.roster.get(jid); const contact = _.get(_converse.roster, jid);
if (contact) { if (contact) {
contact.save({ 'vcard_updated': moment().format() }); contact.save({ 'vcard_updated': moment().format() });
} }
......
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