Commit da06a62b authored by JC Brand's avatar JC Brand

Regenerated dist files

parent f0b12955
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
// 'prosody@conference.prosody.im', // 'prosody@conference.prosody.im',
// 'jdev@conference.jabber.org' // 'jdev@conference.jabber.org'
// ], // ],
websocket_url: 'ws://chat.example.org:5280/xmpp-websocket', // websocket_url: 'ws://chat.example.org:5280/xmpp-websocket',
view_mode: 'fullscreen', view_mode: 'fullscreen',
archived_messages_page_size: '500', archived_messages_page_size: '500',
allow_public_bookmarks: true, allow_public_bookmarks: true,
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
'discuss@conference.conversejs.org' 'discuss@conference.conversejs.org'
], ],
// 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',
debug: true debug: true
}); });
......
...@@ -10268,6 +10268,15 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -10268,6 +10268,15 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
}; };
}; };
u.rootContains = function (root, el) {
// The document element does not have the contains method in IE.
if (root === document && !root.contains) {
return document.head.contains(el) || document.body.contains(el);
}
return root.contains ? root.contains(el) : window.HTMLElement.prototype.contains.call(root, el);
};
u.createFragmentFromText = function (markup) { u.createFragmentFromText = function (markup) {
/* Returns a DocumentFragment containing DOM nodes based on the /* Returns a DocumentFragment containing DOM nodes based on the
* passed-in markup text. * passed-in markup text.
...@@ -10968,6 +10977,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -10968,6 +10977,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
_converse.chatboxviews.closeAllChatBoxes(); _converse.chatboxviews.closeAllChatBoxes();
if (_converse.bookmarks) {
_converse.bookmarks.reset();
}
delete _converse.controlboxtoggle; delete _converse.controlboxtoggle;
delete _converse.chatboxviews; delete _converse.chatboxviews;
...@@ -11044,7 +11057,6 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -11044,7 +11057,6 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
locales_url: 'locale/{{{locale}}}/LC_MESSAGES/converse.json', locales_url: 'locale/{{{locale}}}/LC_MESSAGES/converse.json',
locales: ['af', 'ar', 'bg', 'ca', 'de', 'es', 'eu', 'en', 'fr', 'he', 'hu', 'id', 'it', 'ja', 'nb', 'nl', 'pl', 'pt_BR', 'ru', 'tr', 'uk', 'zh_CN', 'zh_TW'], locales: ['af', 'ar', 'bg', 'ca', 'de', 'es', 'eu', 'en', 'fr', 'he', 'hu', 'id', 'it', 'ja', 'nb', 'nl', 'pl', 'pt_BR', 'ru', 'tr', 'uk', 'zh_CN', 'zh_TW'],
message_carbons: true, message_carbons: true,
message_storage: 'session',
nickname: undefined, nickname: undefined,
password: undefined, password: undefined,
prebind_url: null, prebind_url: null,
...@@ -11058,6 +11070,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -11058,6 +11070,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
storage: 'session', storage: 'session',
strict_plugin_dependencies: false, strict_plugin_dependencies: false,
synchronize_availability: true, synchronize_availability: true,
trusted: true,
view_mode: 'overlayed', view_mode: 'overlayed',
// Choices are 'overlayed', 'fullscreen', 'mobile' // Choices are 'overlayed', 'fullscreen', 'mobile'
websocket_url: undefined, websocket_url: undefined,
...@@ -11417,9 +11430,14 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -11417,9 +11430,14 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
}; };
this.clearSession = function () { this.clearSession = function () {
if (!_.isUndefined(this.session) && this.session.browserStorage) { if (!_converse.trusted) {
window.localStorage.clear();
window.sessionStorage.clear();
} else if (!_.isUndefined(this.session) && this.session.browserStorage) {
this.session.browserStorage._clear(); this.session.browserStorage._clear();
} }
_converse.emit('clearSession');
}; };
this.logOut = function () { this.logOut = function () {
...@@ -11531,14 +11549,6 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -11531,14 +11549,6 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
this.connection.send(carbons_iq); this.connection.send(carbons_iq);
}; };
this.unregisterPresenceHandler = function () {
if (!_.isUndefined(_converse.presence_ref)) {
_converse.connection.deleteHandler(_converse.presence_ref);
delete _converse.presence_ref;
}
};
this.sendInitialPresence = function () { this.sendInitialPresence = function () {
if (_converse.send_initial_presence) { if (_converse.send_initial_presence) {
_converse.xmppstatus.sendPresence(); _converse.xmppstatus.sendPresence();
...@@ -11798,7 +11808,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -11798,7 +11808,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
} else if (!this.jid) { } else if (!this.jid) {
throw new Error("attemptNonPreboundSession: If you use auto_login, " + "you also need to give either a jid value (and if " + "applicable a password) or you need to pass in a URL " + "from where the username and password can be fetched " + "(via credentials_url)."); throw new Error("attemptNonPreboundSession: If you use auto_login, " + "you also need to give either a jid value (and if " + "applicable a password) or you need to pass in a URL " + "from where the username and password can be fetched " + "(via credentials_url).");
} else { } else {
this.autoLogin(); // Probably ANONYMOUS login this.autoLogin(); // Could be ANONYMOUS or EXTERNAL
} }
} else if (reconnecting) { } else if (reconnecting) {
this.autoLogin(); this.autoLogin();
...@@ -11812,7 +11822,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -11812,7 +11822,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
this.jid = credentials.jid; this.jid = credentials.jid;
} }
if (this.authentication === _converse.ANONYMOUS) { if (this.authentication === _converse.ANONYMOUS || this.authentication === _converse.EXTERNAL) {
if (!this.jid) { if (!this.jid) {
throw new Error("Config Error: when using anonymous login " + "you need to provide the server's domain via the 'jid' option. " + "Either when calling converse.initialize, or when calling " + "_converse.api.user.login."); throw new Error("Config Error: when using anonymous login " + "you need to provide the server's domain via the 'jid' option. " + "Either when calling converse.initialize, or when calling " + "_converse.api.user.login.");
} }
...@@ -11891,8 +11901,6 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -11891,8 +11901,6 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
*/ */
_converse.emit('beforeTearDown'); _converse.emit('beforeTearDown');
_converse.unregisterPresenceHandler();
if (!_.isUndefined(_converse.session)) { if (!_.isUndefined(_converse.session)) {
_converse.session.destroy(); _converse.session.destroy();
} }
...@@ -13549,8 +13557,8 @@ define("emojione", (function (global) { ...@@ -13549,8 +13557,8 @@ define("emojione", (function (global) {
throw new TypeError('disco.supports: You need to provide an entity JID'); throw new TypeError('disco.supports: You need to provide an entity JID');
} }
return _converse.api.waitUntil('discoInitialized').then(function () { return new Promise(function (resolve, reject) {
return new Promise(function (resolve, reject) { return _converse.api.waitUntil('discoInitialized').then(function () {
_converse.api.disco.entities.get(entity_jid, true).then(function (entity) { _converse.api.disco.entities.get(entity_jid, true).then(function (entity) {
entity.waitUntilFeaturesDiscovered.then(function () { entity.waitUntilFeaturesDiscovered.then(function () {
var promises = _.concat(entity.items.map(function (item) { var promises = _.concat(entity.items.map(function (item) {
...@@ -13561,8 +13569,8 @@ define("emojione", (function (global) { ...@@ -13561,8 +13569,8 @@ define("emojione", (function (global) {
resolve(f.filter(f.isObject, result)); resolve(f.filter(f.isObject, result));
}).catch(reject); }).catch(reject);
}).catch(reject); }).catch(reject);
}); }).catch(reject);
}); }).catch(reject);
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)); }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}, },
'getIdentity': function getIdentity(category, type, entity_jid) { 'getIdentity': function getIdentity(category, type, entity_jid) {
...@@ -16257,7 +16265,7 @@ return __p ...@@ -16257,7 +16265,7 @@ return __p
define('tpl!bookmark', ['lodash'], function(_) {return function(o) { define('tpl!bookmark', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<div class="list-item room-item available-chatroom d-flex flex-row '; __p += '<div class="list-item controlbox-padded room-item available-chatroom d-flex flex-row ';
if (o.hidden) { ; if (o.hidden) { ;
__p += ' hidden '; __p += ' hidden ';
} ; } ;
...@@ -16291,7 +16299,7 @@ return __p ...@@ -16291,7 +16299,7 @@ return __p
define('tpl!bookmarks_list', ['lodash'], function(_) {return function(o) { define('tpl!bookmarks_list', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<a href="#" class="rooms-toggle bookmarks-toggle" title="' + __p += '<a href="#" class="rooms-toggle bookmarks-toggle controlbox-padded" title="' +
__e(o.desc_bookmarks) + __e(o.desc_bookmarks) +
'">\n <span class="fa '; '">\n <span class="fa ';
if (o.toggle_state === o._converse.OPENED) { ; if (o.toggle_state === o._converse.OPENED) { ;
...@@ -16351,17 +16359,6 @@ return __p ...@@ -16351,17 +16359,6 @@ return __p
// relevant objects or classes. // relevant objects or classes.
// //
// New functions which don't exist yet can also be added. // New functions which don't exist yet can also be added.
clearSession: function clearSession() {
this.__super__.clearSession.apply(this, arguments);
if (!_.isUndefined(this.bookmarks)) {
this.bookmarks.reset();
this.bookmarks.browserStorage._clear();
window.sessionStorage.removeItem(this.bookmarks.fetched_flag);
}
},
ChatRoomView: { ChatRoomView: {
events: { events: {
'click .toggle-bookmark': 'toggleBookmark' 'click .toggle-bookmark': 'toggleBookmark'
...@@ -16788,7 +16785,7 @@ return __p ...@@ -16788,7 +16785,7 @@ return __p
insertIntoControlBox: function insertIntoControlBox() { insertIntoControlBox: function insertIntoControlBox() {
var controlboxview = _converse.chatboxviews.get('controlbox'); var controlboxview = _converse.chatboxviews.get('controlbox');
if (!_.isUndefined(controlboxview) && !_converse.root.contains(this.el)) { if (!_.isUndefined(controlboxview) && !u.rootContains(_converse.root, this.el)) {
var el = controlboxview.el.querySelector('.bookmarks-list'); var el = controlboxview.el.querySelector('.bookmarks-list');
if (!_.isNull(el)) { if (!_.isNull(el)) {
...@@ -16898,6 +16895,14 @@ return __p ...@@ -16898,6 +16895,14 @@ return __p
'event': 'roomsPanelRendered' 'event': 'roomsPanelRendered'
}], initBookmarks); }], initBookmarks);
_converse.on('clearSession', function () {
if (!_.isUndefined(_converse.bookmarks)) {
_converse.bookmarks.browserStorage._clear();
window.sessionStorage.removeItem(_converse.bookmarks.fetched_flag);
}
});
_converse.on('reconnected', initBookmarks); _converse.on('reconnected', initBookmarks);
_converse.on('connected', function () { _converse.on('connected', function () {
...@@ -21276,7 +21281,7 @@ return __p ...@@ -21276,7 +21281,7 @@ return __p
model: _converse.Message, model: _converse.Message,
comparator: 'time' comparator: 'time'
}); });
_converse.ChatBox = Backbone.Model.extend({ _converse.ChatBox = _converse.ModelWithVCardAndPresence.extend({
defaults: { defaults: {
'bookmarked': false, 'bookmarked': false,
'chat_state': undefined, 'chat_state': undefined,
...@@ -21288,15 +21293,7 @@ return __p ...@@ -21288,15 +21293,7 @@ return __p
initialize: function initialize() { initialize: function initialize() {
var _this4 = this; var _this4 = this;
this.vcard = _converse.vcards.findWhere({ _converse.ModelWithVCardAndPresence.prototype.initialize.apply(this, arguments);
'jid': this.get('jid')
});
if (_.isNil(this.vcard)) {
this.vcard = _converse.vcards.create({
'jid': this.get('jid')
});
}
_converse.api.waitUntil('rosterContactsFetched').then(function () { _converse.api.waitUntil('rosterContactsFetched').then(function () {
_this4.addRelatedContact(_converse.roster.findWhere({ _this4.addRelatedContact(_converse.roster.findWhere({
...@@ -21305,7 +21302,7 @@ return __p ...@@ -21305,7 +21302,7 @@ return __p
}); });
this.messages = new _converse.Messages(); this.messages = new _converse.Messages();
this.messages.browserStorage = new Backbone.BrowserStorage[_converse.message_storage](b64_sha1("converse.messages".concat(this.get('jid')).concat(_converse.bare_jid))); this.messages.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.messages".concat(this.get('jid')).concat(_converse.bare_jid)));
this.messages.chatbox = this; this.messages.chatbox = this;
this.messages.on('change:upload', function (message) { this.messages.on('change:upload', function (message) {
if (message.get('upload') === _converse.SUCCESS) { if (message.get('upload') === _converse.SUCCESS) {
...@@ -22604,9 +22601,8 @@ return __p ...@@ -22604,9 +22601,8 @@ return __p
this.model.messages.on('add', this.onMessageAdded, this); this.model.messages.on('add', this.onMessageAdded, this);
this.model.messages.on('rendered', this.scrollDown, this); this.model.messages.on('rendered', this.scrollDown, this);
this.model.on('show', this.show, this); this.model.on('show', this.show, this);
this.model.on('destroy', this.remove, this); // TODO check for changed fullname as well this.model.on('destroy', this.remove, this);
this.model.presence.on('change:show', this.onPresenceChanged, this);
this.model.on('change:chat_status', this.onChatStatusChanged, this);
this.model.on('showHelpMessages', this.showHelpMessages, this); this.model.on('showHelpMessages', this.showHelpMessages, this);
this.render(); this.render();
this.fetchMessages(); this.fetchMessages();
...@@ -22706,7 +22702,7 @@ return __p ...@@ -22706,7 +22702,7 @@ return __p
} }
var contact_jid = this.model.get('jid'); var contact_jid = this.model.get('jid');
var resources = this.model.get('resources'); var resources = this.model.presence.get('resources');
if (_.isEmpty(resources)) { if (_.isEmpty(resources)) {
return; return;
...@@ -22715,7 +22711,7 @@ return __p ...@@ -22715,7 +22711,7 @@ return __p
Promise.all(_.map(_.keys(resources), function (resource) { Promise.all(_.map(_.keys(resources), function (resource) {
return _converse.api.disco.supports(Strophe.NS.SPOILER, "".concat(contact_jid, "/").concat(resource)); return _converse.api.disco.supports(Strophe.NS.SPOILER, "".concat(contact_jid, "/").concat(resource));
})).then(function (results) { })).then(function (results) {
if (results.length) { if (_.filter(results, 'length').length) {
var html = tpl_spoiler_button(_this4.model.toJSON()); var html = tpl_spoiler_button(_this4.model.toJSON());
if (_converse.visible_toolbar_buttons.emoji) { if (_converse.visible_toolbar_buttons.emoji) {
...@@ -23130,7 +23126,11 @@ return __p ...@@ -23130,7 +23126,11 @@ return __p
} }
textarea.value = ''; textarea.value = '';
textarea.focus(); textarea.focus(); // Trigger input event, so that the textarea resizes
var event = document.createEvent('Event');
event.initEvent('input', true, true);
textarea.dispatchEvent(event);
if (message !== '') { if (message !== '') {
this.onMessageSubmitted(message, spoiler_hint); this.onMessageSubmitted(message, spoiler_hint);
...@@ -23243,20 +23243,19 @@ return __p ...@@ -23243,20 +23243,19 @@ return __p
toggle_el.setAttribute("data-toggle-state", "closed"); toggle_el.setAttribute("data-toggle-state", "closed");
} }
}, },
onChatStatusChanged: function onChatStatusChanged(item) { onPresenceChanged: function onPresenceChanged(item) {
var chat_status = item.get('chat_status'); var show = item.get('show'),
var fullname = item.get('fullname'); fullname = this.model.getDisplayName();
var text; var text;
fullname = _.isEmpty(fullname) ? item.get('jid') : fullname;
if (u.isVisible(this.el)) { if (u.isVisible(this.el)) {
if (chat_status === 'offline') { if (show === 'offline') {
text = fullname + ' ' + __('has gone offline'); text = fullname + ' ' + __('has gone offline');
} else if (chat_status === 'away') { } else if (show === 'away') {
text = fullname + ' ' + __('has gone away'); text = fullname + ' ' + __('has gone away');
} else if (chat_status === 'dnd') { } else if (show === 'dnd') {
text = fullname + ' ' + __('is busy'); text = fullname + ' ' + __('is busy');
} else if (chat_status === 'online') { } else if (show === 'online') {
text = fullname + ' ' + __('is online'); text = fullname + ' ' + __('is online');
} }
...@@ -23477,7 +23476,7 @@ return __p ...@@ -23477,7 +23476,7 @@ return __p
define('tpl!login_panel', ['lodash'], function(_) {return function(o) { define('tpl!login_panel', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<div id="converse-login-panel" class="controlbox-pane fade-in row">\n <form id="converse-login" class="converse-form" method="post">\n <div class="conn-feedback fade-in '; __p += '<div id="converse-login-panel" class="controlbox-pane fade-in row no-gutters">\n <form id="converse-login" class="converse-form" method="post">\n <div class="conn-feedback fade-in ';
if (!o.conn_feedback_subject) { ; if (!o.conn_feedback_subject) { ;
__p += ' hidden '; __p += ' hidden ';
} ; } ;
...@@ -23497,20 +23496,28 @@ __p += '\n <span class="spinner fa fa-spinner centered"/>\n '; ...@@ -23497,20 +23496,28 @@ __p += '\n <span class="spinner fa fa-spinner centered"/>\n ';
} else { ; } else { ;
__p += '\n '; __p += '\n ';
if (o.authentication == o.LOGIN || o.authentication == o.EXTERNAL) { ; if (o.authentication == o.LOGIN || o.authentication == o.EXTERNAL) { ;
__p += '\n <div class="form-group">\n <label for="jid">' + __p += '\n <div class="form-group">\n <label for="converse-login-jid">' +
__e(o.__("XMPP Username:")) + __e(o.__("XMPP Username:")) +
'</label>\n <input class="form-control" autofocus required="required" type="text" name="jid" placeholder="' + '</label>\n <input id="converse-login-jid" class="form-control" autofocus required="required" type="text" name="jid" placeholder="' +
__e(o.placeholder_username) + __e(o.placeholder_username) +
'">\n </div>\n '; '">\n </div>\n ';
if (o.authentication !== o.EXTERNAL) { ; if (o.authentication !== o.EXTERNAL) { ;
__p += '\n <div class="form-group">\n <label for="password">' + __p += '\n <div class="form-group">\n <label for="converse-login-password">' +
__e(o.__("Password:")) + __e(o.__("Password:")) +
'</label>\n <input class="form-control" required="required" type="password" name="password" placeholder="' + '</label>\n <input id="converse-login-password" class="form-control" required="required" type="password" name="password" placeholder="' +
__e(o.__('password')) + __e(o.__('password')) +
'">\n </div>\n '; '">\n </div>\n ';
} ; } ;
__p += '\n <fieldset class="buttons">\n <input class="btn btn-primary" type="submit" value="' + __p += '\n <div class="form-group form-check">\n <input id="converse-login-trusted" type="checkbox" class="form-check-input" name="trusted" ';
__e(o.__('Submit')) + if (o._converse.trusted) { ;
__p += ' checked="checked" ';
} ;
__p += '>\n <label for="converse-login-trusted" class="form-check-label">' +
__e(o.__('This is a trusted device')) +
'</label>\n <i class="fa fa-info-circle" data-toggle="popover"\n data-title="Trusted device?"\n data-content="' +
__e(o.__('To improve performance, we cache your data in this browser. Uncheck this box if this is a public computer or if you want your data to be deleted when you log out. It\'s important that you explicitly log out, otherwise not all cached data might be deleted.')) +
'"></i>\n </div>\n\n <fieldset class="buttons">\n <input class="btn btn-primary" type="submit" value="' +
__e(o.__('Log in')) +
'">\n </fieldset>\n '; '">\n </fieldset>\n ';
} ; } ;
__p += '\n '; __p += '\n ';
...@@ -23575,7 +23582,7 @@ return __p ...@@ -23575,7 +23582,7 @@ return __p
define('tpl!group_header', ['lodash'], function(_) {return function(o) { define('tpl!group_header', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<a href="#" class="group-toggle" title="' + __p += '<a href="#" class="group-toggle controlbox-padded" title="' +
__e(o.desc_group_toggle) + __e(o.desc_group_toggle) +
'">\n <span class="fa '; '">\n <span class="fa ';
if (o.toggle_state === o._converse.OPENED) { ; if (o.toggle_state === o._converse.OPENED) { ;
...@@ -23646,7 +23653,7 @@ return __p ...@@ -23646,7 +23653,7 @@ return __p
define('tpl!roster', ['lodash'], function(_) {return function(o) { define('tpl!roster', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape; var __t, __p = '', __e = _.escape;
__p += '<div class="d-flex">\n <span class="w-100 controlbox-heading">' + __p += '<div class="d-flex controlbox-padded">\n <span class="w-100 controlbox-heading">' +
__e(o.heading_contacts) + __e(o.heading_contacts) +
'</span>\n <a class="chatbox-btn add-contact fa fa-user-plus" title="' + '</span>\n <a class="chatbox-btn add-contact fa fa-user-plus" title="' +
__e(o.title_add_contact) + __e(o.title_add_contact) +
...@@ -23658,7 +23665,7 @@ return __p ...@@ -23658,7 +23665,7 @@ return __p
define('tpl!roster_filter', ['lodash'], function(_) {return function(o) { define('tpl!roster_filter', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<form class="roster-filter-form input-button-group '; __p += '<form class="controlbox-padded roster-filter-form input-button-group ';
if (!o.visible) { ; if (!o.visible) { ;
__p += ' hidden '; __p += ' hidden ';
} ; } ;
...@@ -23980,7 +23987,7 @@ return __p ...@@ -23980,7 +23987,7 @@ return __p
}; };
name_input.addEventListener('input', _.debounce(function () { name_input.addEventListener('input', _.debounce(function () {
xhr.open("GET", "".concat(_converse.xhr_user_search_url, "?q=").concat(name_input.value), true); xhr.open("GET", "".concat(_converse.xhr_user_search_url, "q=").concat(name_input.value), true);
xhr.send(); xhr.send();
}, 300)); }, 300));
this.el.addEventListener('awesomplete-selectcomplete', function (ev) { this.el.addEventListener('awesomplete-selectcomplete', function (ev) {
...@@ -24148,7 +24155,7 @@ return __p ...@@ -24148,7 +24155,7 @@ return __p
}); });
_converse.RosterContactView = Backbone.NativeView.extend({ _converse.RosterContactView = Backbone.NativeView.extend({
tagName: 'li', tagName: 'li',
className: 'd-flex hidden', className: 'd-flex hidden controlbox-padded',
events: { events: {
"click .accept-xmpp-request": "acceptRequest", "click .accept-xmpp-request": "acceptRequest",
"click .decline-xmpp-request": "declineRequest", "click .decline-xmpp-request": "declineRequest",
...@@ -24160,6 +24167,7 @@ return __p ...@@ -24160,6 +24167,7 @@ return __p
this.model.on("destroy", this.remove, this); this.model.on("destroy", this.remove, this);
this.model.on("open", this.openChat, this); this.model.on("open", this.openChat, this);
this.model.on("remove", this.remove, this); this.model.on("remove", this.remove, this);
this.model.presence.on("change:show", this.render, this);
this.model.vcard.on('change:fullname', this.render, this); this.model.vcard.on('change:fullname', this.render, this);
}, },
render: function render() { render: function render() {
...@@ -24172,7 +24180,7 @@ return __p ...@@ -24172,7 +24180,7 @@ return __p
var item = this.model, var item = this.model,
ask = item.get('ask'), ask = item.get('ask'),
chat_status = item.get('chat_status'), show = item.presence.get('show'),
requesting = item.get('requesting'), requesting = item.get('requesting'),
subscription = item.get('subscription'); subscription = item.get('subscription');
var classes_to_remove = ['current-xmpp-contact', 'pending-xmpp-contact', 'requesting-xmpp-contact'].concat(_.keys(STATUSES)); var classes_to_remove = ['current-xmpp-contact', 'pending-xmpp-contact', 'requesting-xmpp-contact'].concat(_.keys(STATUSES));
...@@ -24183,8 +24191,8 @@ return __p ...@@ -24183,8 +24191,8 @@ return __p
} }
}); });
this.el.classList.add(chat_status); this.el.classList.add(show);
this.el.setAttribute('data-status', chat_status); this.el.setAttribute('data-status', show);
if (ask === 'subscribe' || subscription === 'from') { if (ask === 'subscribe' || subscription === 'from') {
/* ask === 'subscribe' /* ask === 'subscribe'
...@@ -24226,22 +24234,22 @@ return __p ...@@ -24226,22 +24234,22 @@ return __p
}, },
renderRosterItem: function renderRosterItem(item) { renderRosterItem: function renderRosterItem(item) {
var status_icon = 'fa-times-circle'; var status_icon = 'fa-times-circle';
var chat_status = item.get('chat_status') || 'offline'; var show = item.presence.get('show') || 'offline';
if (chat_status === 'online') { if (show === 'online') {
status_icon = 'fa-circle'; status_icon = 'fa-circle';
} else if (chat_status === 'away') { } else if (show === 'away') {
status_icon = 'fa-dot-circle-o'; status_icon = 'fa-dot-circle-o';
} else if (chat_status === 'xa') { } else if (show === 'xa') {
status_icon = 'fa-circle-o'; status_icon = 'fa-circle-o';
} else if (chat_status === 'dnd') { } else if (show === 'dnd') {
status_icon = 'fa-minus-circle'; status_icon = 'fa-minus-circle';
} }
var display_name = item.getDisplayName(); var display_name = item.getDisplayName();
this.el.innerHTML = tpl_roster_item(_.extend(item.toJSON(), { this.el.innerHTML = tpl_roster_item(_.extend(item.toJSON(), {
'display_name': display_name, 'display_name': display_name,
'desc_status': STATUSES[chat_status], 'desc_status': STATUSES[show],
'status_icon': status_icon, 'status_icon': status_icon,
'desc_chat': __('Click to chat with %1$s (JID: %2$s)', display_name, item.get('jid')), 'desc_chat': __('Click to chat with %1$s (JID: %2$s)', display_name, item.get('jid')),
'desc_remove': __('Click to remove %1$s as a contact', display_name), 'desc_remove': __('Click to remove %1$s as a contact', display_name),
...@@ -24257,7 +24265,7 @@ return __p ...@@ -24257,7 +24265,7 @@ return __p
* It doesn't check for the more specific case of whether * It doesn't check for the more specific case of whether
* the group it's in is collapsed. * the group it's in is collapsed.
*/ */
var chatStatus = this.model.get('chat_status'); var chatStatus = this.model.presence.get('show');
if (_converse.show_only_online_users && chatStatus !== 'online' || _converse.hide_offline_users && chatStatus === 'offline') { if (_converse.show_only_online_users && chatStatus !== 'online' || _converse.hide_offline_users && chatStatus === 'offline') {
// If pending or requesting, show // If pending or requesting, show
...@@ -24338,7 +24346,7 @@ return __p ...@@ -24338,7 +24346,7 @@ return __p
ItemView: _converse.RosterContactView, ItemView: _converse.RosterContactView,
listItems: 'model.contacts', listItems: 'model.contacts',
listSelector: '.roster-group-contacts', listSelector: '.roster-group-contacts',
sortEvent: 'change:chat_status', sortEvent: 'presenceChanged',
initialize: function initialize() { initialize: function initialize() {
Backbone.OrderedListView.prototype.initialize.apply(this, arguments); Backbone.OrderedListView.prototype.initialize.apply(this, arguments);
this.model.contacts.on("change:subscription", this.onContactSubscriptionChange, this); this.model.contacts.on("change:subscription", this.onContactSubscriptionChange, this);
...@@ -24428,14 +24436,16 @@ return __p ...@@ -24428,14 +24436,16 @@ return __p
// show requesting contacts, even though they don't // show requesting contacts, even though they don't
// have the state in question. // have the state in question.
matches = this.model.contacts.filter(function (contact) { matches = this.model.contacts.filter(function (contact) {
return u.contains.not('chat_status', q)(contact) && !contact.get('requesting'); return !_.includes(contact.presence.get('show'), q) && !contact.get('requesting');
}); });
} else if (q === 'unread_messages') { } else if (q === 'unread_messages') {
matches = this.model.contacts.filter({ matches = this.model.contacts.filter({
'num_unread': 0 'num_unread': 0
}); });
} else { } else {
matches = this.model.contacts.filter(u.contains.not('chat_status', q)); matches = this.model.contacts.filter(function (contact) {
return !_.includes(contact.presence.get('show'), q);
});
} }
} else { } else {
matches = this.model.contacts.filter(function (contact) { matches = this.model.contacts.filter(function (contact) {
...@@ -24556,6 +24566,12 @@ return __p ...@@ -24556,6 +24566,12 @@ return __p
_converse.roster.on("remove", this.update, this); _converse.roster.on("remove", this.update, this);
_converse.presences.on('change:show', function () {
_this5.update();
_this5.updateFilter();
});
this.model.on("reset", this.reset, this); // This event gets triggered once *all* contacts (i.e. not this.model.on("reset", this.reset, this); // This event gets triggered once *all* contacts (i.e. not
// just this group's) have been fetched from browser // just this group's) have been fetched from browser
// storage or the XMPP server and once they've been // storage or the XMPP server and once they've been
...@@ -24667,11 +24683,13 @@ return __p ...@@ -24667,11 +24683,13 @@ return __p
return this; return this;
}, },
onContactAdded: function onContactAdded(contact) { onContactAdded: function onContactAdded(contact) {
this.addRosterContact(contact).update(); this.addRosterContact(contact);
this.update();
this.updateFilter(); this.updateFilter();
}, },
onContactChange: function onContactChange(contact) { onContactChange: function onContactChange(contact) {
this.updateChatBox(contact).update(); this.updateChatBox(contact);
this.update();
if (_.has(contact.changed, 'subscription')) { if (_.has(contact.changed, 'subscription')) {
if (contact.changed.subscription === 'from') { if (contact.changed.subscription === 'from') {
...@@ -24699,10 +24717,6 @@ return __p ...@@ -24699,10 +24717,6 @@ return __p
return this; return this;
} }
if (_.has(contact.changed, 'chat_status')) {
changes.chat_status = contact.get('chat_status');
}
if (_.has(contact.changed, 'status')) { if (_.has(contact.changed, 'status')) {
changes.status = contact.get('status'); changes.status = contact.get('status');
} }
...@@ -24967,7 +24981,7 @@ return __p ...@@ -24967,7 +24981,7 @@ return __p
define('tpl!profile_view', ['lodash'], function(_) {return function(o) { define('tpl!profile_view', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<div class="userinfo">\n<div class="profile d-flex">\n <a class="show-profile" href="#">\n <img alt="User Avatar" class="avatar align-self-center" height="40px" width="40px" src="data:' + __p += '<div class="userinfo controlbox-padded">\n<div class="profile d-flex">\n <a class="show-profile" href="#">\n <img alt="User Avatar" class="avatar align-self-center" height="40px" width="40px" src="data:' +
__e(o.image_type) + __e(o.image_type) +
';base64,' + ';base64,' +
__e(o.image) + __e(o.image) +
...@@ -25135,7 +25149,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -25135,7 +25149,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
if (result.image) { if (result.image) {
var word_array_from_b64 = CryptoJS.enc.Base64.parse(result['image']); var word_array_from_b64 = CryptoJS.enc.Base64.parse(result['image']);
result['image_type'] = CryptoJS.SHA1(word_array_from_b64).toString(); result['image_hash'] = CryptoJS.SHA1(word_array_from_b64).toString();
} }
if (callback) { if (callback) {
...@@ -25196,7 +25210,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -25196,7 +25210,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
_converse.initVCardCollection = function () { _converse.initVCardCollection = function () {
_converse.vcards = new _converse.VCards(); _converse.vcards = new _converse.VCards();
_converse.vcards.browserStorage = new Backbone.BrowserStorage.local(b64_sha1("converse.vcards")); _converse.vcards.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.vcards"));
_converse.vcards.fetch(); _converse.vcards.fetch();
}; };
...@@ -25488,8 +25502,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -25488,8 +25502,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
/*global define */ /*global define */
(function (root, factory) { (function (root, factory) {
define('converse-controlbox',["converse-core", "lodash.fp", "tpl!converse_brand_heading", "tpl!controlbox", "tpl!controlbox_toggle", "tpl!login_panel", "converse-chatview", "converse-rosterview", "converse-profile"], factory); define('converse-controlbox',["converse-core", "bootstrap", "lodash.fp", "tpl!converse_brand_heading", "tpl!controlbox", "tpl!controlbox_toggle", "tpl!login_panel", "converse-chatview", "converse-rosterview", "converse-profile"], factory);
})(this, function (converse, fp, tpl_brand_heading, tpl_controlbox, tpl_controlbox_toggle, tpl_login_panel) { })(this, function (converse, bootstrap, fp, tpl_brand_heading, tpl_controlbox, tpl_controlbox_toggle, tpl_login_panel) {
"use strict"; "use strict";
var CHATBOX_TYPE = 'chatbox'; var CHATBOX_TYPE = 'chatbox';
...@@ -25565,21 +25579,6 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -25565,21 +25579,6 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
this.rosterview.removeAll().remove(); this.rosterview.removeAll().remove();
} }
}, },
clearSession: function clearSession() {
this.__super__.clearSession.apply(this, arguments);
var chatboxes = _.get(this, 'chatboxes', null);
if (!_.isNil(chatboxes)) {
var controlbox = chatboxes.get('controlbox');
if (controlbox && controlbox.collection && controlbox.collection.browserStorage) {
controlbox.save({
'connected': false
});
}
}
},
ChatBoxes: { ChatBoxes: {
chatBoxMayBeShown: function chatBoxMayBeShown(chatbox) { chatBoxMayBeShown: function chatBoxMayBeShown(chatbox) {
return this.__super__.chatBoxMayBeShown.apply(this, arguments) && chatbox.get('id') !== 'controlbox'; return this.__super__.chatBoxMayBeShown.apply(this, arguments) && chatbox.get('id') !== 'controlbox';
...@@ -25882,6 +25881,15 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -25882,6 +25881,15 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
initialize: function initialize(cfg) { initialize: function initialize(cfg) {
this.model.on('change', this.render, this); this.model.on('change', this.render, this);
this.listenTo(_converse.connfeedback, 'change', this.render); this.listenTo(_converse.connfeedback, 'change', this.render);
this.render();
_.forEach(this.el.querySelectorAll('[data-title]'), function (el) {
var popover = new bootstrap.Popover(el, {
'trigger': _converse.view_mode === 'mobile' && 'click' || 'hover',
'dismissible': _converse.view_mode === 'mobile' && true || false,
'container': _converse.chatboxviews.el
});
});
}, },
toHTML: function toHTML() { toHTML: function toHTML() {
var connection_status = _converse.connfeedback.get('connection_status'); var connection_status = _converse.connfeedback.get('connection_status');
...@@ -25937,7 +25945,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -25937,7 +25945,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
return; return;
} }
var jid = ev.target.querySelector('input[name=jid]').value; var form_data = new FormData(ev.target);
_converse.trusted = form_data.get('trusted');
_converse.storage = form_data.get('trusted') ? 'local' : 'session';
var jid = form_data.get('jid');
if (_converse.locked_domain) { if (_converse.locked_domain) {
jid = Strophe.escapeNode(jid) + '@' + _converse.locked_domain; jid = Strophe.escapeNode(jid) + '@' + _converse.locked_domain;
...@@ -25945,7 +25956,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -25945,7 +25956,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
jid = jid + '@' + _converse.default_domain; jid = jid + '@' + _converse.default_domain;
} }
this.connect(jid, _.get(ev.target.querySelector('input[name=password]'), 'value')); this.connect(jid, form_data.get('password'));
}, },
connect: function connect(jid, password) { connect: function connect(jid, password) {
if (jid) { if (jid) {
...@@ -26044,6 +26055,23 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -26044,6 +26055,23 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
} }
} }
}); });
_converse.on('clearSession', function () {
if (_converse.trusted) {
var chatboxes = _.get(_converse, 'chatboxes', null);
if (!_.isNil(chatboxes)) {
var controlbox = chatboxes.get('controlbox');
if (controlbox && controlbox.collection && controlbox.collection.browserStorage) {
controlbox.save({
'connected': false
});
}
}
}
});
Promise.all([_converse.api.waitUntil('connectionInitialized'), _converse.api.waitUntil('chatBoxesInitialized')]).then(_converse.addControlBox).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)); Promise.all([_converse.api.waitUntil('connectionInitialized'), _converse.api.waitUntil('chatBoxesInitialized')]).then(_converse.addControlBox).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
_converse.on('chatBoxesFetched', function () { _converse.on('chatBoxesFetched', function () {
...@@ -28114,7 +28142,7 @@ return __p ...@@ -28114,7 +28142,7 @@ return __p
define('tpl!chatroom_head', ['lodash'], function(_) {return function(o) { define('tpl!chatroom_head', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<div class="col col-9">\n <div class="chat-title" title="' + __p += '<div class="col col-8">\n <div class="chat-title" title="' +
__e(o.jid) + __e(o.jid) +
'">\n '; '">\n ';
if (o.name && o.name !== o.Strophe.getNodeFromJid(o.jid)) { ; if (o.name && o.name !== o.Strophe.getNodeFromJid(o.jid)) { ;
...@@ -28432,7 +28460,7 @@ return __p ...@@ -28432,7 +28460,7 @@ return __p
define('tpl!room_panel', ['lodash'], function(_) {return function(o) { define('tpl!room_panel', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape; var __t, __p = '', __e = _.escape;
__p += '<!-- <div id="chatrooms"> -->\n<div class="d-flex">\n <span class="w-100 controlbox-heading">' + __p += '<!-- <div id="chatrooms"> -->\n<div class="d-flex controlbox-padded">\n <span class="w-100 controlbox-heading">' +
__e(o.heading_chatrooms) + __e(o.heading_chatrooms) +
'</span>\n <a class="chatbox-btn trigger-list-chatrooms-modal fa fa-list-ul" title="' + '</span>\n <a class="chatbox-btn trigger-list-chatrooms-modal fa fa-list-ul" title="' +
__e(o.title_list_rooms) + __e(o.title_list_rooms) +
...@@ -30558,7 +30586,7 @@ return __p ...@@ -30558,7 +30586,7 @@ return __p
}; };
_converse.handleChatStateNotification = function (contact) { _converse.handleChatStateNotification = function (contact) {
/* Event handler for on('contactStatusChanged'). /* Event handler for on('contactPresenceChanged').
* Will show an HTML5 notification to indicate that the chat * Will show an HTML5 notification to indicate that the chat
* status has changed. * status has changed.
*/ */
...@@ -30609,7 +30637,7 @@ return __p ...@@ -30609,7 +30637,7 @@ return __p
// handlers. // handlers.
_converse.on('contactRequest', _converse.handleContactRequestNotification); _converse.on('contactRequest', _converse.handleContactRequestNotification);
_converse.on('contactStatusChanged', _converse.handleChatStateNotification); _converse.on('contactPresenceChanged', _converse.handleChatStateNotification);
_converse.on('message', _converse.handleMessageNotification); _converse.on('message', _converse.handleMessageNotification);
...@@ -31338,18 +31366,8 @@ return __p ...@@ -31338,18 +31366,8 @@ return __p
dependencies: ["converse-vcard"], dependencies: ["converse-vcard"],
overrides: { overrides: {
clearSession () {
this.__super__.clearSession.apply(this, arguments);
if (!_.isUndefined(this.roster)) {
this.roster.browserStorage._clear();
}
},
_tearDown () { _tearDown () {
this.__super__._tearDown.apply(this, arguments); this.__super__._tearDown.apply(this, arguments);
if (this.roster) {
this.roster.off().reset(); // Removes roster contacts
}
} }
}, },
...@@ -31384,10 +31402,10 @@ return __p ...@@ -31384,10 +31402,10 @@ return __p
* roster and the roster groups. * roster and the roster groups.
*/ */
_converse.roster = new _converse.RosterContacts(); _converse.roster = new _converse.RosterContacts();
_converse.roster.browserStorage = new Backbone.BrowserStorage.session( _converse.roster.browserStorage = new Backbone.BrowserStorage[_converse.storage](
b64_sha1(`converse.contacts-${_converse.bare_jid}`)); b64_sha1(`converse.contacts-${_converse.bare_jid}`));
_converse.rostergroups = new _converse.RosterGroups(); _converse.rostergroups = new _converse.RosterGroups();
_converse.rostergroups.browserStorage = new Backbone.BrowserStorage.session( _converse.rostergroups.browserStorage = new Backbone.BrowserStorage[_converse.storage](
b64_sha1(`converse.roster.groups${_converse.bare_jid}`)); b64_sha1(`converse.roster.groups${_converse.bare_jid}`));
_converse.emit('rosterInitialized'); _converse.emit('rosterInitialized');
}; };
...@@ -31427,11 +31445,115 @@ return __p ...@@ -31427,11 +31445,115 @@ return __p
}; };
_converse.RosterContact = Backbone.Model.extend({ _converse.Presence = Backbone.Model.extend({
defaults: {
'show': 'offline',
'resources': {}
},
getHighestPriorityResource () {
/* Return the resource with the highest priority.
*
* If multiple resources have the same priority, take the
* latest one.
*/
const resources = this.get('resources');
if (_.isObject(resources) && _.size(resources)) {
const val = _.flow(
_.values,
_.partial(_.sortBy, _, ['priority', 'timestamp']),
_.reverse
)(resources)[0];
if (!_.isUndefined(val)) {
return val;
}
}
},
addResource (presence) {
/* Adds a new resource and it's associated attributes as taken
* from the passed in presence stanza.
*
* Also updates the presence if the resource has higher priority (and is newer).
*/
const jid = presence.getAttribute('from'),
show = _.propertyOf(presence.querySelector('show'))('textContent') || 'online',
resource = Strophe.getResourceFromJid(jid),
delay = presence.querySelector(
`delay[xmlns="${Strophe.NS.DELAY}"]`
),
timestamp = _.isNull(delay) ? moment().format() : moment(delay.getAttribute('stamp')).format();
let priority = _.propertyOf(presence.querySelector('priority'))('textContent') || 0;
priority = _.isNaN(parseInt(priority, 10)) ? 0 : parseInt(priority, 10);
const resources = _.isObject(this.get('resources')) ? this.get('resources') : {};
resources[resource] = {
'name': resource,
'priority': priority,
'show': show,
'timestamp': timestamp
};
const changed = {'resources': resources};
const hpr = this.getHighestPriorityResource();
if (priority == hpr.priority && timestamp == hpr.timestamp) {
// Only set the "global" presence if this is the newest resource
// with the highest priority
changed.show = show;
}
this.save(changed);
return resources;
},
removeResource (resource) {
/* Remove the passed in resource from the resources map.
*
* Also redetermines the presence given that there's one less
* resource.
*/
let resources = this.get('resources');
if (!_.isObject(resources)) {
resources = {};
} else {
delete resources[resource];
}
this.save({
'resources': resources,
'show': _.propertyOf(
this.getHighestPriorityResource())('show') || 'offline'
});
},
});
_converse.Presences = Backbone.Collection.extend({
model: _converse.Presence,
});
_converse.ModelWithVCardAndPresence = Backbone.Model.extend({
initialize () {
this.setVCard();
this.setPresence();
},
setVCard () {
const jid = this.get('jid');
this.vcard = _converse.vcards.findWhere({'jid': jid}) || _converse.vcards.create({'jid': jid});
},
setPresence () {
const jid = this.get('jid');
this.presence = _converse.presences.findWhere({'jid': jid}) || _converse.presences.create({'jid': jid});
}
});
_converse.RosterContact = _converse.ModelWithVCardAndPresence.extend({
defaults: { defaults: {
'chat_state': undefined, 'chat_state': undefined,
'chat_status': 'offline',
'image': _converse.DEFAULT_IMAGE, 'image': _converse.DEFAULT_IMAGE,
'image_type': _converse.DEFAULT_IMAGE_TYPE, 'image_type': _converse.DEFAULT_IMAGE_TYPE,
'num_unread': 0, 'num_unread': 0,
...@@ -31439,6 +31561,8 @@ return __p ...@@ -31439,6 +31561,8 @@ return __p
}, },
initialize (attributes) { initialize (attributes) {
_converse.ModelWithVCardAndPresence.prototype.initialize.apply(this, arguments);
const { jid } = attributes, const { jid } = attributes,
bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase(), bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase(),
resource = Strophe.getResourceFromJid(jid); resource = Strophe.getResourceFromJid(jid);
...@@ -31448,18 +31572,11 @@ return __p ...@@ -31448,18 +31572,11 @@ return __p
'groups': [], 'groups': [],
'id': bare_jid, 'id': bare_jid,
'jid': bare_jid, 'jid': bare_jid,
'resources': {},
'user_id': Strophe.getNodeFromJid(jid) 'user_id': Strophe.getNodeFromJid(jid)
}, attributes)); }, attributes));
this.vcard = _converse.vcards.findWhere({'jid': bare_jid}); this.presence.on('change:show', () => _converse.emit('contactPresenceChanged', this));
if (_.isNil(this.vcard)) { this.presence.on('change:show', () => this.trigger('presenceChanged'));
this.vcard = _converse.vcards.create({'jid': bare_jid});
}
this.on('change:chat_status', function (item) {
_converse.emit('contactStatusChanged', item.attributes);
});
}, },
getDisplayName () { getDisplayName () {
...@@ -31538,80 +31655,6 @@ return __p ...@@ -31538,80 +31655,6 @@ return __p
return this; return this;
}, },
addResource (presence) {
/* Adds a new resource and it's associated attributes as taken
* from the passed in presence stanza.
*
* Also updates the contact's chat_status if the presence has
* higher priority (and is newer).
*/
const jid = presence.getAttribute('from'),
chat_status = _.propertyOf(presence.querySelector('show'))('textContent') || 'online',
resource = Strophe.getResourceFromJid(jid),
delay = presence.querySelector(
`delay[xmlns="${Strophe.NS.DELAY}"]`
),
timestamp = _.isNull(delay) ? moment().format() : moment(delay.getAttribute('stamp')).format();
let priority = _.propertyOf(presence.querySelector('priority'))('textContent') || 0;
priority = _.isNaN(parseInt(priority, 10)) ? 0 : parseInt(priority, 10);
const resources = _.isObject(this.get('resources')) ? this.get('resources') : {};
resources[resource] = {
'name': resource,
'priority': priority,
'status': chat_status,
'timestamp': timestamp
};
const changed = {'resources': resources};
const hpr = this.getHighestPriorityResource();
if (priority == hpr.priority && timestamp == hpr.timestamp) {
// Only set the chat status if this is the newest resource
// with the highest priority
changed.chat_status = chat_status;
}
this.save(changed);
return resources;
},
removeResource (resource) {
/* Remove the passed in resource from the contact's resources map.
*
* Also recomputes the chat_status given that there's one less
* resource.
*/
let resources = this.get('resources');
if (!_.isObject(resources)) {
resources = {};
} else {
delete resources[resource];
}
this.save({
'resources': resources,
'chat_status': _.propertyOf(
this.getHighestPriorityResource())('status') || 'offline'
});
},
getHighestPriorityResource () {
/* Return the resource with the highest priority.
*
* If multiple resources have the same priority, take the
* newest one.
*/
const resources = this.get('resources');
if (_.isObject(resources) && _.size(resources)) {
const val = _.flow(
_.values,
_.partial(_.sortBy, _, ['priority', 'timestamp']),
_.reverse
)(resources)[0];
if (!_.isUndefined(val)) {
return val;
}
}
},
removeFromRoster (callback, errback) { removeFromRoster (callback, errback) {
/* Instruct the XMPP server to remove this contact from our roster /* Instruct the XMPP server to remove this contact from our roster
* Parameters: * Parameters:
...@@ -31630,8 +31673,8 @@ return __p ...@@ -31630,8 +31673,8 @@ return __p
model: _converse.RosterContact, model: _converse.RosterContact,
comparator (contact1, contact2) { comparator (contact1, contact2) {
const status1 = contact1.get('chat_status') || 'offline'; const status1 = contact1.presence.get('show') || 'offline';
const status2 = contact2.get('chat_status') || 'offline'; const status2 = contact2.presence.get('show') || 'offline';
if (_converse.STATUS_WEIGHTS[status1] === _converse.STATUS_WEIGHTS[status2]) { if (_converse.STATUS_WEIGHTS[status1] === _converse.STATUS_WEIGHTS[status2]) {
const name1 = (contact1.getDisplayName()).toLowerCase(); const name1 = (contact1.getDisplayName()).toLowerCase();
const name2 = (contact2.getDisplayName()).toLowerCase(); const name2 = (contact2.getDisplayName()).toLowerCase();
...@@ -31682,12 +31725,12 @@ return __p ...@@ -31682,12 +31725,12 @@ return __p
fetchRosterContacts () { fetchRosterContacts () {
/* Fetches the roster contacts, first by trying the /* Fetches the roster contacts, first by trying the
* sessionStorage cache, and if that's empty, then by querying * sessionStorage cache, and if that's empty, then by querying
* the XMPP server. * the XMPP server.
* *
* Returns a promise which resolves once the contacts have been * Returns a promise which resolves once the contacts have been
* fetched. * fetched.
*/ */
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.fetch({ this.fetch({
'add': true, 'add': true,
...@@ -31814,7 +31857,7 @@ return __p ...@@ -31814,7 +31857,7 @@ return __p
if (_converse.show_only_online_users) { if (_converse.show_only_online_users) {
ignored = _.union(ignored, ['dnd', 'xa', 'away']); ignored = _.union(ignored, ['dnd', 'xa', 'away']);
} }
return _.sum(this.models.filter((model) => !_.includes(ignored, model.get('chat_status')))); return _.sum(this.models.filter((model) => !_.includes(ignored, model.presence.get('show'))));
}, },
onRosterPush (iq) { onRosterPush (iq) {
...@@ -31962,7 +32005,6 @@ return __p ...@@ -31962,7 +32005,6 @@ return __p
const jid = presence.getAttribute('from'), const jid = presence.getAttribute('from'),
bare_jid = Strophe.getBareJidFromJid(jid), bare_jid = Strophe.getBareJidFromJid(jid),
resource = Strophe.getResourceFromJid(jid), resource = Strophe.getResourceFromJid(jid),
chat_status = _.propertyOf(presence.querySelector('show'))('textContent') || 'online',
status_message = _.propertyOf(presence.querySelector('status'))('textContent'), status_message = _.propertyOf(presence.querySelector('status'))('textContent'),
contact = this.get(bare_jid); contact = this.get(bare_jid);
...@@ -31974,7 +32016,8 @@ return __p ...@@ -31974,7 +32016,8 @@ return __p
// Another resource has changed its status and // Another resource has changed its status and
// synchronize_availability option set to update, // synchronize_availability option set to update,
// we'll update ours as well. // we'll update ours as well.
_converse.xmppstatus.save({'status': chat_status}); const show = _.propertyOf(presence.querySelector('show'))('textContent') || 'online';
_converse.xmppstatus.save({'status': show});
if (status_message) { if (status_message) {
_converse.xmppstatus.save({'status_message': status_message}); _converse.xmppstatus.save({'status_message': status_message});
} }
...@@ -32012,10 +32055,10 @@ return __p ...@@ -32012,10 +32055,10 @@ return __p
} else if (presence_type === 'subscribe') { } else if (presence_type === 'subscribe') {
this.handleIncomingSubscription(presence); this.handleIncomingSubscription(presence);
} else if (presence_type === 'unavailable' && contact) { } else if (presence_type === 'unavailable' && contact) {
contact.removeResource(resource); contact.presence.removeResource(resource);
} else if (contact) { } else if (contact) {
// presence_type is undefined // presence_type is undefined
contact.addResource(presence); contact.presence.addResource(presence);
} }
} }
}); });
...@@ -32054,9 +32097,37 @@ return __p ...@@ -32054,9 +32097,37 @@ return __p
} }
}); });
_converse.unregisterPresenceHandler = function () {
if (!_.isUndefined(_converse.presence_ref)) {
_converse.connection.deleteHandler(_converse.presence_ref);
delete _converse.presence_ref;
}
};
/********** Event Handlers *************/ /********** Event Handlers *************/
_converse.api.listen.on('beforeTearDown', _converse.unregisterPresenceHandler());
_converse.api.listen.on('afterTearDown', () => {
if (_converse.presence) {
_converse.presences.off().reset(); // Remove presences
}
});
_converse.api.listen.on('clearSession', () => {
if (!_.isUndefined(this.roster)) {
this.roster.browserStorage._clear();
}
});
_converse.api.listen.on('connectionInitialized', () => {
_converse.presences = new _converse.Presences();
_converse.presences.browserStorage =
new Backbone.BrowserStorage.session(b64_sha1(`converse.presences-${_converse.bare_jid}`));
_converse.presences.fetch();
});
_converse.api.listen.on('statusInitialized', (reconnecting) => { _converse.api.listen.on('statusInitialized', (reconnecting) => {
if (reconnecting) { if (reconnecting) {
// No need to recreate the roster, otherwise we lose our // No need to recreate the roster, otherwise we lose our
...@@ -32908,7 +32979,7 @@ return __p ...@@ -32908,7 +32979,7 @@ return __p
define('tpl!rooms_list', ['lodash'], function(_) {return function(o) { define('tpl!rooms_list', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<a href="#" class="rooms-toggle open-rooms-toggle" title="' + __p += '<a href="#" class="rooms-toggle open-rooms-toggle controlbox-padded" title="' +
__e(o.desc_rooms) + __e(o.desc_rooms) +
'">\n <span class="fa '; '">\n <span class="fa ';
if (o.toggle_state === o._converse.OPENED) { ; if (o.toggle_state === o._converse.OPENED) { ;
...@@ -32926,7 +32997,7 @@ return __p ...@@ -32926,7 +32997,7 @@ return __p
define('tpl!rooms_list_item', ['lodash'], function(_) {return function(o) { define('tpl!rooms_list_item', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<div class="list-item available-chatroom d-flex flex-row '; __p += '<div class="list-item controlbox-padded available-chatroom d-flex flex-row ';
if (o.num_unread_general) { ; if (o.num_unread_general) { ;
__p += ' unread-msgs '; __p += ' unread-msgs ';
} ; } ;
...@@ -33162,7 +33233,7 @@ return __p ...@@ -33162,7 +33233,7 @@ return __p
insertIntoControlBox: function insertIntoControlBox() { insertIntoControlBox: function insertIntoControlBox() {
var controlboxview = _converse.chatboxviews.get('controlbox'); var controlboxview = _converse.chatboxviews.get('controlbox');
if (!_.isUndefined(controlboxview) && !_converse.root.contains(this.el)) { if (!_.isUndefined(controlboxview) && !u.rootContains(_converse.root, this.el)) {
var el = controlboxview.el.querySelector('.open-rooms-list'); var el = controlboxview.el.querySelector('.open-rooms-list');
if (!_.isNull(el)) { if (!_.isNull(el)) {
...@@ -42396,6 +42396,15 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -42396,6 +42396,15 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
}; };
}; };
u.rootContains = function (root, el) {
// The document element does not have the contains method in IE.
if (root === document && !root.contains) {
return document.head.contains(el) || document.body.contains(el);
}
return root.contains ? root.contains(el) : window.HTMLElement.prototype.contains.call(root, el);
};
u.createFragmentFromText = function (markup) { u.createFragmentFromText = function (markup) {
/* Returns a DocumentFragment containing DOM nodes based on the /* Returns a DocumentFragment containing DOM nodes based on the
* passed-in markup text. * passed-in markup text.
...@@ -43543,6 +43552,10 @@ return Backbone.BrowserStorage; ...@@ -43543,6 +43552,10 @@ return Backbone.BrowserStorage;
_converse.chatboxviews.closeAllChatBoxes(); _converse.chatboxviews.closeAllChatBoxes();
if (_converse.bookmarks) {
_converse.bookmarks.reset();
}
delete _converse.controlboxtoggle; delete _converse.controlboxtoggle;
delete _converse.chatboxviews; delete _converse.chatboxviews;
...@@ -43619,7 +43632,6 @@ return Backbone.BrowserStorage; ...@@ -43619,7 +43632,6 @@ return Backbone.BrowserStorage;
locales_url: 'locale/{{{locale}}}/LC_MESSAGES/converse.json', locales_url: 'locale/{{{locale}}}/LC_MESSAGES/converse.json',
locales: ['af', 'ar', 'bg', 'ca', 'de', 'es', 'eu', 'en', 'fr', 'he', 'hu', 'id', 'it', 'ja', 'nb', 'nl', 'pl', 'pt_BR', 'ru', 'tr', 'uk', 'zh_CN', 'zh_TW'], locales: ['af', 'ar', 'bg', 'ca', 'de', 'es', 'eu', 'en', 'fr', 'he', 'hu', 'id', 'it', 'ja', 'nb', 'nl', 'pl', 'pt_BR', 'ru', 'tr', 'uk', 'zh_CN', 'zh_TW'],
message_carbons: true, message_carbons: true,
message_storage: 'session',
nickname: undefined, nickname: undefined,
password: undefined, password: undefined,
prebind_url: null, prebind_url: null,
...@@ -43633,6 +43645,7 @@ return Backbone.BrowserStorage; ...@@ -43633,6 +43645,7 @@ return Backbone.BrowserStorage;
storage: 'session', storage: 'session',
strict_plugin_dependencies: false, strict_plugin_dependencies: false,
synchronize_availability: true, synchronize_availability: true,
trusted: true,
view_mode: 'overlayed', view_mode: 'overlayed',
// Choices are 'overlayed', 'fullscreen', 'mobile' // Choices are 'overlayed', 'fullscreen', 'mobile'
websocket_url: undefined, websocket_url: undefined,
...@@ -43992,9 +44005,14 @@ return Backbone.BrowserStorage; ...@@ -43992,9 +44005,14 @@ return Backbone.BrowserStorage;
}; };
this.clearSession = function () { this.clearSession = function () {
if (!_.isUndefined(this.session) && this.session.browserStorage) { if (!_converse.trusted) {
window.localStorage.clear();
window.sessionStorage.clear();
} else if (!_.isUndefined(this.session) && this.session.browserStorage) {
this.session.browserStorage._clear(); this.session.browserStorage._clear();
} }
_converse.emit('clearSession');
}; };
this.logOut = function () { this.logOut = function () {
...@@ -44106,14 +44124,6 @@ return Backbone.BrowserStorage; ...@@ -44106,14 +44124,6 @@ return Backbone.BrowserStorage;
this.connection.send(carbons_iq); this.connection.send(carbons_iq);
}; };
this.unregisterPresenceHandler = function () {
if (!_.isUndefined(_converse.presence_ref)) {
_converse.connection.deleteHandler(_converse.presence_ref);
delete _converse.presence_ref;
}
};
this.sendInitialPresence = function () { this.sendInitialPresence = function () {
if (_converse.send_initial_presence) { if (_converse.send_initial_presence) {
_converse.xmppstatus.sendPresence(); _converse.xmppstatus.sendPresence();
...@@ -44373,7 +44383,7 @@ return Backbone.BrowserStorage; ...@@ -44373,7 +44383,7 @@ return Backbone.BrowserStorage;
} else if (!this.jid) { } else if (!this.jid) {
throw new Error("attemptNonPreboundSession: If you use auto_login, " + "you also need to give either a jid value (and if " + "applicable a password) or you need to pass in a URL " + "from where the username and password can be fetched " + "(via credentials_url)."); throw new Error("attemptNonPreboundSession: If you use auto_login, " + "you also need to give either a jid value (and if " + "applicable a password) or you need to pass in a URL " + "from where the username and password can be fetched " + "(via credentials_url).");
} else { } else {
this.autoLogin(); // Probably ANONYMOUS login this.autoLogin(); // Could be ANONYMOUS or EXTERNAL
} }
} else if (reconnecting) { } else if (reconnecting) {
this.autoLogin(); this.autoLogin();
...@@ -44387,7 +44397,7 @@ return Backbone.BrowserStorage; ...@@ -44387,7 +44397,7 @@ return Backbone.BrowserStorage;
this.jid = credentials.jid; this.jid = credentials.jid;
} }
if (this.authentication === _converse.ANONYMOUS) { if (this.authentication === _converse.ANONYMOUS || this.authentication === _converse.EXTERNAL) {
if (!this.jid) { if (!this.jid) {
throw new Error("Config Error: when using anonymous login " + "you need to provide the server's domain via the 'jid' option. " + "Either when calling converse.initialize, or when calling " + "_converse.api.user.login."); throw new Error("Config Error: when using anonymous login " + "you need to provide the server's domain via the 'jid' option. " + "Either when calling converse.initialize, or when calling " + "_converse.api.user.login.");
} }
...@@ -44466,8 +44476,6 @@ return Backbone.BrowserStorage; ...@@ -44466,8 +44476,6 @@ return Backbone.BrowserStorage;
*/ */
_converse.emit('beforeTearDown'); _converse.emit('beforeTearDown');
_converse.unregisterPresenceHandler();
if (!_.isUndefined(_converse.session)) { if (!_.isUndefined(_converse.session)) {
_converse.session.destroy(); _converse.session.destroy();
} }
...@@ -46124,8 +46132,8 @@ define("emojione", (function (global) { ...@@ -46124,8 +46132,8 @@ define("emojione", (function (global) {
throw new TypeError('disco.supports: You need to provide an entity JID'); throw new TypeError('disco.supports: You need to provide an entity JID');
} }
return _converse.api.waitUntil('discoInitialized').then(function () { return new Promise(function (resolve, reject) {
return new Promise(function (resolve, reject) { return _converse.api.waitUntil('discoInitialized').then(function () {
_converse.api.disco.entities.get(entity_jid, true).then(function (entity) { _converse.api.disco.entities.get(entity_jid, true).then(function (entity) {
entity.waitUntilFeaturesDiscovered.then(function () { entity.waitUntilFeaturesDiscovered.then(function () {
var promises = _.concat(entity.items.map(function (item) { var promises = _.concat(entity.items.map(function (item) {
...@@ -46136,8 +46144,8 @@ define("emojione", (function (global) { ...@@ -46136,8 +46144,8 @@ define("emojione", (function (global) {
resolve(f.filter(f.isObject, result)); resolve(f.filter(f.isObject, result));
}).catch(reject); }).catch(reject);
}).catch(reject); }).catch(reject);
}); }).catch(reject);
}); }).catch(reject);
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)); }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}, },
'getIdentity': function getIdentity(category, type, entity_jid) { 'getIdentity': function getIdentity(category, type, entity_jid) {
...@@ -48994,7 +49002,7 @@ return __p ...@@ -48994,7 +49002,7 @@ return __p
define('tpl!bookmark', ['lodash'], function(_) {return function(o) { define('tpl!bookmark', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<div class="list-item room-item available-chatroom d-flex flex-row '; __p += '<div class="list-item controlbox-padded room-item available-chatroom d-flex flex-row ';
if (o.hidden) { ; if (o.hidden) { ;
__p += ' hidden '; __p += ' hidden ';
} ; } ;
...@@ -49028,7 +49036,7 @@ return __p ...@@ -49028,7 +49036,7 @@ return __p
define('tpl!bookmarks_list', ['lodash'], function(_) {return function(o) { define('tpl!bookmarks_list', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<a href="#" class="rooms-toggle bookmarks-toggle" title="' + __p += '<a href="#" class="rooms-toggle bookmarks-toggle controlbox-padded" title="' +
__e(o.desc_bookmarks) + __e(o.desc_bookmarks) +
'">\n <span class="fa '; '">\n <span class="fa ';
if (o.toggle_state === o._converse.OPENED) { ; if (o.toggle_state === o._converse.OPENED) { ;
...@@ -49088,17 +49096,6 @@ return __p ...@@ -49088,17 +49096,6 @@ return __p
// relevant objects or classes. // relevant objects or classes.
// //
// New functions which don't exist yet can also be added. // New functions which don't exist yet can also be added.
clearSession: function clearSession() {
this.__super__.clearSession.apply(this, arguments);
if (!_.isUndefined(this.bookmarks)) {
this.bookmarks.reset();
this.bookmarks.browserStorage._clear();
window.sessionStorage.removeItem(this.bookmarks.fetched_flag);
}
},
ChatRoomView: { ChatRoomView: {
events: { events: {
'click .toggle-bookmark': 'toggleBookmark' 'click .toggle-bookmark': 'toggleBookmark'
...@@ -49525,7 +49522,7 @@ return __p ...@@ -49525,7 +49522,7 @@ return __p
insertIntoControlBox: function insertIntoControlBox() { insertIntoControlBox: function insertIntoControlBox() {
var controlboxview = _converse.chatboxviews.get('controlbox'); var controlboxview = _converse.chatboxviews.get('controlbox');
if (!_.isUndefined(controlboxview) && !_converse.root.contains(this.el)) { if (!_.isUndefined(controlboxview) && !u.rootContains(_converse.root, this.el)) {
var el = controlboxview.el.querySelector('.bookmarks-list'); var el = controlboxview.el.querySelector('.bookmarks-list');
if (!_.isNull(el)) { if (!_.isNull(el)) {
...@@ -49635,6 +49632,14 @@ return __p ...@@ -49635,6 +49632,14 @@ return __p
'event': 'roomsPanelRendered' 'event': 'roomsPanelRendered'
}], initBookmarks); }], initBookmarks);
_converse.on('clearSession', function () {
if (!_.isUndefined(_converse.bookmarks)) {
_converse.bookmarks.browserStorage._clear();
window.sessionStorage.removeItem(_converse.bookmarks.fetched_flag);
}
});
_converse.on('reconnected', initBookmarks); _converse.on('reconnected', initBookmarks);
_converse.on('connected', function () { _converse.on('connected', function () {
...@@ -54013,7 +54018,7 @@ return __p ...@@ -54013,7 +54018,7 @@ return __p
model: _converse.Message, model: _converse.Message,
comparator: 'time' comparator: 'time'
}); });
_converse.ChatBox = Backbone.Model.extend({ _converse.ChatBox = _converse.ModelWithVCardAndPresence.extend({
defaults: { defaults: {
'bookmarked': false, 'bookmarked': false,
'chat_state': undefined, 'chat_state': undefined,
...@@ -54025,15 +54030,7 @@ return __p ...@@ -54025,15 +54030,7 @@ return __p
initialize: function initialize() { initialize: function initialize() {
var _this4 = this; var _this4 = this;
this.vcard = _converse.vcards.findWhere({ _converse.ModelWithVCardAndPresence.prototype.initialize.apply(this, arguments);
'jid': this.get('jid')
});
if (_.isNil(this.vcard)) {
this.vcard = _converse.vcards.create({
'jid': this.get('jid')
});
}
_converse.api.waitUntil('rosterContactsFetched').then(function () { _converse.api.waitUntil('rosterContactsFetched').then(function () {
_this4.addRelatedContact(_converse.roster.findWhere({ _this4.addRelatedContact(_converse.roster.findWhere({
...@@ -54042,7 +54039,7 @@ return __p ...@@ -54042,7 +54039,7 @@ return __p
}); });
this.messages = new _converse.Messages(); this.messages = new _converse.Messages();
this.messages.browserStorage = new Backbone.BrowserStorage[_converse.message_storage](b64_sha1("converse.messages".concat(this.get('jid')).concat(_converse.bare_jid))); this.messages.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.messages".concat(this.get('jid')).concat(_converse.bare_jid)));
this.messages.chatbox = this; this.messages.chatbox = this;
this.messages.on('change:upload', function (message) { this.messages.on('change:upload', function (message) {
if (message.get('upload') === _converse.SUCCESS) { if (message.get('upload') === _converse.SUCCESS) {
...@@ -55312,9 +55309,8 @@ return __p ...@@ -55312,9 +55309,8 @@ return __p
this.model.messages.on('add', this.onMessageAdded, this); this.model.messages.on('add', this.onMessageAdded, this);
this.model.messages.on('rendered', this.scrollDown, this); this.model.messages.on('rendered', this.scrollDown, this);
this.model.on('show', this.show, this); this.model.on('show', this.show, this);
this.model.on('destroy', this.remove, this); // TODO check for changed fullname as well this.model.on('destroy', this.remove, this);
this.model.presence.on('change:show', this.onPresenceChanged, this);
this.model.on('change:chat_status', this.onChatStatusChanged, this);
this.model.on('showHelpMessages', this.showHelpMessages, this); this.model.on('showHelpMessages', this.showHelpMessages, this);
this.render(); this.render();
this.fetchMessages(); this.fetchMessages();
...@@ -55414,7 +55410,7 @@ return __p ...@@ -55414,7 +55410,7 @@ return __p
} }
var contact_jid = this.model.get('jid'); var contact_jid = this.model.get('jid');
var resources = this.model.get('resources'); var resources = this.model.presence.get('resources');
if (_.isEmpty(resources)) { if (_.isEmpty(resources)) {
return; return;
...@@ -55423,7 +55419,7 @@ return __p ...@@ -55423,7 +55419,7 @@ return __p
Promise.all(_.map(_.keys(resources), function (resource) { Promise.all(_.map(_.keys(resources), function (resource) {
return _converse.api.disco.supports(Strophe.NS.SPOILER, "".concat(contact_jid, "/").concat(resource)); return _converse.api.disco.supports(Strophe.NS.SPOILER, "".concat(contact_jid, "/").concat(resource));
})).then(function (results) { })).then(function (results) {
if (results.length) { if (_.filter(results, 'length').length) {
var html = tpl_spoiler_button(_this4.model.toJSON()); var html = tpl_spoiler_button(_this4.model.toJSON());
if (_converse.visible_toolbar_buttons.emoji) { if (_converse.visible_toolbar_buttons.emoji) {
...@@ -55838,7 +55834,11 @@ return __p ...@@ -55838,7 +55834,11 @@ return __p
} }
textarea.value = ''; textarea.value = '';
textarea.focus(); textarea.focus(); // Trigger input event, so that the textarea resizes
var event = document.createEvent('Event');
event.initEvent('input', true, true);
textarea.dispatchEvent(event);
if (message !== '') { if (message !== '') {
this.onMessageSubmitted(message, spoiler_hint); this.onMessageSubmitted(message, spoiler_hint);
...@@ -55951,20 +55951,19 @@ return __p ...@@ -55951,20 +55951,19 @@ return __p
toggle_el.setAttribute("data-toggle-state", "closed"); toggle_el.setAttribute("data-toggle-state", "closed");
} }
}, },
onChatStatusChanged: function onChatStatusChanged(item) { onPresenceChanged: function onPresenceChanged(item) {
var chat_status = item.get('chat_status'); var show = item.get('show'),
var fullname = item.get('fullname'); fullname = this.model.getDisplayName();
var text; var text;
fullname = _.isEmpty(fullname) ? item.get('jid') : fullname;
if (u.isVisible(this.el)) { if (u.isVisible(this.el)) {
if (chat_status === 'offline') { if (show === 'offline') {
text = fullname + ' ' + __('has gone offline'); text = fullname + ' ' + __('has gone offline');
} else if (chat_status === 'away') { } else if (show === 'away') {
text = fullname + ' ' + __('has gone away'); text = fullname + ' ' + __('has gone away');
} else if (chat_status === 'dnd') { } else if (show === 'dnd') {
text = fullname + ' ' + __('is busy'); text = fullname + ' ' + __('is busy');
} else if (chat_status === 'online') { } else if (show === 'online') {
text = fullname + ' ' + __('is online'); text = fullname + ' ' + __('is online');
} }
...@@ -56185,7 +56184,7 @@ return __p ...@@ -56185,7 +56184,7 @@ return __p
define('tpl!login_panel', ['lodash'], function(_) {return function(o) { define('tpl!login_panel', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<div id="converse-login-panel" class="controlbox-pane fade-in row">\n <form id="converse-login" class="converse-form" method="post">\n <div class="conn-feedback fade-in '; __p += '<div id="converse-login-panel" class="controlbox-pane fade-in row no-gutters">\n <form id="converse-login" class="converse-form" method="post">\n <div class="conn-feedback fade-in ';
if (!o.conn_feedback_subject) { ; if (!o.conn_feedback_subject) { ;
__p += ' hidden '; __p += ' hidden ';
} ; } ;
...@@ -56205,20 +56204,28 @@ __p += '\n <span class="spinner fa fa-spinner centered"/>\n '; ...@@ -56205,20 +56204,28 @@ __p += '\n <span class="spinner fa fa-spinner centered"/>\n ';
} else { ; } else { ;
__p += '\n '; __p += '\n ';
if (o.authentication == o.LOGIN || o.authentication == o.EXTERNAL) { ; if (o.authentication == o.LOGIN || o.authentication == o.EXTERNAL) { ;
__p += '\n <div class="form-group">\n <label for="jid">' + __p += '\n <div class="form-group">\n <label for="converse-login-jid">' +
__e(o.__("XMPP Username:")) + __e(o.__("XMPP Username:")) +
'</label>\n <input class="form-control" autofocus required="required" type="text" name="jid" placeholder="' + '</label>\n <input id="converse-login-jid" class="form-control" autofocus required="required" type="text" name="jid" placeholder="' +
__e(o.placeholder_username) + __e(o.placeholder_username) +
'">\n </div>\n '; '">\n </div>\n ';
if (o.authentication !== o.EXTERNAL) { ; if (o.authentication !== o.EXTERNAL) { ;
__p += '\n <div class="form-group">\n <label for="password">' + __p += '\n <div class="form-group">\n <label for="converse-login-password">' +
__e(o.__("Password:")) + __e(o.__("Password:")) +
'</label>\n <input class="form-control" required="required" type="password" name="password" placeholder="' + '</label>\n <input id="converse-login-password" class="form-control" required="required" type="password" name="password" placeholder="' +
__e(o.__('password')) + __e(o.__('password')) +
'">\n </div>\n '; '">\n </div>\n ';
} ; } ;
__p += '\n <fieldset class="buttons">\n <input class="btn btn-primary" type="submit" value="' + __p += '\n <div class="form-group form-check">\n <input id="converse-login-trusted" type="checkbox" class="form-check-input" name="trusted" ';
__e(o.__('Submit')) + if (o._converse.trusted) { ;
__p += ' checked="checked" ';
} ;
__p += '>\n <label for="converse-login-trusted" class="form-check-label">' +
__e(o.__('This is a trusted device')) +
'</label>\n <i class="fa fa-info-circle" data-toggle="popover"\n data-title="Trusted device?"\n data-content="' +
__e(o.__('To improve performance, we cache your data in this browser. Uncheck this box if this is a public computer or if you want your data to be deleted when you log out. It\'s important that you explicitly log out, otherwise not all cached data might be deleted.')) +
'"></i>\n </div>\n\n <fieldset class="buttons">\n <input class="btn btn-primary" type="submit" value="' +
__e(o.__('Log in')) +
'">\n </fieldset>\n '; '">\n </fieldset>\n ';
} ; } ;
__p += '\n '; __p += '\n ';
...@@ -56283,7 +56290,7 @@ return __p ...@@ -56283,7 +56290,7 @@ return __p
define('tpl!group_header', ['lodash'], function(_) {return function(o) { define('tpl!group_header', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<a href="#" class="group-toggle" title="' + __p += '<a href="#" class="group-toggle controlbox-padded" title="' +
__e(o.desc_group_toggle) + __e(o.desc_group_toggle) +
'">\n <span class="fa '; '">\n <span class="fa ';
if (o.toggle_state === o._converse.OPENED) { ; if (o.toggle_state === o._converse.OPENED) { ;
...@@ -56354,7 +56361,7 @@ return __p ...@@ -56354,7 +56361,7 @@ return __p
define('tpl!roster', ['lodash'], function(_) {return function(o) { define('tpl!roster', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape; var __t, __p = '', __e = _.escape;
__p += '<div class="d-flex">\n <span class="w-100 controlbox-heading">' + __p += '<div class="d-flex controlbox-padded">\n <span class="w-100 controlbox-heading">' +
__e(o.heading_contacts) + __e(o.heading_contacts) +
'</span>\n <a class="chatbox-btn add-contact fa fa-user-plus" title="' + '</span>\n <a class="chatbox-btn add-contact fa fa-user-plus" title="' +
__e(o.title_add_contact) + __e(o.title_add_contact) +
...@@ -56366,7 +56373,7 @@ return __p ...@@ -56366,7 +56373,7 @@ return __p
define('tpl!roster_filter', ['lodash'], function(_) {return function(o) { define('tpl!roster_filter', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<form class="roster-filter-form input-button-group '; __p += '<form class="controlbox-padded roster-filter-form input-button-group ';
if (!o.visible) { ; if (!o.visible) { ;
__p += ' hidden '; __p += ' hidden ';
} ; } ;
...@@ -57204,7 +57211,7 @@ define("awesomplete", (function (global) { ...@@ -57204,7 +57211,7 @@ define("awesomplete", (function (global) {
}; };
name_input.addEventListener('input', _.debounce(function () { name_input.addEventListener('input', _.debounce(function () {
xhr.open("GET", "".concat(_converse.xhr_user_search_url, "?q=").concat(name_input.value), true); xhr.open("GET", "".concat(_converse.xhr_user_search_url, "q=").concat(name_input.value), true);
xhr.send(); xhr.send();
}, 300)); }, 300));
this.el.addEventListener('awesomplete-selectcomplete', function (ev) { this.el.addEventListener('awesomplete-selectcomplete', function (ev) {
...@@ -57372,7 +57379,7 @@ define("awesomplete", (function (global) { ...@@ -57372,7 +57379,7 @@ define("awesomplete", (function (global) {
}); });
_converse.RosterContactView = Backbone.NativeView.extend({ _converse.RosterContactView = Backbone.NativeView.extend({
tagName: 'li', tagName: 'li',
className: 'd-flex hidden', className: 'd-flex hidden controlbox-padded',
events: { events: {
"click .accept-xmpp-request": "acceptRequest", "click .accept-xmpp-request": "acceptRequest",
"click .decline-xmpp-request": "declineRequest", "click .decline-xmpp-request": "declineRequest",
...@@ -57384,6 +57391,7 @@ define("awesomplete", (function (global) { ...@@ -57384,6 +57391,7 @@ define("awesomplete", (function (global) {
this.model.on("destroy", this.remove, this); this.model.on("destroy", this.remove, this);
this.model.on("open", this.openChat, this); this.model.on("open", this.openChat, this);
this.model.on("remove", this.remove, this); this.model.on("remove", this.remove, this);
this.model.presence.on("change:show", this.render, this);
this.model.vcard.on('change:fullname', this.render, this); this.model.vcard.on('change:fullname', this.render, this);
}, },
render: function render() { render: function render() {
...@@ -57396,7 +57404,7 @@ define("awesomplete", (function (global) { ...@@ -57396,7 +57404,7 @@ define("awesomplete", (function (global) {
var item = this.model, var item = this.model,
ask = item.get('ask'), ask = item.get('ask'),
chat_status = item.get('chat_status'), show = item.presence.get('show'),
requesting = item.get('requesting'), requesting = item.get('requesting'),
subscription = item.get('subscription'); subscription = item.get('subscription');
var classes_to_remove = ['current-xmpp-contact', 'pending-xmpp-contact', 'requesting-xmpp-contact'].concat(_.keys(STATUSES)); var classes_to_remove = ['current-xmpp-contact', 'pending-xmpp-contact', 'requesting-xmpp-contact'].concat(_.keys(STATUSES));
...@@ -57407,8 +57415,8 @@ define("awesomplete", (function (global) { ...@@ -57407,8 +57415,8 @@ define("awesomplete", (function (global) {
} }
}); });
this.el.classList.add(chat_status); this.el.classList.add(show);
this.el.setAttribute('data-status', chat_status); this.el.setAttribute('data-status', show);
if (ask === 'subscribe' || subscription === 'from') { if (ask === 'subscribe' || subscription === 'from') {
/* ask === 'subscribe' /* ask === 'subscribe'
...@@ -57450,22 +57458,22 @@ define("awesomplete", (function (global) { ...@@ -57450,22 +57458,22 @@ define("awesomplete", (function (global) {
}, },
renderRosterItem: function renderRosterItem(item) { renderRosterItem: function renderRosterItem(item) {
var status_icon = 'fa-times-circle'; var status_icon = 'fa-times-circle';
var chat_status = item.get('chat_status') || 'offline'; var show = item.presence.get('show') || 'offline';
if (chat_status === 'online') { if (show === 'online') {
status_icon = 'fa-circle'; status_icon = 'fa-circle';
} else if (chat_status === 'away') { } else if (show === 'away') {
status_icon = 'fa-dot-circle-o'; status_icon = 'fa-dot-circle-o';
} else if (chat_status === 'xa') { } else if (show === 'xa') {
status_icon = 'fa-circle-o'; status_icon = 'fa-circle-o';
} else if (chat_status === 'dnd') { } else if (show === 'dnd') {
status_icon = 'fa-minus-circle'; status_icon = 'fa-minus-circle';
} }
var display_name = item.getDisplayName(); var display_name = item.getDisplayName();
this.el.innerHTML = tpl_roster_item(_.extend(item.toJSON(), { this.el.innerHTML = tpl_roster_item(_.extend(item.toJSON(), {
'display_name': display_name, 'display_name': display_name,
'desc_status': STATUSES[chat_status], 'desc_status': STATUSES[show],
'status_icon': status_icon, 'status_icon': status_icon,
'desc_chat': __('Click to chat with %1$s (JID: %2$s)', display_name, item.get('jid')), 'desc_chat': __('Click to chat with %1$s (JID: %2$s)', display_name, item.get('jid')),
'desc_remove': __('Click to remove %1$s as a contact', display_name), 'desc_remove': __('Click to remove %1$s as a contact', display_name),
...@@ -57481,7 +57489,7 @@ define("awesomplete", (function (global) { ...@@ -57481,7 +57489,7 @@ define("awesomplete", (function (global) {
* It doesn't check for the more specific case of whether * It doesn't check for the more specific case of whether
* the group it's in is collapsed. * the group it's in is collapsed.
*/ */
var chatStatus = this.model.get('chat_status'); var chatStatus = this.model.presence.get('show');
if (_converse.show_only_online_users && chatStatus !== 'online' || _converse.hide_offline_users && chatStatus === 'offline') { if (_converse.show_only_online_users && chatStatus !== 'online' || _converse.hide_offline_users && chatStatus === 'offline') {
// If pending or requesting, show // If pending or requesting, show
...@@ -57562,7 +57570,7 @@ define("awesomplete", (function (global) { ...@@ -57562,7 +57570,7 @@ define("awesomplete", (function (global) {
ItemView: _converse.RosterContactView, ItemView: _converse.RosterContactView,
listItems: 'model.contacts', listItems: 'model.contacts',
listSelector: '.roster-group-contacts', listSelector: '.roster-group-contacts',
sortEvent: 'change:chat_status', sortEvent: 'presenceChanged',
initialize: function initialize() { initialize: function initialize() {
Backbone.OrderedListView.prototype.initialize.apply(this, arguments); Backbone.OrderedListView.prototype.initialize.apply(this, arguments);
this.model.contacts.on("change:subscription", this.onContactSubscriptionChange, this); this.model.contacts.on("change:subscription", this.onContactSubscriptionChange, this);
...@@ -57652,14 +57660,16 @@ define("awesomplete", (function (global) { ...@@ -57652,14 +57660,16 @@ define("awesomplete", (function (global) {
// show requesting contacts, even though they don't // show requesting contacts, even though they don't
// have the state in question. // have the state in question.
matches = this.model.contacts.filter(function (contact) { matches = this.model.contacts.filter(function (contact) {
return u.contains.not('chat_status', q)(contact) && !contact.get('requesting'); return !_.includes(contact.presence.get('show'), q) && !contact.get('requesting');
}); });
} else if (q === 'unread_messages') { } else if (q === 'unread_messages') {
matches = this.model.contacts.filter({ matches = this.model.contacts.filter({
'num_unread': 0 'num_unread': 0
}); });
} else { } else {
matches = this.model.contacts.filter(u.contains.not('chat_status', q)); matches = this.model.contacts.filter(function (contact) {
return !_.includes(contact.presence.get('show'), q);
});
} }
} else { } else {
matches = this.model.contacts.filter(function (contact) { matches = this.model.contacts.filter(function (contact) {
...@@ -57780,6 +57790,12 @@ define("awesomplete", (function (global) { ...@@ -57780,6 +57790,12 @@ define("awesomplete", (function (global) {
_converse.roster.on("remove", this.update, this); _converse.roster.on("remove", this.update, this);
_converse.presences.on('change:show', function () {
_this5.update();
_this5.updateFilter();
});
this.model.on("reset", this.reset, this); // This event gets triggered once *all* contacts (i.e. not this.model.on("reset", this.reset, this); // This event gets triggered once *all* contacts (i.e. not
// just this group's) have been fetched from browser // just this group's) have been fetched from browser
// storage or the XMPP server and once they've been // storage or the XMPP server and once they've been
...@@ -57891,11 +57907,13 @@ define("awesomplete", (function (global) { ...@@ -57891,11 +57907,13 @@ define("awesomplete", (function (global) {
return this; return this;
}, },
onContactAdded: function onContactAdded(contact) { onContactAdded: function onContactAdded(contact) {
this.addRosterContact(contact).update(); this.addRosterContact(contact);
this.update();
this.updateFilter(); this.updateFilter();
}, },
onContactChange: function onContactChange(contact) { onContactChange: function onContactChange(contact) {
this.updateChatBox(contact).update(); this.updateChatBox(contact);
this.update();
if (_.has(contact.changed, 'subscription')) { if (_.has(contact.changed, 'subscription')) {
if (contact.changed.subscription === 'from') { if (contact.changed.subscription === 'from') {
...@@ -57923,10 +57941,6 @@ define("awesomplete", (function (global) { ...@@ -57923,10 +57941,6 @@ define("awesomplete", (function (global) {
return this; return this;
} }
if (_.has(contact.changed, 'chat_status')) {
changes.chat_status = contact.get('chat_status');
}
if (_.has(contact.changed, 'status')) { if (_.has(contact.changed, 'status')) {
changes.status = contact.get('status'); changes.status = contact.get('status');
} }
...@@ -58191,7 +58205,7 @@ return __p ...@@ -58191,7 +58205,7 @@ return __p
define('tpl!profile_view', ['lodash'], function(_) {return function(o) { define('tpl!profile_view', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<div class="userinfo">\n<div class="profile d-flex">\n <a class="show-profile" href="#">\n <img alt="User Avatar" class="avatar align-self-center" height="40px" width="40px" src="data:' + __p += '<div class="userinfo controlbox-padded">\n<div class="profile d-flex">\n <a class="show-profile" href="#">\n <img alt="User Avatar" class="avatar align-self-center" height="40px" width="40px" src="data:' +
__e(o.image_type) + __e(o.image_type) +
';base64,' + ';base64,' +
__e(o.image) + __e(o.image) +
...@@ -60793,7 +60807,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -60793,7 +60807,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
if (result.image) { if (result.image) {
var word_array_from_b64 = CryptoJS.enc.Base64.parse(result['image']); var word_array_from_b64 = CryptoJS.enc.Base64.parse(result['image']);
result['image_type'] = CryptoJS.SHA1(word_array_from_b64).toString(); result['image_hash'] = CryptoJS.SHA1(word_array_from_b64).toString();
} }
if (callback) { if (callback) {
...@@ -60854,7 +60868,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -60854,7 +60868,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
_converse.initVCardCollection = function () { _converse.initVCardCollection = function () {
_converse.vcards = new _converse.VCards(); _converse.vcards = new _converse.VCards();
_converse.vcards.browserStorage = new Backbone.BrowserStorage.local(b64_sha1("converse.vcards")); _converse.vcards.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.vcards"));
_converse.vcards.fetch(); _converse.vcards.fetch();
}; };
...@@ -61146,8 +61160,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -61146,8 +61160,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
/*global define */ /*global define */
(function (root, factory) { (function (root, factory) {
define('converse-controlbox',["converse-core", "lodash.fp", "tpl!converse_brand_heading", "tpl!controlbox", "tpl!controlbox_toggle", "tpl!login_panel", "converse-chatview", "converse-rosterview", "converse-profile"], factory); define('converse-controlbox',["converse-core", "bootstrap", "lodash.fp", "tpl!converse_brand_heading", "tpl!controlbox", "tpl!controlbox_toggle", "tpl!login_panel", "converse-chatview", "converse-rosterview", "converse-profile"], factory);
})(this, function (converse, fp, tpl_brand_heading, tpl_controlbox, tpl_controlbox_toggle, tpl_login_panel) { })(this, function (converse, bootstrap, fp, tpl_brand_heading, tpl_controlbox, tpl_controlbox_toggle, tpl_login_panel) {
"use strict"; "use strict";
var CHATBOX_TYPE = 'chatbox'; var CHATBOX_TYPE = 'chatbox';
...@@ -61223,21 +61237,6 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -61223,21 +61237,6 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
this.rosterview.removeAll().remove(); this.rosterview.removeAll().remove();
} }
}, },
clearSession: function clearSession() {
this.__super__.clearSession.apply(this, arguments);
var chatboxes = _.get(this, 'chatboxes', null);
if (!_.isNil(chatboxes)) {
var controlbox = chatboxes.get('controlbox');
if (controlbox && controlbox.collection && controlbox.collection.browserStorage) {
controlbox.save({
'connected': false
});
}
}
},
ChatBoxes: { ChatBoxes: {
chatBoxMayBeShown: function chatBoxMayBeShown(chatbox) { chatBoxMayBeShown: function chatBoxMayBeShown(chatbox) {
return this.__super__.chatBoxMayBeShown.apply(this, arguments) && chatbox.get('id') !== 'controlbox'; return this.__super__.chatBoxMayBeShown.apply(this, arguments) && chatbox.get('id') !== 'controlbox';
...@@ -61540,6 +61539,15 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -61540,6 +61539,15 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
initialize: function initialize(cfg) { initialize: function initialize(cfg) {
this.model.on('change', this.render, this); this.model.on('change', this.render, this);
this.listenTo(_converse.connfeedback, 'change', this.render); this.listenTo(_converse.connfeedback, 'change', this.render);
this.render();
_.forEach(this.el.querySelectorAll('[data-title]'), function (el) {
var popover = new bootstrap.Popover(el, {
'trigger': _converse.view_mode === 'mobile' && 'click' || 'hover',
'dismissible': _converse.view_mode === 'mobile' && true || false,
'container': _converse.chatboxviews.el
});
});
}, },
toHTML: function toHTML() { toHTML: function toHTML() {
var connection_status = _converse.connfeedback.get('connection_status'); var connection_status = _converse.connfeedback.get('connection_status');
...@@ -61595,7 +61603,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -61595,7 +61603,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
return; return;
} }
var jid = ev.target.querySelector('input[name=jid]').value; var form_data = new FormData(ev.target);
_converse.trusted = form_data.get('trusted');
_converse.storage = form_data.get('trusted') ? 'local' : 'session';
var jid = form_data.get('jid');
if (_converse.locked_domain) { if (_converse.locked_domain) {
jid = Strophe.escapeNode(jid) + '@' + _converse.locked_domain; jid = Strophe.escapeNode(jid) + '@' + _converse.locked_domain;
...@@ -61603,7 +61614,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -61603,7 +61614,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
jid = jid + '@' + _converse.default_domain; jid = jid + '@' + _converse.default_domain;
} }
this.connect(jid, _.get(ev.target.querySelector('input[name=password]'), 'value')); this.connect(jid, form_data.get('password'));
}, },
connect: function connect(jid, password) { connect: function connect(jid, password) {
if (jid) { if (jid) {
...@@ -61702,6 +61713,23 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat ...@@ -61702,6 +61713,23 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
} }
} }
}); });
_converse.on('clearSession', function () {
if (_converse.trusted) {
var chatboxes = _.get(_converse, 'chatboxes', null);
if (!_.isNil(chatboxes)) {
var controlbox = chatboxes.get('controlbox');
if (controlbox && controlbox.collection && controlbox.collection.browserStorage) {
controlbox.save({
'connected': false
});
}
}
}
});
Promise.all([_converse.api.waitUntil('connectionInitialized'), _converse.api.waitUntil('chatBoxesInitialized')]).then(_converse.addControlBox).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)); Promise.all([_converse.api.waitUntil('connectionInitialized'), _converse.api.waitUntil('chatBoxesInitialized')]).then(_converse.addControlBox).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
_converse.on('chatBoxesFetched', function () { _converse.on('chatBoxesFetched', function () {
...@@ -62164,7 +62192,7 @@ return __p ...@@ -62164,7 +62192,7 @@ return __p
define('tpl!inverse_brand_heading', ['lodash'], function(_) {return function(o) { define('tpl!inverse_brand_heading', ['lodash'], function(_) {return function(o) {
var __t, __p = ''; var __t, __p = '';
__p += '<div class="row">\n <div class="container brand-heading-container">\n <h1 class="brand-heading"><i class="icon-conversejs"></i>Converse</h1>\n <p class="brand-subtitle"><a target="_blank" rel="nofollow" href="https://conversejs.org">Open Source</a> XMPP chat client</p>\n <p class="brand-subtitle"><a target="_blank" rel="nofollow" href="https://hosted.weblate.org/projects/conversejs/#languages">Translate</a> into your own language</p>\n <div>\n</div>\n'; __p += '<div class="row">\n <div class="container brand-heading-container">\n <h1 class="brand-heading"><i class="icon-conversejs"></i>Converse</h1>\n <p class="brand-subtitle"><a target="_blank" rel="nofollow" href="https://conversejs.org">Open Source</a> XMPP chat client brought to you by <a target="_blank" rel="nofollow" href="https://opkode.com">Opkode</a> </p>\n <p class="brand-subtitle"><a target="_blank" rel="nofollow" href="https://hosted.weblate.org/projects/conversejs/#languages">Translate</a> it into your own language</p>\n <div>\n</div>\n';
return __p return __p
};}); };});
...@@ -63853,7 +63881,7 @@ return __p ...@@ -63853,7 +63881,7 @@ return __p
define('tpl!chatroom_head', ['lodash'], function(_) {return function(o) { define('tpl!chatroom_head', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<div class="col col-9">\n <div class="chat-title" title="' + __p += '<div class="col col-8">\n <div class="chat-title" title="' +
__e(o.jid) + __e(o.jid) +
'">\n '; '">\n ';
if (o.name && o.name !== o.Strophe.getNodeFromJid(o.jid)) { ; if (o.name && o.name !== o.Strophe.getNodeFromJid(o.jid)) { ;
...@@ -64171,7 +64199,7 @@ return __p ...@@ -64171,7 +64199,7 @@ return __p
define('tpl!room_panel', ['lodash'], function(_) {return function(o) { define('tpl!room_panel', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape; var __t, __p = '', __e = _.escape;
__p += '<!-- <div id="chatrooms"> -->\n<div class="d-flex">\n <span class="w-100 controlbox-heading">' + __p += '<!-- <div id="chatrooms"> -->\n<div class="d-flex controlbox-padded">\n <span class="w-100 controlbox-heading">' +
__e(o.heading_chatrooms) + __e(o.heading_chatrooms) +
'</span>\n <a class="chatbox-btn trigger-list-chatrooms-modal fa fa-list-ul" title="' + '</span>\n <a class="chatbox-btn trigger-list-chatrooms-modal fa fa-list-ul" title="' +
__e(o.title_list_rooms) + __e(o.title_list_rooms) +
...@@ -66269,7 +66297,7 @@ return __p ...@@ -66269,7 +66297,7 @@ return __p
}; };
_converse.handleChatStateNotification = function (contact) { _converse.handleChatStateNotification = function (contact) {
/* Event handler for on('contactStatusChanged'). /* Event handler for on('contactPresenceChanged').
* Will show an HTML5 notification to indicate that the chat * Will show an HTML5 notification to indicate that the chat
* status has changed. * status has changed.
*/ */
...@@ -66320,7 +66348,7 @@ return __p ...@@ -66320,7 +66348,7 @@ return __p
// handlers. // handlers.
_converse.on('contactRequest', _converse.handleContactRequestNotification); _converse.on('contactRequest', _converse.handleContactRequestNotification);
_converse.on('contactStatusChanged', _converse.handleChatStateNotification); _converse.on('contactPresenceChanged', _converse.handleChatStateNotification);
_converse.on('message', _converse.handleMessageNotification); _converse.on('message', _converse.handleMessageNotification);
...@@ -71952,22 +71980,13 @@ return __p ...@@ -71952,22 +71980,13 @@ return __p
converse.plugins.add('converse-roster', { converse.plugins.add('converse-roster', {
dependencies: ["converse-vcard"], dependencies: ["converse-vcard"],
overrides: { overrides: {
clearSession: function clearSession() {
this.__super__.clearSession.apply(this, arguments);
if (!_.isUndefined(this.roster)) {
this.roster.browserStorage._clear();
}
},
_tearDown: function _tearDown() { _tearDown: function _tearDown() {
this.__super__._tearDown.apply(this, arguments); this.__super__._tearDown.apply(this, arguments);
if (this.roster) {
this.roster.off().reset(); // Removes roster contacts
}
} }
}, },
initialize: function initialize() { initialize: function initialize() {
var _this6 = this;
/* The initialize function gets called as soon as the plugin is /* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery. * loaded by converse.js's plugin machinery.
*/ */
...@@ -71991,9 +72010,9 @@ return __p ...@@ -71991,9 +72010,9 @@ return __p
* roster and the roster groups. * roster and the roster groups.
*/ */
_converse.roster = new _converse.RosterContacts(); _converse.roster = new _converse.RosterContacts();
_converse.roster.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.contacts-".concat(_converse.bare_jid))); _converse.roster.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.contacts-".concat(_converse.bare_jid)));
_converse.rostergroups = new _converse.RosterGroups(); _converse.rostergroups = new _converse.RosterGroups();
_converse.rostergroups.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.roster.groups".concat(_converse.bare_jid))); _converse.rostergroups.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.roster.groups".concat(_converse.bare_jid)));
_converse.emit('rosterInitialized'); _converse.emit('rosterInitialized');
}; };
...@@ -72038,16 +72057,119 @@ return __p ...@@ -72038,16 +72057,119 @@ return __p
} }
}; };
_converse.RosterContact = Backbone.Model.extend({ _converse.Presence = Backbone.Model.extend({
defaults: {
'show': 'offline',
'resources': {}
},
getHighestPriorityResource: function getHighestPriorityResource() {
/* Return the resource with the highest priority.
*
* If multiple resources have the same priority, take the
* latest one.
*/
var resources = this.get('resources');
if (_.isObject(resources) && _.size(resources)) {
var val = _.flow(_.values, _.partial(_.sortBy, _, ['priority', 'timestamp']), _.reverse)(resources)[0];
if (!_.isUndefined(val)) {
return val;
}
}
},
addResource: function addResource(presence) {
/* Adds a new resource and it's associated attributes as taken
* from the passed in presence stanza.
*
* Also updates the presence if the resource has higher priority (and is newer).
*/
var jid = presence.getAttribute('from'),
show = _.propertyOf(presence.querySelector('show'))('textContent') || 'online',
resource = Strophe.getResourceFromJid(jid),
delay = presence.querySelector("delay[xmlns=\"".concat(Strophe.NS.DELAY, "\"]")),
timestamp = _.isNull(delay) ? moment().format() : moment(delay.getAttribute('stamp')).format();
var priority = _.propertyOf(presence.querySelector('priority'))('textContent') || 0;
priority = _.isNaN(parseInt(priority, 10)) ? 0 : parseInt(priority, 10);
var resources = _.isObject(this.get('resources')) ? this.get('resources') : {};
resources[resource] = {
'name': resource,
'priority': priority,
'show': show,
'timestamp': timestamp
};
var changed = {
'resources': resources
};
var hpr = this.getHighestPriorityResource();
if (priority == hpr.priority && timestamp == hpr.timestamp) {
// Only set the "global" presence if this is the newest resource
// with the highest priority
changed.show = show;
}
this.save(changed);
return resources;
},
removeResource: function removeResource(resource) {
/* Remove the passed in resource from the resources map.
*
* Also redetermines the presence given that there's one less
* resource.
*/
var resources = this.get('resources');
if (!_.isObject(resources)) {
resources = {};
} else {
delete resources[resource];
}
this.save({
'resources': resources,
'show': _.propertyOf(this.getHighestPriorityResource())('show') || 'offline'
});
}
});
_converse.Presences = Backbone.Collection.extend({
model: _converse.Presence
});
_converse.ModelWithVCardAndPresence = Backbone.Model.extend({
initialize: function initialize() {
this.setVCard();
this.setPresence();
},
setVCard: function setVCard() {
var jid = this.get('jid');
this.vcard = _converse.vcards.findWhere({
'jid': jid
}) || _converse.vcards.create({
'jid': jid
});
},
setPresence: function setPresence() {
var jid = this.get('jid');
this.presence = _converse.presences.findWhere({
'jid': jid
}) || _converse.presences.create({
'jid': jid
});
}
});
_converse.RosterContact = _converse.ModelWithVCardAndPresence.extend({
defaults: { defaults: {
'chat_state': undefined, 'chat_state': undefined,
'chat_status': 'offline',
'image': _converse.DEFAULT_IMAGE, 'image': _converse.DEFAULT_IMAGE,
'image_type': _converse.DEFAULT_IMAGE_TYPE, 'image_type': _converse.DEFAULT_IMAGE_TYPE,
'num_unread': 0, 'num_unread': 0,
'status': '' 'status': ''
}, },
initialize: function initialize(attributes) { initialize: function initialize(attributes) {
var _this = this;
_converse.ModelWithVCardAndPresence.prototype.initialize.apply(this, arguments);
var jid = attributes.jid, var jid = attributes.jid,
bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase(), bare_jid = Strophe.getBareJidFromJid(jid).toLowerCase(),
resource = Strophe.getResourceFromJid(jid); resource = Strophe.getResourceFromJid(jid);
...@@ -72056,21 +72178,13 @@ return __p ...@@ -72056,21 +72178,13 @@ return __p
'groups': [], 'groups': [],
'id': bare_jid, 'id': bare_jid,
'jid': bare_jid, 'jid': bare_jid,
'resources': {},
'user_id': Strophe.getNodeFromJid(jid) 'user_id': Strophe.getNodeFromJid(jid)
}, attributes)); }, attributes));
this.vcard = _converse.vcards.findWhere({ this.presence.on('change:show', function () {
'jid': bare_jid return _converse.emit('contactPresenceChanged', _this);
}); });
this.presence.on('change:show', function () {
if (_.isNil(this.vcard)) { return _this.trigger('presenceChanged');
this.vcard = _converse.vcards.create({
'jid': bare_jid
});
}
this.on('change:chat_status', function (item) {
_converse.emit('contactStatusChanged', item.attributes);
}); });
}, },
getDisplayName: function getDisplayName() { getDisplayName: function getDisplayName() {
...@@ -72164,76 +72278,6 @@ return __p ...@@ -72164,76 +72278,6 @@ return __p
return this; return this;
}, },
addResource: function addResource(presence) {
/* Adds a new resource and it's associated attributes as taken
* from the passed in presence stanza.
*
* Also updates the contact's chat_status if the presence has
* higher priority (and is newer).
*/
var jid = presence.getAttribute('from'),
chat_status = _.propertyOf(presence.querySelector('show'))('textContent') || 'online',
resource = Strophe.getResourceFromJid(jid),
delay = presence.querySelector("delay[xmlns=\"".concat(Strophe.NS.DELAY, "\"]")),
timestamp = _.isNull(delay) ? moment().format() : moment(delay.getAttribute('stamp')).format();
var priority = _.propertyOf(presence.querySelector('priority'))('textContent') || 0;
priority = _.isNaN(parseInt(priority, 10)) ? 0 : parseInt(priority, 10);
var resources = _.isObject(this.get('resources')) ? this.get('resources') : {};
resources[resource] = {
'name': resource,
'priority': priority,
'status': chat_status,
'timestamp': timestamp
};
var changed = {
'resources': resources
};
var hpr = this.getHighestPriorityResource();
if (priority == hpr.priority && timestamp == hpr.timestamp) {
// Only set the chat status if this is the newest resource
// with the highest priority
changed.chat_status = chat_status;
}
this.save(changed);
return resources;
},
removeResource: function removeResource(resource) {
/* Remove the passed in resource from the contact's resources map.
*
* Also recomputes the chat_status given that there's one less
* resource.
*/
var resources = this.get('resources');
if (!_.isObject(resources)) {
resources = {};
} else {
delete resources[resource];
}
this.save({
'resources': resources,
'chat_status': _.propertyOf(this.getHighestPriorityResource())('status') || 'offline'
});
},
getHighestPriorityResource: function getHighestPriorityResource() {
/* Return the resource with the highest priority.
*
* If multiple resources have the same priority, take the
* newest one.
*/
var resources = this.get('resources');
if (_.isObject(resources) && _.size(resources)) {
var val = _.flow(_.values, _.partial(_.sortBy, _, ['priority', 'timestamp']), _.reverse)(resources)[0];
if (!_.isUndefined(val)) {
return val;
}
}
},
removeFromRoster: function removeFromRoster(callback, errback) { removeFromRoster: function removeFromRoster(callback, errback) {
/* Instruct the XMPP server to remove this contact from our roster /* Instruct the XMPP server to remove this contact from our roster
* Parameters: * Parameters:
...@@ -72256,8 +72300,8 @@ return __p ...@@ -72256,8 +72300,8 @@ return __p
_converse.RosterContacts = Backbone.Collection.extend({ _converse.RosterContacts = Backbone.Collection.extend({
model: _converse.RosterContact, model: _converse.RosterContact,
comparator: function comparator(contact1, contact2) { comparator: function comparator(contact1, contact2) {
var status1 = contact1.get('chat_status') || 'offline'; var status1 = contact1.presence.get('show') || 'offline';
var status2 = contact2.get('chat_status') || 'offline'; var status2 = contact2.presence.get('show') || 'offline';
if (_converse.STATUS_WEIGHTS[status1] === _converse.STATUS_WEIGHTS[status2]) { if (_converse.STATUS_WEIGHTS[status1] === _converse.STATUS_WEIGHTS[status2]) {
var name1 = contact1.getDisplayName().toLowerCase(); var name1 = contact1.getDisplayName().toLowerCase();
...@@ -72299,17 +72343,17 @@ return __p ...@@ -72299,17 +72343,17 @@ return __p
}, Strophe.NS.ROSTERX, 'message', null); }, Strophe.NS.ROSTERX, 'message', null);
}, },
fetchRosterContacts: function fetchRosterContacts() { fetchRosterContacts: function fetchRosterContacts() {
var _this = this; var _this2 = this;
/* Fetches the roster contacts, first by trying the /* Fetches the roster contacts, first by trying the
* sessionStorage cache, and if that's empty, then by querying * sessionStorage cache, and if that's empty, then by querying
* the XMPP server. * the XMPP server.
* *
* Returns a promise which resolves once the contacts have been * Returns a promise which resolves once the contacts have been
* fetched. * fetched.
*/ */
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
_this.fetch({ _this2.fetch({
'add': true, 'add': true,
'silent': true, 'silent': true,
success: function success(collection) { success: function success(collection) {
...@@ -72384,7 +72428,7 @@ return __p ...@@ -72384,7 +72428,7 @@ return __p
_converse.connection.sendIQ(iq, callback, errback); _converse.connection.sendIQ(iq, callback, errback);
}, },
addContactToRoster: function addContactToRoster(jid, name, groups, attributes) { addContactToRoster: function addContactToRoster(jid, name, groups, attributes) {
var _this2 = this; var _this3 = this;
/* Adds a RosterContact instance to _converse.roster and /* Adds a RosterContact instance to _converse.roster and
* registers the contact on the XMPP server. * registers the contact on the XMPP server.
...@@ -72400,8 +72444,8 @@ return __p ...@@ -72400,8 +72444,8 @@ return __p
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
groups = groups || []; groups = groups || [];
_this2.sendContactAddIQ(jid, name, groups, function () { _this3.sendContactAddIQ(jid, name, groups, function () {
var contact = _this2.create(_.assignIn({ var contact = _this3.create(_.assignIn({
'ask': undefined, 'ask': undefined,
'nickname': name, 'nickname': name,
groups: groups, groups: groups,
...@@ -72450,7 +72494,7 @@ return __p ...@@ -72450,7 +72494,7 @@ return __p
} }
return _.sum(this.models.filter(function (model) { return _.sum(this.models.filter(function (model) {
return !_.includes(ignored, model.get('chat_status')); return !_.includes(ignored, model.presence.get('show'));
})); }));
}, },
onRosterPush: function onRosterPush(iq) { onRosterPush: function onRosterPush(iq) {
...@@ -72496,7 +72540,7 @@ return __p ...@@ -72496,7 +72540,7 @@ return __p
return true; return true;
}, },
fetchFromServer: function fetchFromServer() { fetchFromServer: function fetchFromServer() {
var _this3 = this; var _this4 = this;
/* Fetch the roster from the XMPP server */ /* Fetch the roster from the XMPP server */
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
...@@ -72507,7 +72551,7 @@ return __p ...@@ -72507,7 +72551,7 @@ return __p
xmlns: Strophe.NS.ROSTER xmlns: Strophe.NS.ROSTER
}); });
var callback = _.flow(_this3.onReceivedFromServer.bind(_this3), resolve); var callback = _.flow(_this4.onReceivedFromServer.bind(_this4), resolve);
var errback = function errback(iq) { var errback = function errback(iq) {
var errmsg = "Error while trying to fetch roster from the server"; var errmsg = "Error while trying to fetch roster from the server";
...@@ -72627,7 +72671,6 @@ return __p ...@@ -72627,7 +72671,6 @@ return __p
var jid = presence.getAttribute('from'), var jid = presence.getAttribute('from'),
bare_jid = Strophe.getBareJidFromJid(jid), bare_jid = Strophe.getBareJidFromJid(jid),
resource = Strophe.getResourceFromJid(jid), resource = Strophe.getResourceFromJid(jid),
chat_status = _.propertyOf(presence.querySelector('show'))('textContent') || 'online',
status_message = _.propertyOf(presence.querySelector('status'))('textContent'), status_message = _.propertyOf(presence.querySelector('status'))('textContent'),
contact = this.get(bare_jid); contact = this.get(bare_jid);
...@@ -72636,8 +72679,10 @@ return __p ...@@ -72636,8 +72679,10 @@ return __p
// Another resource has changed its status and // Another resource has changed its status and
// synchronize_availability option set to update, // synchronize_availability option set to update,
// we'll update ours as well. // we'll update ours as well.
var show = _.propertyOf(presence.querySelector('show'))('textContent') || 'online';
_converse.xmppstatus.save({ _converse.xmppstatus.save({
'status': chat_status 'status': show
}); });
if (status_message) { if (status_message) {
...@@ -72685,10 +72730,10 @@ return __p ...@@ -72685,10 +72730,10 @@ return __p
} else if (presence_type === 'subscribe') { } else if (presence_type === 'subscribe') {
this.handleIncomingSubscription(presence); this.handleIncomingSubscription(presence);
} else if (presence_type === 'unavailable' && contact) { } else if (presence_type === 'unavailable' && contact) {
contact.removeResource(resource); contact.presence.removeResource(resource);
} else if (contact) { } else if (contact) {
// presence_type is undefined // presence_type is undefined
contact.addResource(presence); contact.presence.addResource(presence);
} }
} }
}); });
...@@ -72705,7 +72750,7 @@ return __p ...@@ -72705,7 +72750,7 @@ return __p
_converse.RosterGroups = Backbone.Collection.extend({ _converse.RosterGroups = Backbone.Collection.extend({
model: _converse.RosterGroup, model: _converse.RosterGroup,
fetchRosterGroups: function fetchRosterGroups() { fetchRosterGroups: function fetchRosterGroups() {
var _this4 = this; var _this5 = this;
/* Fetches all the roster groups from sessionStorage. /* Fetches all the roster groups from sessionStorage.
* *
...@@ -72713,7 +72758,7 @@ return __p ...@@ -72713,7 +72758,7 @@ return __p
* returned. * returned.
*/ */
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
_this4.fetch({ _this5.fetch({
silent: true, silent: true,
// We need to first have all groups before // We need to first have all groups before
// we can start positioning them, so we set // we can start positioning them, so we set
...@@ -72723,8 +72768,39 @@ return __p ...@@ -72723,8 +72768,39 @@ return __p
}); });
} }
}); });
_converse.unregisterPresenceHandler = function () {
if (!_.isUndefined(_converse.presence_ref)) {
_converse.connection.deleteHandler(_converse.presence_ref);
delete _converse.presence_ref;
}
};
/********** Event Handlers *************/ /********** Event Handlers *************/
_converse.api.listen.on('beforeTearDown', _converse.unregisterPresenceHandler());
_converse.api.listen.on('afterTearDown', function () {
if (_converse.presence) {
_converse.presences.off().reset(); // Remove presences
}
});
_converse.api.listen.on('clearSession', function () {
if (!_.isUndefined(_this6.roster)) {
_this6.roster.browserStorage._clear();
}
});
_converse.api.listen.on('connectionInitialized', function () {
_converse.presences = new _converse.Presences();
_converse.presences.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.presences-".concat(_converse.bare_jid)));
_converse.presences.fetch();
});
_converse.api.listen.on('statusInitialized', function (reconnecting) { _converse.api.listen.on('statusInitialized', function (reconnecting) {
if (reconnecting) { if (reconnecting) {
// No need to recreate the roster, otherwise we lose our // No need to recreate the roster, otherwise we lose our
...@@ -73582,7 +73658,7 @@ return __p ...@@ -73582,7 +73658,7 @@ return __p
define('tpl!rooms_list', ['lodash'], function(_) {return function(o) { define('tpl!rooms_list', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<a href="#" class="rooms-toggle open-rooms-toggle" title="' + __p += '<a href="#" class="rooms-toggle open-rooms-toggle controlbox-padded" title="' +
__e(o.desc_rooms) + __e(o.desc_rooms) +
'">\n <span class="fa '; '">\n <span class="fa ';
if (o.toggle_state === o._converse.OPENED) { ; if (o.toggle_state === o._converse.OPENED) { ;
...@@ -73600,7 +73676,7 @@ return __p ...@@ -73600,7 +73676,7 @@ return __p
define('tpl!rooms_list_item', ['lodash'], function(_) {return function(o) { define('tpl!rooms_list_item', ['lodash'], function(_) {return function(o) {
var __t, __p = '', __e = _.escape, __j = Array.prototype.join; var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') } function print() { __p += __j.call(arguments, '') }
__p += '<div class="list-item available-chatroom d-flex flex-row '; __p += '<div class="list-item controlbox-padded available-chatroom d-flex flex-row ';
if (o.num_unread_general) { ; if (o.num_unread_general) { ;
__p += ' unread-msgs '; __p += ' unread-msgs ';
} ; } ;
...@@ -73836,7 +73912,7 @@ return __p ...@@ -73836,7 +73912,7 @@ return __p
insertIntoControlBox: function insertIntoControlBox() { insertIntoControlBox: function insertIntoControlBox() {
var controlboxview = _converse.chatboxviews.get('controlbox'); var controlboxview = _converse.chatboxviews.get('controlbox');
if (!_.isUndefined(controlboxview) && !_converse.root.contains(this.el)) { if (!_.isUndefined(controlboxview) && !u.rootContains(_converse.root, this.el)) {
var el = controlboxview.el.querySelector('.open-rooms-list'); var el = controlboxview.el.querySelector('.open-rooms-list');
if (!_.isNull(el)) { if (!_.isNull(el)) {
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