Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
converse.js
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
converse.js
Commits
4d004a5c
Commit
4d004a5c
authored
May 24, 2018
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New dist files
parent
eff65693
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
322 additions
and
224 deletions
+322
-224
dist/converse-no-dependencies.js
dist/converse-no-dependencies.js
+166
-117
dist/converse.js
dist/converse.js
+156
-107
No files found.
dist/converse-no-dependencies.js
View file @
4d004a5c
...
@@ -11759,7 +11759,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
...
@@ -11759,7 +11759,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
} catch (e) {
} catch (e) {
_converse.log("Could not restore session for jid: " + this.jid + " Error message: " + e.message, Strophe.LogLevel.WARN);
_converse.log("Could not restore session for jid: " + this.jid + " Error message: " + e.message, Strophe.LogLevel.WARN);
this.clearSession(); //
If there's a roster, we want to clear it
(see #555)
this.clearSession(); //
We want to clear presences
(see #555)
return false;
return false;
}
}
...
@@ -15622,21 +15622,14 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
...
@@ -15622,21 +15622,14 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
var occupant = this.occupants.findOccupant(data);
var occupant = this.occupants.findOccupant(data);
if (data.type === 'unavailable') {
if (data.type === 'unavailable' && occupant) {
if (occupant) {
if (!_.includes(data.states, converse.MUC_NICK_CHANGED_CODE) && !occupant.isMember()) {
// Even before destroying, we set the new data, so
// We only destroy the occupant if this is not a nickname change operation.
// that we can for example show the
// and if they're not on the member lists.
// disconnection message.
// Before destroying we set the new data, so
// that we can show the disconnection message.
occupant.set(data);
occupant.set(data);
}
occupant.destroy();
if (!_.includes(data.states, converse.MUC_NICK_CHANGED_CODE)) {
// We only destroy the occupant if this is not a
// nickname change operation.
if (occupant) {
occupant.destroy();
}
return;
return;
}
}
}
}
...
@@ -15656,12 +15649,13 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
...
@@ -15656,12 +15649,13 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
},
},
parsePresence: function parsePresence(pres) {
parsePresence: function parsePresence(pres) {
var from = pres.getAttribute("from"),
var from = pres.getAttribute("from"),
type = pres.getAttribute("type"),
data = {
data = {
'from': from,
'from': from,
'nick': Strophe.getResourceFromJid(from),
'nick': Strophe.getResourceFromJid(from),
'type':
pres.getAttribute("type")
,
'type':
type
,
'states': [],
'states': [],
'show':
'on
line'
'show':
type !== 'unavailable' ? 'online' : 'off
line'
};
};
_.each(pres.childNodes, function (child) {
_.each(pres.childNodes, function (child) {
...
@@ -15912,6 +15906,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
...
@@ -15912,6 +15906,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
},
},
getDisplayName: function getDisplayName() {
getDisplayName: function getDisplayName() {
return this.get('nick') || this.get('jid');
return this.get('nick') || this.get('jid');
},
isMember: function isMember() {
return _.includes(['admin', 'owner', 'member'], this.get('affiliation'));
}
}
});
});
_converse.ChatRoomOccupants = Backbone.Collection.extend({
_converse.ChatRoomOccupants = Backbone.Collection.extend({
...
@@ -21144,31 +21141,57 @@ return __p
...
@@ -21144,31 +21141,57 @@ return __p
window.setTimeout(this.destroy.bind(this), 20000);
window.setTimeout(this.destroy.bind(this), 20000);
}
}
},
},
setVCard: function setVCard() {
getVCardForChatroomOccupant: function getVCardForChatroomOccupant() {
if (this.get('type') === 'groupchat') {
var chatbox = this.collection.chatbox,
var chatbox = this.collection.chatbox,
nick = Strophe.getResourceFromJid(this.get('from'));
nick = Strophe.getResourceFromJid(this.get('from'));
if (chatbox.get('nick') === nick) {
if (chatbox.get('nick') === nick) {
this.vcard = _converse.xmppstatus.vcard;
return _converse.xmppstatus.vcard;
} else {
} else {
var vcard;
if (this.get('vcard_jid')) {
vcard = _converse.vcards.findWhere({
'jid': this.get('vcard_jid')
});
}
if (!vcard) {
var jid;
var occupant = chatbox.occupants.findWhere({
var occupant = chatbox.occupants.findWhere({
'nick': nick
'nick': nick
});
});
var jid = occupant && occupant.get('jid') ? occupant.get('jid') : this.get('from');
this.vcard = _converse.vcards.findWhere({
if (occupant && occupant.get('jid')) {
jid = occupant.get('jid');
this.save({
'vcard_jid': jid
}, {
'silent': true
});
} else {
jid = this.get('from');
}
vcard = _converse.vcards.findWhere({
'jid': jid
'jid': jid
}) || _converse.vcards.create({
}) || _converse.vcards.create({
'jid': jid
'jid': jid
});
});
}
}
} else {
var _jid = this.get('from');
return vcard;
}
},
setVCard: function setVCard() {
if (this.get('type') === 'groupchat') {
this.vcard = this.getVCardForChatroomOccupant();
} else {
var jid = this.get('from');
this.vcard = _converse.vcards.findWhere({
this.vcard = _converse.vcards.findWhere({
'jid':
_
jid
'jid': jid
}) || _converse.vcards.create({
}) || _converse.vcards.create({
'jid':
_
jid
'jid': jid
});
});
}
}
},
},
...
@@ -21899,7 +21922,7 @@ return __p
...
@@ -21899,7 +21922,7 @@ return __p
delete _converse.chatboxes.browserStorage;
delete _converse.chatboxes.browserStorage;
});
});
_converse.api.listen.on('
statu
sInitialized', function () {
_converse.api.listen.on('
presence
sInitialized', function () {
return _converse.chatboxes.onConnected();
return _converse.chatboxes.onConnected();
});
});
/************************ END Event Handlers ************************/
/************************ END Event Handlers ************************/
...
@@ -24969,10 +24992,10 @@ __e(o.label_role) +
...
@@ -24969,10 +24992,10 @@ __e(o.label_role) +
__e(o.role) +
__e(o.role) +
'" aria-describedby="vcard-role-help">\n <small id="vcard-role-help" class="form-text text-muted">' +
'" aria-describedby="vcard-role-help">\n <small id="vcard-role-help" class="form-text text-muted">' +
__e(o.label_role_help) +
__e(o.label_role_help) +
'</small>\n </div>\n </div>\n <div class="modal-footer">\n <button type="button" class="btn btn-secondary" data-dismiss="modal">' +
'</small>\n </div>\n </div>\n <div class="modal-footer">\n <button type="submit" class="save-form btn btn-primary">' +
__e(o.label_close) +
'</button>\n <button type="submit" class="save-form btn btn-primary">' +
__e(o.label_save) +
__e(o.label_save) +
'</button>\n <button type="button" class="btn btn-secondary" data-dismiss="modal">' +
__e(o.label_close) +
'</button>\n </div>\n </form>\n </div>\n </div>\n</div>\n';
'</button>\n </div>\n </form>\n </div>\n </div>\n</div>\n';
return __p
return __p
};});
};});
...
@@ -25050,7 +25073,7 @@ var __t, __p = '', __e = _.escape;
...
@@ -25050,7 +25073,7 @@ var __t, __p = '', __e = _.escape;
__p += '<vCard xmlns="vcard-temp">\n <FN>' +
__p += '<vCard xmlns="vcard-temp">\n <FN>' +
__e(o.fn) +
__e(o.fn) +
'</FN>\n <NICKNAME>' +
'</FN>\n <NICKNAME>' +
__e(o.
fn
) +
__e(o.
nickname
) +
'</NICKNAME>\n <URL>' +
'</NICKNAME>\n <URL>' +
__e(o.url) +
__e(o.url) +
'</URL>\n <ROLE>' +
'</URL>\n <ROLE>' +
...
@@ -25351,6 +25374,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
...
@@ -25351,6 +25374,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
image_file = form_data.get('image');
image_file = form_data.get('image');
var data = {
var data = {
'fn': form_data.get('fn'),
'fn': form_data.get('fn'),
'nickname': form_data.get('nickname'),
'role': form_data.get('role'),
'role': form_data.get('role'),
'email': form_data.get('email'),
'email': form_data.get('email'),
'url': form_data.get('url')
'url': form_data.get('url')
...
@@ -26584,7 +26608,7 @@ return __p
...
@@ -26584,7 +26608,7 @@ return __p
// an error will be raised if the plugin is not found.
// an error will be raised if the plugin is not found.
//
//
// NB: These plugins need to have already been loaded via require.js.
// NB: These plugins need to have already been loaded via require.js.
dependencies: ['converse-chatboxes', 'converse-muc', 'converse-controlbox', 'converse-rosterview'],
dependencies: ['converse-chatboxes', 'converse-muc', 'converse-
muc-views', 'converse-
controlbox', 'converse-rosterview'],
enabled: function enabled(_converse) {
enabled: function enabled(_converse) {
return _.includes(['mobile', 'fullscreen', 'embedded'], _converse.view_mode);
return _.includes(['mobile', 'fullscreen', 'embedded'], _converse.view_mode);
},
},
...
@@ -28142,7 +28166,7 @@ return __p
...
@@ -28142,7 +28166,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="c
ol col-8
">\n <div class="chat-title" title="' +
__p += '<div class="c
hatbox-title
">\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)) { ;
...
@@ -28591,7 +28615,7 @@ return __p
...
@@ -28591,7 +28615,7 @@ return __p
if (!this.roomspanel.model.get('nick')) {
if (!this.roomspanel.model.get('nick')) {
this.roomspanel.model.save({
this.roomspanel.model.save({
nick: _converse.xmppstatus.get('nickname') || Strophe.getNodeFromJid(_converse.bare_jid)
nick: _converse.xmppstatus.
vcard.
get('nickname') || Strophe.getNodeFromJid(_converse.bare_jid)
});
});
}
}
_converse.emit('roomsPanelRendered');
_converse.emit('roomsPanelRendered');
...
@@ -29004,6 +29028,16 @@ return __p
...
@@ -29004,6 +29028,16 @@ return __p
this.model.occupants.on('add', this.showJoinNotification, this);
this.model.occupants.on('add', this.showJoinNotification, this);
this.model.occupants.on('remove', this.showLeaveNotification, this);
this.model.occupants.on('remove', this.showLeaveNotification, this);
this.model.occupants.on('change:show', (occupant) => {
if (!occupant.isMember() || _.includes(occupant.get('states'), '303')) {
return;
}
if (occupant.get('show') === 'offline') {
this.showLeaveNotification(occupant);
} else if (occupant.get('show') === 'online') {
this.showJoinNotification(occupant);
}
});
this.createEmojiPicker();
this.createEmojiPicker();
this.createOccupantsView();
this.createOccupantsView();
...
@@ -29577,10 +29611,9 @@ return __p
...
@@ -29577,10 +29611,9 @@ return __p
},
},
onNickNameNotFound (message) {
onNickNameNotFound (message) {
if (_converse.muc_nickname_from_jid) {
const nick = this.getDefaultNickName();
// We try to enter the room with the node part of
if (nick) {
// the user's JID.
this.join(nick);
this.join(this.getDefaultNickName());
} else {
} else {
this.renderNicknameForm(message);
this.renderNicknameForm(message);
}
}
...
@@ -29592,7 +29625,12 @@ return __p
...
@@ -29592,7 +29625,12 @@ return __p
* We put this in a separate method so that it can be
* We put this in a separate method so that it can be
* overridden by plugins.
* overridden by plugins.
*/
*/
return Strophe.unescapeNode(Strophe.getNodeFromJid(_converse.bare_jid));
const nick = _converse.xmppstatus.vcard.get('nickname');
if (nick) {
return nick;
} else if (_converse.muc_nickname_from_jid) {
return Strophe.unescapeNode(Strophe.getNodeFromJid(_converse.bare_jid));
}
},
},
onNicknameClash (presence) {
onNicknameClash (presence) {
...
@@ -29835,10 +29873,13 @@ return __p
...
@@ -29835,10 +29873,13 @@ return __p
},
},
showLeaveNotification (occupant) {
showLeaveNotification (occupant) {
const nick = occupant.get('nick');
const nick = occupant.get('nick'),
const stat = occupant.get('status');
stat = occupant.get('status'),
const last_el = this.content.lastElementChild;
last_el = this.content.lastElementChild,
last_msg_date = last_el.getAttribute('data-isodate');
if (_.includes(_.get(last_el, 'classList', []), 'chat-info') &&
if (_.includes(_.get(last_el, 'classList', []), 'chat-info') &&
moment(last_msg_date).isSame(new Date(), "day") &&
_.get(last_el, 'dataset', {}).join === `"${nick}"`) {
_.get(last_el, 'dataset', {}).join === `"${nick}"`) {
let message;
let message;
...
@@ -31365,12 +31406,6 @@ return __p
...
@@ -31365,12 +31406,6 @@ return __p
dependencies: ["converse-vcard"],
dependencies: ["converse-vcard"],
overrides: {
_tearDown () {
this.__super__._tearDown.apply(this, arguments);
}
},
initialize () {
initialize () {
/* 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.
...
@@ -31446,9 +31481,11 @@ return __p
...
@@ -31446,9 +31481,11 @@ return __p
_converse.Presence = Backbone.Model.extend({
_converse.Presence = Backbone.Model.extend({
defaults: {
defaults () {
'show': 'offline',
return {
'resources': {}
'show': 'offline',
'resources': {}
}
},
},
getHighestPriorityResource () {
getHighestPriorityResource () {
...
@@ -31477,12 +31514,10 @@ return __p
...
@@ -31477,12 +31514,10 @@ return __p
* Also updates the presence if the resource has higher priority (and is newer).
* Also updates the presence if the resource has higher priority (and is newer).
*/
*/
const jid = presence.getAttribute('from'),
const jid = presence.getAttribute('from'),
show = _.propertyOf(presence.querySelector('show'))('textContent') || 'online',
show = _.propertyOf(presence.querySelector('show'))('textContent') || 'online',
resource = Strophe.getResourceFromJid(jid),
resource = Strophe.getResourceFromJid(jid),
delay = presence.querySelector(
delay = sizzle(`delay[xmlns="${Strophe.NS.DELAY}"]`, presence).pop(),
`delay[xmlns="${Strophe.NS.DELAY}"]`
timestamp = _.isNil(delay) ? moment().format() : moment(delay.getAttribute('stamp')).format();
),
timestamp = _.isNull(delay) ? moment().format() : moment(delay.getAttribute('stamp')).format();
let priority = _.propertyOf(presence.querySelector('priority'))('textContent') || 0;
let priority = _.propertyOf(presence.querySelector('priority'))('textContent') || 0;
priority = _.isNaN(parseInt(priority, 10)) ? 0 : parseInt(priority, 10);
priority = _.isNaN(parseInt(priority, 10)) ? 0 : parseInt(priority, 10);
...
@@ -31512,17 +31547,17 @@ return __p
...
@@ -31512,17 +31547,17 @@ return __p
* Also redetermines the presence given that there's one less
* Also redetermines the presence given that there's one less
* resource.
* resource.
*/
*/
let resources = this.get('resources');
let resources = this.get('resources');
if (!_.isObject(resources)) {
if (!_.isObject(resources)) {
resources = {};
resources = {};
} else {
} else {
delete resources[resource];
delete resources[resource];
}
}
this.save({
this.save({
'resources': resources,
'resources': resources,
'show': _.propertyOf(
'show': _.propertyOf(
this.getHighestPriorityResource())('show') || 'offline'
this.getHighestPriorityResource())('show') || 'offline'
});
});
},
},
});
});
...
@@ -31998,54 +32033,64 @@ return __p
...
@@ -31998,54 +32033,64 @@ return __p
}
}
},
},
presenceHandler (presence) {
handleOwnPresence (presence) {
const presence_type = presence.getAttribute('type');
if (presence_type === 'error') { return true; }
const jid = presence.getAttribute('from'),
const jid = presence.getAttribute('from'),
bare_jid = Strophe.getBareJidFromJid(jid),
resource = Strophe.getResourceFromJid(jid),
resource = Strophe.getResourceFromJid(jid),
presence_type = presence.getAttribute('type');
status_message = _.propertyOf(presence.querySelector('status'))('textContent'),
contact = this.get(bare_jid);
if (this.isSelf(bare_jid)) {
if ((_converse.connection.jid !== jid) &&
if ((_converse.connection.jid !== jid) &&
(presence_type !== 'unavailable') &&
(presence_type !== 'unavailable') &&
(_converse.synchronize_availability === true ||
(_converse.synchronize_availability === true ||
_converse.synchronize_availability === resource)) {
_converse.synchronize_availability === resource)) {
// 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.
const show = _.propertyOf(presence.querySelector('show'))('textContent') || 'online';
const show = _.propertyOf(presence.querySelector('show'))('textContent') || 'online';
_converse.xmppstatus.save({'status': show});
_converse.xmppstatus.save({'status': show});
if (status_message) {
_converse.xmppstatus.save({'status_message': status_message});
const status_message = _.propertyOf(presence.querySelector('status'))('textContent');
}
if (status_message) {
}
_converse.xmppstatus.save({'status_message': status_message});
if (_converse.jid === jid && presence_type === 'unavailable') {
// XXX: We've received an "unavailable" presence from our
// own resource. Apparently this happens due to a
// Prosody bug, whereby we send an IQ stanza to remove
// a roster contact, and Prosody then sends
// "unavailable" globally, instead of directed to the
// particular user that's removed.
//
// Here is the bug report: https://prosody.im/issues/1121
//
// I'm not sure whether this might legitimately happen
// in other cases.
//
// As a workaround for now we simply send our presence again,
// otherwise we're treated as offline.
_converse.xmppstatus.sendPresence();
}
}
return;
}
if (_converse.jid === jid && presence_type === 'unavailable') {
// XXX: We've received an "unavailable" presence from our
// own resource. Apparently this happens due to a
// Prosody bug, whereby we send an IQ stanza to remove
// a roster contact, and Prosody then sends
// "unavailable" globally, instead of directed to the
// particular user that's removed.
//
// Here is the bug report: https://prosody.im/issues/1121
//
// I'm not sure whether this might legitimately happen
// in other cases.
//
// As a workaround for now we simply send our presence again,
// otherwise we're treated as offline.
_converse.xmppstatus.sendPresence();
}
},
presenceHandler (presence) {
const presence_type = presence.getAttribute('type');
if (presence_type === 'error') { return true; }
const jid = presence.getAttribute('from'),
bare_jid = Strophe.getBareJidFromJid(jid);
if (this.isSelf(bare_jid)) {
return this.handleOwnPresence(presence);
} else if (sizzle(`query[xmlns="${Strophe.NS.MUC}"]`, presence).length) {
} else if (sizzle(`query[xmlns="${Strophe.NS.MUC}"]`, presence).length) {
return; // Ignore MUC
return; // Ignore MUC
}
}
const status_message = _.propertyOf(presence.querySelector('status'))('textContent'),
contact = this.get(bare_jid);
if (contact && (status_message !== contact.get('status'))) {
if (contact && (status_message !== contact.get('status'))) {
contact.save({'status': status_message});
contact.save({'status': status_message});
}
}
if (presence_type === 'subscribed' && contact) {
if (presence_type === 'subscribed' && contact) {
contact.ackSubscribe();
contact.ackSubscribe();
} else if (presence_type === 'unsubscribed' && contact) {
} else if (presence_type === 'unsubscribed' && contact) {
...
@@ -32055,6 +32100,7 @@ return __p
...
@@ -32055,6 +32100,7 @@ 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) {
const resource = Strophe.getResourceFromJid(jid);
contact.presence.removeResource(resource);
contact.presence.removeResource(resource);
} else if (contact) {
} else if (contact) {
// presence_type is undefined
// presence_type is undefined
...
@@ -32110,25 +32156,28 @@ return __p
...
@@ -32110,25 +32156,28 @@ return __p
_converse.api.listen.on('beforeTearDown', _converse.unregisterPresenceHandler());
_converse.api.listen.on('beforeTearDown', _converse.unregisterPresenceHandler());
_converse.api.listen.on('afterTearDown', () => {
_converse.api.listen.on('afterTearDown', () => {
if (_converse.presence) {
if (_converse.presence
s
) {
_converse.presences.off().reset(); // Remove presences
_converse.presences.off().reset(); // Remove presences
}
}
});
});
_converse.api.listen.on('clearSession', () => {
_converse.api.listen.on('clearSession', () => {
if (
!_.isUndefined(this.roster)
) {
if (
_converse.presences
) {
this.roster
.browserStorage._clear();
_converse.presences
.browserStorage._clear();
}
}
});
});
_converse.api.listen.on('connectionInitialized', () => {
_converse.api.listen.on('statusInitialized', (reconnecting) => {
_converse.presences = new _converse.Presences();
if (!reconnecting) {
_converse.presences.browserStorage =
_converse.presences = new _converse.Presences();
new Backbone.BrowserStorage.session(b64_sha1(`converse.presences-${_converse.bare_jid}`));
_converse.presences.browserStorage =
_converse.presences.fetch();
new Backbone.BrowserStorage.session(b64_sha1(`converse.presences-${_converse.bare_jid}`));
_converse.presences.fetch();
}
_converse.emit('presencesInitialized', reconnecting);
});
});
_converse.api.listen.on('
statu
sInitialized', (reconnecting) => {
_converse.api.listen.on('
presence
sInitialized', (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
// cached data. However we still emit an event, to give
// cached data. However we still emit an event, to give
dist/converse.js
View file @
4d004a5c
...
@@ -44334,7 +44334,7 @@ return Backbone.BrowserStorage;
...
@@ -44334,7 +44334,7 @@ return Backbone.BrowserStorage;
} catch (e) {
} catch (e) {
_converse.log("Could not restore session for jid: " + this.jid + " Error message: " + e.message, Strophe.LogLevel.WARN);
_converse.log("Could not restore session for jid: " + this.jid + " Error message: " + e.message, Strophe.LogLevel.WARN);
this.clearSession(); //
If there's a roster, we want to clear it
(see #555)
this.clearSession(); //
We want to clear presences
(see #555)
return false;
return false;
}
}
...
@@ -48359,21 +48359,14 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
...
@@ -48359,21 +48359,14 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
var occupant = this.occupants.findOccupant(data);
var occupant = this.occupants.findOccupant(data);
if (data.type === 'unavailable') {
if (data.type === 'unavailable' && occupant) {
if (occupant) {
if (!_.includes(data.states, converse.MUC_NICK_CHANGED_CODE) && !occupant.isMember()) {
// Even before destroying, we set the new data, so
// We only destroy the occupant if this is not a nickname change operation.
// that we can for example show the
// and if they're not on the member lists.
// disconnection message.
// Before destroying we set the new data, so
// that we can show the disconnection message.
occupant.set(data);
occupant.set(data);
}
occupant.destroy();
if (!_.includes(data.states, converse.MUC_NICK_CHANGED_CODE)) {
// We only destroy the occupant if this is not a
// nickname change operation.
if (occupant) {
occupant.destroy();
}
return;
return;
}
}
}
}
...
@@ -48393,12 +48386,13 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
...
@@ -48393,12 +48386,13 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
},
},
parsePresence: function parsePresence(pres) {
parsePresence: function parsePresence(pres) {
var from = pres.getAttribute("from"),
var from = pres.getAttribute("from"),
type = pres.getAttribute("type"),
data = {
data = {
'from': from,
'from': from,
'nick': Strophe.getResourceFromJid(from),
'nick': Strophe.getResourceFromJid(from),
'type':
pres.getAttribute("type")
,
'type':
type
,
'states': [],
'states': [],
'show':
'on
line'
'show':
type !== 'unavailable' ? 'online' : 'off
line'
};
};
_.each(pres.childNodes, function (child) {
_.each(pres.childNodes, function (child) {
...
@@ -48649,6 +48643,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
...
@@ -48649,6 +48643,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
},
},
getDisplayName: function getDisplayName() {
getDisplayName: function getDisplayName() {
return this.get('nick') || this.get('jid');
return this.get('nick') || this.get('jid');
},
isMember: function isMember() {
return _.includes(['admin', 'owner', 'member'], this.get('affiliation'));
}
}
});
});
_converse.ChatRoomOccupants = Backbone.Collection.extend({
_converse.ChatRoomOccupants = Backbone.Collection.extend({
...
@@ -53881,31 +53878,57 @@ return __p
...
@@ -53881,31 +53878,57 @@ return __p
window.setTimeout(this.destroy.bind(this), 20000);
window.setTimeout(this.destroy.bind(this), 20000);
}
}
},
},
setVCard: function setVCard() {
getVCardForChatroomOccupant: function getVCardForChatroomOccupant() {
if (this.get('type') === 'groupchat') {
var chatbox = this.collection.chatbox,
var chatbox = this.collection.chatbox,
nick = Strophe.getResourceFromJid(this.get('from'));
nick = Strophe.getResourceFromJid(this.get('from'));
if (chatbox.get('nick') === nick) {
if (chatbox.get('nick') === nick) {
this.vcard = _converse.xmppstatus.vcard;
return _converse.xmppstatus.vcard;
} else {
} else {
var vcard;
if (this.get('vcard_jid')) {
vcard = _converse.vcards.findWhere({
'jid': this.get('vcard_jid')
});
}
if (!vcard) {
var jid;
var occupant = chatbox.occupants.findWhere({
var occupant = chatbox.occupants.findWhere({
'nick': nick
'nick': nick
});
});
var jid = occupant && occupant.get('jid') ? occupant.get('jid') : this.get('from');
this.vcard = _converse.vcards.findWhere({
if (occupant && occupant.get('jid')) {
jid = occupant.get('jid');
this.save({
'vcard_jid': jid
}, {
'silent': true
});
} else {
jid = this.get('from');
}
vcard = _converse.vcards.findWhere({
'jid': jid
'jid': jid
}) || _converse.vcards.create({
}) || _converse.vcards.create({
'jid': jid
'jid': jid
});
});
}
}
} else {
var _jid = this.get('from');
return vcard;
}
},
setVCard: function setVCard() {
if (this.get('type') === 'groupchat') {
this.vcard = this.getVCardForChatroomOccupant();
} else {
var jid = this.get('from');
this.vcard = _converse.vcards.findWhere({
this.vcard = _converse.vcards.findWhere({
'jid':
_
jid
'jid': jid
}) || _converse.vcards.create({
}) || _converse.vcards.create({
'jid':
_
jid
'jid': jid
});
});
}
}
},
},
...
@@ -54636,7 +54659,7 @@ return __p
...
@@ -54636,7 +54659,7 @@ return __p
delete _converse.chatboxes.browserStorage;
delete _converse.chatboxes.browserStorage;
});
});
_converse.api.listen.on('
statu
sInitialized', function () {
_converse.api.listen.on('
presence
sInitialized', function () {
return _converse.chatboxes.onConnected();
return _converse.chatboxes.onConnected();
});
});
/************************ END Event Handlers ************************/
/************************ END Event Handlers ************************/
...
@@ -58193,10 +58216,10 @@ __e(o.label_role) +
...
@@ -58193,10 +58216,10 @@ __e(o.label_role) +
__e(o.role) +
__e(o.role) +
'" aria-describedby="vcard-role-help">\n <small id="vcard-role-help" class="form-text text-muted">' +
'" aria-describedby="vcard-role-help">\n <small id="vcard-role-help" class="form-text text-muted">' +
__e(o.label_role_help) +
__e(o.label_role_help) +
'</small>\n </div>\n </div>\n <div class="modal-footer">\n <button type="button" class="btn btn-secondary" data-dismiss="modal">' +
'</small>\n </div>\n </div>\n <div class="modal-footer">\n <button type="submit" class="save-form btn btn-primary">' +
__e(o.label_close) +
'</button>\n <button type="submit" class="save-form btn btn-primary">' +
__e(o.label_save) +
__e(o.label_save) +
'</button>\n <button type="button" class="btn btn-secondary" data-dismiss="modal">' +
__e(o.label_close) +
'</button>\n </div>\n </form>\n </div>\n </div>\n</div>\n';
'</button>\n </div>\n </form>\n </div>\n </div>\n</div>\n';
return __p
return __p
};});
};});
...
@@ -60708,7 +60731,7 @@ var __t, __p = '', __e = _.escape;
...
@@ -60708,7 +60731,7 @@ var __t, __p = '', __e = _.escape;
__p += '<vCard xmlns="vcard-temp">\n <FN>' +
__p += '<vCard xmlns="vcard-temp">\n <FN>' +
__e(o.fn) +
__e(o.fn) +
'</FN>\n <NICKNAME>' +
'</FN>\n <NICKNAME>' +
__e(o.
fn
) +
__e(o.
nickname
) +
'</NICKNAME>\n <URL>' +
'</NICKNAME>\n <URL>' +
__e(o.url) +
__e(o.url) +
'</URL>\n <ROLE>' +
'</URL>\n <ROLE>' +
...
@@ -61009,6 +61032,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
...
@@ -61009,6 +61032,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
image_file = form_data.get('image');
image_file = form_data.get('image');
var data = {
var data = {
'fn': form_data.get('fn'),
'fn': form_data.get('fn'),
'nickname': form_data.get('nickname'),
'role': form_data.get('role'),
'role': form_data.get('role'),
'email': form_data.get('email'),
'email': form_data.get('email'),
'url': form_data.get('url')
'url': form_data.get('url')
...
@@ -62242,7 +62266,7 @@ return __p
...
@@ -62242,7 +62266,7 @@ return __p
// an error will be raised if the plugin is not found.
// an error will be raised if the plugin is not found.
//
//
// NB: These plugins need to have already been loaded via require.js.
// NB: These plugins need to have already been loaded via require.js.
dependencies: ['converse-chatboxes', 'converse-muc', 'converse-controlbox', 'converse-rosterview'],
dependencies: ['converse-chatboxes', 'converse-muc', 'converse-
muc-views', 'converse-
controlbox', 'converse-rosterview'],
enabled: function enabled(_converse) {
enabled: function enabled(_converse) {
return _.includes(['mobile', 'fullscreen', 'embedded'], _converse.view_mode);
return _.includes(['mobile', 'fullscreen', 'embedded'], _converse.view_mode);
},
},
...
@@ -63881,7 +63905,7 @@ return __p
...
@@ -63881,7 +63905,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="c
ol col-8
">\n <div class="chat-title" title="' +
__p += '<div class="c
hatbox-title
">\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)) { ;
...
@@ -64286,7 +64310,7 @@ return __p
...
@@ -64286,7 +64310,7 @@ return __p
if (!this.roomspanel.model.get('nick')) {
if (!this.roomspanel.model.get('nick')) {
this.roomspanel.model.save({
this.roomspanel.model.save({
nick: _converse.xmppstatus.get('nickname') || Strophe.getNodeFromJid(_converse.bare_jid)
nick: _converse.xmppstatus.
vcard.
get('nickname') || Strophe.getNodeFromJid(_converse.bare_jid)
});
});
}
}
...
@@ -64684,6 +64708,17 @@ return __p
...
@@ -64684,6 +64708,17 @@ return __p
this.model.on('show', this.show, this);
this.model.on('show', this.show, this);
this.model.occupants.on('add', this.showJoinNotification, this);
this.model.occupants.on('add', this.showJoinNotification, this);
this.model.occupants.on('remove', this.showLeaveNotification, this);
this.model.occupants.on('remove', this.showLeaveNotification, this);
this.model.occupants.on('change:show', function (occupant) {
if (!occupant.isMember() || _.includes(occupant.get('states'), '303')) {
return;
}
if (occupant.get('show') === 'offline') {
_this3.showLeaveNotification(occupant);
} else if (occupant.get('show') === 'online') {
_this3.showJoinNotification(occupant);
}
});
this.createEmojiPicker();
this.createEmojiPicker();
this.createOccupantsView();
this.createOccupantsView();
this.render().insertIntoDOM();
this.render().insertIntoDOM();
...
@@ -65281,10 +65316,10 @@ return __p
...
@@ -65281,10 +65316,10 @@ return __p
}
}
},
},
onNickNameNotFound: function onNickNameNotFound(message) {
onNickNameNotFound: function onNickNameNotFound(message) {
if (_converse.muc_nickname_from_jid) {
var nick = this.getDefaultNickName();
// We try to enter the room with the node part of
// the user's JID.
if (nick) {
this.join(
this.getDefaultNickName()
);
this.join(
nick
);
} else {
} else {
this.renderNicknameForm(message);
this.renderNicknameForm(message);
}
}
...
@@ -65295,7 +65330,13 @@ return __p
...
@@ -65295,7 +65330,13 @@ return __p
* We put this in a separate method so that it can be
* We put this in a separate method so that it can be
* overridden by plugins.
* overridden by plugins.
*/
*/
return Strophe.unescapeNode(Strophe.getNodeFromJid(_converse.bare_jid));
var nick = _converse.xmppstatus.vcard.get('nickname');
if (nick) {
return nick;
} else if (_converse.muc_nickname_from_jid) {
return Strophe.unescapeNode(Strophe.getNodeFromJid(_converse.bare_jid));
}
},
},
onNicknameClash: function onNicknameClash(presence) {
onNicknameClash: function onNicknameClash(presence) {
/* When the nickname is already taken, we either render a
/* When the nickname is already taken, we either render a
...
@@ -65554,11 +65595,12 @@ return __p
...
@@ -65554,11 +65595,12 @@ return __p
this.scrollDown();
this.scrollDown();
},
},
showLeaveNotification: function showLeaveNotification(occupant) {
showLeaveNotification: function showLeaveNotification(occupant) {
var nick = occupant.get('nick');
var nick = occupant.get('nick'),
var stat = occupant.get('status');
stat = occupant.get('status'),
var last_el = this.content.lastElementChild;
last_el = this.content.lastElementChild,
last_msg_date = last_el.getAttribute('data-isodate');
if (_.includes(_.get(last_el, 'classList', []), 'chat-info') && _.get(last_el, 'dataset', {}).join === "\"".concat(nick, "\"")) {
if (_.includes(_.get(last_el, 'classList', []), 'chat-info') &&
moment(last_msg_date).isSame(new Date(), "day") &&
_.get(last_el, 'dataset', {}).join === "\"".concat(nick, "\"")) {
var message;
var message;
if (_.isNil(stat)) {
if (_.isNil(stat)) {
...
@@ -71979,14 +72021,7 @@ return __p
...
@@ -71979,14 +72021,7 @@ return __p
var u = converse.env.utils;
var u = converse.env.utils;
converse.plugins.add('converse-roster', {
converse.plugins.add('converse-roster', {
dependencies: ["converse-vcard"],
dependencies: ["converse-vcard"],
overrides: {
_tearDown: function _tearDown() {
this.__super__._tearDown.apply(this, arguments);
}
},
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.
*/
*/
...
@@ -72058,9 +72093,11 @@ return __p
...
@@ -72058,9 +72093,11 @@ return __p
};
};
_converse.Presence = Backbone.Model.extend({
_converse.Presence = Backbone.Model.extend({
defaults: {
defaults: function defaults() {
'show': 'offline',
return {
'resources': {}
'show': 'offline',
'resources': {}
};
},
},
getHighestPriorityResource: function getHighestPriorityResource() {
getHighestPriorityResource: function getHighestPriorityResource() {
/* Return the resource with the highest priority.
/* Return the resource with the highest priority.
...
@@ -72087,8 +72124,8 @@ return __p
...
@@ -72087,8 +72124,8 @@ return __p
var jid = presence.getAttribute('from'),
var jid = presence.getAttribute('from'),
show = _.propertyOf(presence.querySelector('show'))('textContent') || 'online',
show = _.propertyOf(presence.querySelector('show'))('textContent') || 'online',
resource = Strophe.getResourceFromJid(jid),
resource = Strophe.getResourceFromJid(jid),
delay =
presence.querySelector("delay[xmlns=\"".concat(Strophe.NS.DELAY, "\"]")
),
delay =
sizzle("delay[xmlns=\"".concat(Strophe.NS.DELAY, "\"]"), presence).pop(
),
timestamp = _.isN
ul
l(delay) ? moment().format() : moment(delay.getAttribute('stamp')).format();
timestamp = _.isN
i
l(delay) ? moment().format() : moment(delay.getAttribute('stamp')).format();
var priority = _.propertyOf(presence.querySelector('priority'))('textContent') || 0;
var priority = _.propertyOf(presence.querySelector('priority'))('textContent') || 0;
priority = _.isNaN(parseInt(priority, 10)) ? 0 : parseInt(priority, 10);
priority = _.isNaN(parseInt(priority, 10)) ? 0 : parseInt(priority, 10);
var resources = _.isObject(this.get('resources')) ? this.get('resources') : {};
var resources = _.isObject(this.get('resources')) ? this.get('resources') : {};
...
@@ -72661,6 +72698,48 @@ return __p
...
@@ -72661,6 +72698,48 @@ return __p
}
}
}
}
},
},
handleOwnPresence: function handleOwnPresence(presence) {
var jid = presence.getAttribute('from'),
resource = Strophe.getResourceFromJid(jid),
presence_type = presence.getAttribute('type');
if (_converse.connection.jid !== jid && presence_type !== 'unavailable' && (_converse.synchronize_availability === true || _converse.synchronize_availability === resource)) {
// Another resource has changed its status and
// synchronize_availability option set to update,
// we'll update ours as well.
var show = _.propertyOf(presence.querySelector('show'))('textContent') || 'online';
_converse.xmppstatus.save({
'status': show
});
var status_message = _.propertyOf(presence.querySelector('status'))('textContent');
if (status_message) {
_converse.xmppstatus.save({
'status_message': status_message
});
}
}
if (_converse.jid === jid && presence_type === 'unavailable') {
// XXX: We've received an "unavailable" presence from our
// own resource. Apparently this happens due to a
// Prosody bug, whereby we send an IQ stanza to remove
// a roster contact, and Prosody then sends
// "unavailable" globally, instead of directed to the
// particular user that's removed.
//
// Here is the bug report: https://prosody.im/issues/1121
//
// I'm not sure whether this might legitimately happen
// in other cases.
//
// As a workaround for now we simply send our presence again,
// otherwise we're treated as offline.
_converse.xmppstatus.sendPresence();
}
},
presenceHandler: function presenceHandler(presence) {
presenceHandler: function presenceHandler(presence) {
var presence_type = presence.getAttribute('type');
var presence_type = presence.getAttribute('type');
...
@@ -72669,52 +72748,17 @@ return __p
...
@@ -72669,52 +72748,17 @@ 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),
status_message = _.propertyOf(presence.querySelector('status'))('textContent'),
contact = this.get(bare_jid);
if (this.isSelf(bare_jid)) {
if (this.isSelf(bare_jid)) {
if (_converse.connection.jid !== jid && presence_type !== 'unavailable' && (_converse.synchronize_availability === true || _converse.synchronize_availability === resource)) {
return this.handleOwnPresence(presence);
// Another resource has changed its status and
// synchronize_availability option set to update,
// we'll update ours as well.
var show = _.propertyOf(presence.querySelector('show'))('textContent') || 'online';
_converse.xmppstatus.save({
'status': show
});
if (status_message) {
_converse.xmppstatus.save({
'status_message': status_message
});
}
}
if (_converse.jid === jid && presence_type === 'unavailable') {
// XXX: We've received an "unavailable" presence from our
// own resource. Apparently this happens due to a
// Prosody bug, whereby we send an IQ stanza to remove
// a roster contact, and Prosody then sends
// "unavailable" globally, instead of directed to the
// particular user that's removed.
//
// Here is the bug report: https://prosody.im/issues/1121
//
// I'm not sure whether this might legitimately happen
// in other cases.
//
// As a workaround for now we simply send our presence again,
// otherwise we're treated as offline.
_converse.xmppstatus.sendPresence();
}
return;
} else if (sizzle("query[xmlns=\"".concat(Strophe.NS.MUC, "\"]"), presence).length) {
} else if (sizzle("query[xmlns=\"".concat(Strophe.NS.MUC, "\"]"), presence).length) {
return; // Ignore MUC
return; // Ignore MUC
}
}
var status_message = _.propertyOf(presence.querySelector('status'))('textContent'),
contact = this.get(bare_jid);
if (contact && status_message !== contact.get('status')) {
if (contact && status_message !== contact.get('status')) {
contact.save({
contact.save({
'status': status_message
'status': status_message
...
@@ -72730,6 +72774,7 @@ return __p
...
@@ -72730,6 +72774,7 @@ 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) {
var resource = Strophe.getResourceFromJid(jid);
contact.presence.removeResource(resource);
contact.presence.removeResource(resource);
} else if (contact) {
} else if (contact) {
// presence_type is undefined
// presence_type is undefined
...
@@ -72782,26 +72827,30 @@ return __p
...
@@ -72782,26 +72827,30 @@ return __p
_converse.api.listen.on('beforeTearDown', _converse.unregisterPresenceHandler());
_converse.api.listen.on('beforeTearDown', _converse.unregisterPresenceHandler());
_converse.api.listen.on('afterTearDown', function () {
_converse.api.listen.on('afterTearDown', function () {
if (_converse.presence) {
if (_converse.presence
s
) {
_converse.presences.off().reset(); // Remove presences
_converse.presences.off().reset(); // Remove presences
}
}
});
});
_converse.api.listen.on('clearSession', function () {
_converse.api.listen.on('clearSession', function () {
if (
!_.isUndefined(_this6.roster)
) {
if (
_converse.presences
) {
_
this6.roster
.browserStorage._clear();
_
converse.presences
.browserStorage._clear();
}
}
});
});
_converse.api.listen.on('connectionInitialized', function () {
_converse.api.listen.on('statusInitialized', function (reconnecting) {
_converse.presences = new _converse.Presences();
if (!reconnecting) {
_converse.presences.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.presences-".concat(_converse.bare_jid)));
_converse.presences = new _converse.Presences();
_converse.presences.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.presences-".concat(_converse.bare_jid)));
_converse.presences.fetch();
}
_converse.
presences.fetch(
);
_converse.
emit('presencesInitialized', reconnecting
);
});
});
_converse.api.listen.on('
statu
sInitialized', function (reconnecting) {
_converse.api.listen.on('
presence
sInitialized', 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
// cached data. However we still emit an event, to give
// cached data. However we still emit an event, to give
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment