disco: Create new plugin converse-disco
.
We can now support feature discovery for multiple entities (although we currently still only query for the user's own XMPP server).
This commit is contained in:
parent
00484280c2
commit
7850c38faa
@ -59,7 +59,7 @@
|
||||
"dot-notation": [
|
||||
"error",
|
||||
{
|
||||
"allowKeywords": false
|
||||
"allowKeywords": true
|
||||
}
|
||||
],
|
||||
"eol-last": "error",
|
||||
|
@ -2,6 +2,11 @@
|
||||
|
||||
## 3.2.0 (Unreleased)
|
||||
|
||||
### New Plugins
|
||||
- New plugin `converse-disco` which replaces the original support for
|
||||
[XEP-0030](https://xmpp.org/extensions/xep-0030.html) and which has been
|
||||
refactored to allow features for multiple entities to be stored. [jcbrand]
|
||||
|
||||
### New features and improvements
|
||||
- Add support for Emojis (either native, or via <a href="https://www.emojione.com/">Emojione</a>). [jcbrand]
|
||||
- Add JID validation in the contact add form. [jcbrand]
|
||||
|
@ -53,7 +53,11 @@
|
||||
|
||||
describe("A chat state indication", function () {
|
||||
|
||||
it("are sent out when the client becomes or stops being idle", mock.initConverse(function (_converse) {
|
||||
it("are sent out when the client becomes or stops being idle",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['discoInitialized'], {},
|
||||
function (done, _converse) {
|
||||
|
||||
spyOn(_converse, 'sendCSI').and.callThrough();
|
||||
var sent_stanza;
|
||||
spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
|
||||
@ -61,7 +65,7 @@
|
||||
});
|
||||
var i = 0;
|
||||
_converse.idle_seconds = 0; // Usually initialized by registerIntervalHandler
|
||||
_converse.features['urn:xmpp:csi:0'] = true; // Mock that the server supports CSI
|
||||
_converse.disco_entities.get(_converse.domain).features['urn:xmpp:csi:0'] = true; // Mock that the server supports CSI
|
||||
|
||||
_converse.csi_waiting_time = 3; // The relevant config option
|
||||
while (i <= _converse.csi_waiting_time) {
|
||||
@ -78,10 +82,10 @@
|
||||
expect(sent_stanza.toLocaleString()).toBe(
|
||||
"<active xmlns='urn:xmpp:csi:0'/>"
|
||||
);
|
||||
|
||||
// Reset values
|
||||
_converse.csi_waiting_time = 0;
|
||||
_converse.features['urn:xmpp:csi:0'] = false;
|
||||
_converse.disco_entities.get(_converse.domain).features['urn:xmpp:csi:0'] = false;
|
||||
done();
|
||||
}));
|
||||
});
|
||||
|
||||
|
@ -11,11 +11,16 @@
|
||||
|
||||
describe("Service Discovery", function () {
|
||||
describe("Whenever converse.js discovers a new server feature", function () {
|
||||
it("emits the serviceDiscovered event", mock.initConverse(function (_converse) {
|
||||
it("emits the serviceDiscovered event",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['discoInitialized'], {},
|
||||
function (done, _converse) {
|
||||
|
||||
sinon.spy(_converse, 'emit');
|
||||
_converse.features.create({'var': Strophe.NS.MAM});
|
||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||
expect(_converse.emit.called).toBe(true);
|
||||
expect(_converse.emit.args[0][1].get('var')).toBe(Strophe.NS.MAM);
|
||||
done();
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
55
spec/mam.js
55
spec/mam.js
@ -15,20 +15,25 @@
|
||||
|
||||
describe("The archive.query API", function () {
|
||||
|
||||
it("can be used to query for all archived messages", mock.initConverse(function (_converse) {
|
||||
it("can be used to query for all archived messages",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['discoInitialized'], {},
|
||||
function (done, _converse) {
|
||||
|
||||
var sent_stanza, IQ_id;
|
||||
var sendIQ = _converse.connection.sendIQ;
|
||||
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
||||
sent_stanza = iq;
|
||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||
});
|
||||
if (!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.features.create({'var': Strophe.NS.MAM});
|
||||
if (!_converse.disco_entities.get(_converse.domain).features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||
}
|
||||
_converse.api.archive.query();
|
||||
var queryid = $(sent_stanza.toString()).find('query').attr('queryid');
|
||||
expect(sent_stanza.toString()).toBe(
|
||||
"<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'><query xmlns='urn:xmpp:mam:2' queryid='"+queryid+"'/></iq>");
|
||||
done();
|
||||
}));
|
||||
|
||||
it("can be used to query for all messages to/from a particular JID", mock.initConverse(function (_converse) {
|
||||
@ -38,8 +43,8 @@
|
||||
sent_stanza = iq;
|
||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||
});
|
||||
if (!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.features.create({'var': Strophe.NS.MAM});
|
||||
if (!_converse.disco_entities.get(_converse.domain).features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||
}
|
||||
_converse.api.archive.query({'with':'juliet@capulet.lit'});
|
||||
var queryid = $(sent_stanza.toString()).find('query').attr('queryid');
|
||||
@ -66,8 +71,8 @@
|
||||
sent_stanza = iq;
|
||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||
});
|
||||
if (!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.features.create({'var': Strophe.NS.MAM});
|
||||
if (!_converse.disco_entities.get(_converse.domain).features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||
}
|
||||
var start = '2010-06-07T00:00:00Z';
|
||||
var end = '2010-07-07T13:23:54Z';
|
||||
@ -97,8 +102,8 @@
|
||||
}));
|
||||
|
||||
it("throws a TypeError if an invalid date is provided", mock.initConverse(function (_converse) {
|
||||
if (!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.features.create({'var': Strophe.NS.MAM});
|
||||
if (!_converse.disco_entities.get(_converse.domain).features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||
}
|
||||
expect(_.partial(_converse.api.archive.query, {'start': 'not a real date'})).toThrow(
|
||||
new TypeError('archive.query: invalid date provided for: start')
|
||||
@ -112,8 +117,8 @@
|
||||
sent_stanza = iq;
|
||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||
});
|
||||
if (!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.features.create({'var': Strophe.NS.MAM});
|
||||
if (!_converse.disco_entities.get(_converse.domain).features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||
}
|
||||
var start = '2010-06-07T00:00:00Z';
|
||||
_converse.api.archive.query({'start': start});
|
||||
@ -141,8 +146,8 @@
|
||||
sent_stanza = iq;
|
||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||
});
|
||||
if (!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.features.create({'var': Strophe.NS.MAM});
|
||||
if (!_converse.disco_entities.get(_converse.domain).features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||
}
|
||||
var start = '2010-06-07T00:00:00Z';
|
||||
_converse.api.archive.query({'start': start, 'max':10});
|
||||
@ -173,8 +178,8 @@
|
||||
sent_stanza = iq;
|
||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||
});
|
||||
if (!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.features.create({'var': Strophe.NS.MAM});
|
||||
if (!_converse.disco_entities.get(_converse.domain).features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||
}
|
||||
var start = '2010-06-07T00:00:00Z';
|
||||
_converse.api.archive.query({
|
||||
@ -210,8 +215,8 @@
|
||||
sent_stanza = iq;
|
||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||
});
|
||||
if (!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.features.create({'var': Strophe.NS.MAM});
|
||||
if (!_converse.disco_entities.get(_converse.domain).features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||
}
|
||||
_converse.api.archive.query({'before': '', 'max':10});
|
||||
var queryid = $(sent_stanza.toString()).find('query').attr('queryid');
|
||||
@ -237,8 +242,8 @@
|
||||
// and pass it in. However, in the callback method an RSM object is
|
||||
// returned which can be reused for easy paging. This test is
|
||||
// more for that usecase.
|
||||
if (!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.features.create({'var': Strophe.NS.MAM});
|
||||
if (!_converse.disco_entities.get(_converse.domain).features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||
}
|
||||
var sent_stanza, IQ_id;
|
||||
var sendIQ = _converse.connection.sendIQ;
|
||||
@ -247,7 +252,7 @@
|
||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||
});
|
||||
var rsm = new Strophe.RSM({'max': '10'});
|
||||
rsm['with'] = 'romeo@montague.lit';
|
||||
rsm['with'] = 'romeo@montague.lit'; // eslint-disable-line dot-notation
|
||||
rsm.start = '2010-06-07T00:00:00Z';
|
||||
_converse.api.archive.query(rsm);
|
||||
|
||||
@ -275,8 +280,8 @@
|
||||
}));
|
||||
|
||||
it("accepts a callback function, which it passes the messages and a Strophe.RSM object", mock.initConverse(function (_converse) {
|
||||
if (!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.features.create({'var': Strophe.NS.MAM});
|
||||
if (!_converse.disco_entities.get(_converse.domain).features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||
}
|
||||
var sent_stanza, IQ_id;
|
||||
var sendIQ = _converse.connection.sendIQ;
|
||||
@ -351,7 +356,7 @@
|
||||
expect(args[0].length).toBe(2);
|
||||
expect(args[0][0].outerHTML).toBe(msg1.nodeTree.outerHTML);
|
||||
expect(args[0][1].outerHTML).toBe(msg2.nodeTree.outerHTML);
|
||||
expect(args[1]['with']).toBe('romeo@capulet.lit');
|
||||
expect(args[1]['with']).toBe('romeo@capulet.lit'); // eslint-disable-line dot-notation
|
||||
expect(args[1].max).toBe('10');
|
||||
expect(args[1].count).toBe('16');
|
||||
expect(args[1].first).toBe('23452-4534-1');
|
||||
@ -376,7 +381,7 @@
|
||||
'var': Strophe.NS.MAM
|
||||
});
|
||||
spyOn(feature, 'save').and.callFake(feature.set); // Save will complain about a url not being set
|
||||
_converse.features.onFeatureAdded(feature);
|
||||
_converse.disco_entities.get(_converse.domain).features.onFeatureAdded(feature);
|
||||
|
||||
expect(_converse.connection.sendIQ).toHaveBeenCalled();
|
||||
expect(sent_stanza.toLocaleString()).toBe(
|
||||
@ -430,7 +435,7 @@
|
||||
.c('never').up();
|
||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||
expect(feature.save).toHaveBeenCalled();
|
||||
expect(feature.get('preferences')['default']).toBe('never');
|
||||
expect(feature.get('preferences')['default']).toBe('never'); // eslint-disable-line dot-notation
|
||||
|
||||
// Restore
|
||||
_converse.message_archiving = 'never';
|
||||
|
@ -55,6 +55,7 @@ require.config({
|
||||
"converse-chatview": "src/converse-chatview",
|
||||
"converse-controlbox": "src/converse-controlbox",
|
||||
"converse-core": "src/converse-core",
|
||||
"converse-disco": "src/converse-disco",
|
||||
"converse-dragresize": "src/converse-dragresize",
|
||||
"converse-headline": "src/converse-headline",
|
||||
"converse-inverse": "src/converse-inverse",
|
||||
|
@ -16,7 +16,6 @@
|
||||
"strophe",
|
||||
"pluggable",
|
||||
"backbone.noconflict",
|
||||
"strophe.disco",
|
||||
"backbone.browserStorage",
|
||||
"backbone.overview",
|
||||
], factory);
|
||||
@ -59,6 +58,7 @@
|
||||
'converse-chatview',
|
||||
'converse-controlbox',
|
||||
'converse-core',
|
||||
'converse-disco',
|
||||
'converse-dragresize',
|
||||
'converse-headline',
|
||||
'converse-mam',
|
||||
@ -794,16 +794,11 @@
|
||||
// If there's no xmppstatus obj, then we were never connected to
|
||||
// begin with, so we set reconnecting to false.
|
||||
reconnecting = _.isUndefined(_converse.xmppstatus) ? false : reconnecting;
|
||||
|
||||
if (reconnecting) {
|
||||
_converse.onStatusInitialized(true);
|
||||
_converse.emit('reconnected');
|
||||
} else {
|
||||
// There might be some open chat boxes. We don't
|
||||
// know whether these boxes are of the same account or not, so we
|
||||
// close them now.
|
||||
_converse.chatboxviews.closeAllChatBoxes();
|
||||
_converse.features = new _converse.Features();
|
||||
_converse.initStatus()
|
||||
.then(
|
||||
_.partial(_converse.onStatusInitialized, false),
|
||||
@ -1866,88 +1861,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
this.Features = Backbone.Collection.extend({
|
||||
/* Service Discovery
|
||||
* -----------------
|
||||
* This collection stores Feature Models, representing features
|
||||
* provided by available XMPP entities (e.g. servers)
|
||||
* See XEP-0030 for more details: http://xmpp.org/extensions/xep-0030.html
|
||||
* All features are shown here: http://xmpp.org/registrar/disco-features.html
|
||||
*/
|
||||
model: Backbone.Model,
|
||||
initialize () {
|
||||
this.addClientIdentities().addClientFeatures();
|
||||
this.browserStorage = new Backbone.BrowserStorage[_converse.storage](
|
||||
b64_sha1(`converse.features${_converse.bare_jid}`)
|
||||
);
|
||||
this.on('add', this.onFeatureAdded, this);
|
||||
this.fetchFeatures();
|
||||
},
|
||||
|
||||
fetchFeatures () {
|
||||
if (this.browserStorage.records.length === 0) {
|
||||
// browserStorage is empty, so we've likely never queried this
|
||||
// domain for features yet
|
||||
_converse.connection.disco.info(_converse.domain, null, this.onInfo.bind(this));
|
||||
_converse.connection.disco.items(_converse.domain, null, this.onItems.bind(this));
|
||||
} else {
|
||||
this.fetch({add:true});
|
||||
}
|
||||
},
|
||||
|
||||
onFeatureAdded (feature) {
|
||||
_converse.emit('serviceDiscovered', feature);
|
||||
},
|
||||
|
||||
addClientIdentities () {
|
||||
/* See http://xmpp.org/registrar/disco-categories.html
|
||||
*/
|
||||
_converse.connection.disco.addIdentity('client', 'web', 'Converse.js');
|
||||
return this;
|
||||
},
|
||||
|
||||
addClientFeatures () {
|
||||
/* The strophe.disco.js plugin keeps a list of features which
|
||||
* it will advertise to any #info queries made to it.
|
||||
*
|
||||
* See: http://xmpp.org/extensions/xep-0030.html#info
|
||||
*/
|
||||
_converse.connection.disco.addFeature(Strophe.NS.BOSH);
|
||||
_converse.connection.disco.addFeature(Strophe.NS.CHATSTATES);
|
||||
_converse.connection.disco.addFeature(Strophe.NS.DISCO_INFO);
|
||||
_converse.connection.disco.addFeature(Strophe.NS.ROSTERX); // Limited support
|
||||
if (_converse.message_carbons) {
|
||||
_converse.connection.disco.addFeature(Strophe.NS.CARBONS);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
onItems (stanza) {
|
||||
_.each(stanza.querySelectorAll('query item'), (item) => {
|
||||
_converse.connection.disco.info(
|
||||
item.getAttribute('jid'),
|
||||
null,
|
||||
this.onInfo.bind(this));
|
||||
});
|
||||
},
|
||||
|
||||
onInfo (stanza) {
|
||||
if ((sizzle('identity[category=server][type=im]', stanza).length === 0) &&
|
||||
(sizzle('identity[category=conference][type=text]', stanza).length === 0)) {
|
||||
// This isn't an IM server component
|
||||
return;
|
||||
}
|
||||
_.forEach(stanza.querySelectorAll('feature'), (feature) => {
|
||||
const namespace = feature.getAttribute('var');
|
||||
this[namespace] = true;
|
||||
this.create({
|
||||
'var': namespace,
|
||||
'from': stanza.getAttribute('from')
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.setUpXMLLogging = function () {
|
||||
Strophe.log = function (level, msg) {
|
||||
_converse.log(msg, level);
|
||||
@ -2165,16 +2078,13 @@
|
||||
/* Remove those views which are only allowed with a valid
|
||||
* connection.
|
||||
*/
|
||||
_converse.emit('beforeTearDown');
|
||||
this.unregisterPresenceHandler();
|
||||
if (this.roster) {
|
||||
this.roster.off().reset(); // Removes roster contacts
|
||||
}
|
||||
this.chatboxes.remove(); // Don't call off(), events won't get re-registered upon reconnect.
|
||||
delete this.chatboxes.browserStorage;
|
||||
if (this.features) {
|
||||
this.features.reset();
|
||||
this.features.browserStorage._clear();
|
||||
}
|
||||
this.session.destroy();
|
||||
window.removeEventListener('click', _converse.onUserActivity);
|
||||
window.removeEventListener('focus', _converse.onUserActivity);
|
||||
@ -2182,6 +2092,7 @@
|
||||
window.removeEventListener('mousemove', _converse.onUserActivity);
|
||||
window.removeEventListener(unloadevent, _converse.onUserActivity);
|
||||
window.clearInterval(_converse.everySecondTrigger);
|
||||
_converse.emit('afterTearDown');
|
||||
return this;
|
||||
};
|
||||
|
||||
|
@ -84,7 +84,12 @@
|
||||
* All features are shown here: http://xmpp.org/registrar/disco-features.html
|
||||
*/
|
||||
model: Backbone.Model,
|
||||
initialize (jid) {
|
||||
|
||||
initialize (settings) {
|
||||
const jid = settings.jid;
|
||||
if (_.isNil(jid)) {
|
||||
throw new Error('DiscoEntity must be instantiated with a JID');
|
||||
}
|
||||
this.addClientIdentities().addClientFeatures();
|
||||
this.browserStorage = new Backbone.BrowserStorage[_converse.storage](
|
||||
b64_sha1(`converse.features-${jid}`)
|
||||
@ -158,9 +163,11 @@
|
||||
}
|
||||
});
|
||||
|
||||
_converse.api.waitUntil('connected').then(() => {
|
||||
function initializeDisco () {
|
||||
_converse.disco_entities = new _converse.DiscoEntities();
|
||||
});
|
||||
}
|
||||
_converse.api.listen.on('reconnected', initializeDisco);
|
||||
_converse.api.listen.on('connected', initializeDisco);
|
||||
|
||||
_converse.api.listen.on('beforeTearDown', () => {
|
||||
if (_converse.disco_entities) {
|
||||
|
@ -11,6 +11,7 @@
|
||||
(function (root, factory) {
|
||||
define(["jquery.noconflict",
|
||||
"converse-core",
|
||||
"converse-disco",
|
||||
"converse-chatview", // Could be made a soft dependency
|
||||
"converse-muc", // Could be made a soft dependency
|
||||
"strophe.rsm"
|
||||
@ -31,15 +32,6 @@
|
||||
// relevant objects or classes.
|
||||
//
|
||||
// New functions which don't exist yet can also be added.
|
||||
|
||||
Features: {
|
||||
addClientFeatures () {
|
||||
const { _converse } = this.__super__;
|
||||
_converse.connection.disco.addFeature(Strophe.NS.MAM);
|
||||
return this.__super__.addClientFeatures.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
|
||||
ChatBox: {
|
||||
getMessageAttributes ($message, $delay, original_stanza) {
|
||||
const attrs = this.__super__.getMessageAttributes.apply(this, arguments);
|
||||
@ -60,7 +52,8 @@
|
||||
afterMessagesFetched () {
|
||||
const { _converse } = this.__super__;
|
||||
if (this.disable_mam ||
|
||||
!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
!_converse.disco_entities.get(_converse.domain)
|
||||
.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
return this.__super__.afterMessagesFetched.apply(this, arguments);
|
||||
}
|
||||
if (!this.model.get('mam_initialized') &&
|
||||
@ -83,7 +76,9 @@
|
||||
* box, so that they are displayed inside it.
|
||||
*/
|
||||
const { _converse } = this.__super__;
|
||||
if (!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
if (!_converse.disco_entities.get(_converse.domain)
|
||||
.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
|
||||
_converse.log(
|
||||
"Attempted to fetch archived messages but this "+
|
||||
"user's server doesn't support XEP-0313",
|
||||
@ -167,7 +162,9 @@
|
||||
* so that they are displayed inside it.
|
||||
*/
|
||||
const { _converse } = this.__super__;
|
||||
if (!_converse.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
if (!_converse.disco_entities.get(_converse.domain)
|
||||
.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||
|
||||
_converse.log(
|
||||
"Attempted to fetch archived messages but this "+
|
||||
"user's server doesn't support XEP-0313",
|
||||
@ -237,12 +234,12 @@
|
||||
const queryid = _converse.connection.getUniqueId();
|
||||
const attrs = {'type':'set'};
|
||||
if (!_.isUndefined(options) && options.groupchat) {
|
||||
if (!options['with']) {
|
||||
if (!options['with']) { // eslint-disable-line dot-notation
|
||||
throw new Error(
|
||||
'You need to specify a "with" value containing '+
|
||||
'the chat room JID, when querying groupchat messages.');
|
||||
}
|
||||
attrs.to = options['with'];
|
||||
attrs.to = options['with']; // eslint-disable-line dot-notation
|
||||
}
|
||||
const stanza = $iq(attrs).c('query', {'xmlns':Strophe.NS.MAM, 'queryid':queryid});
|
||||
if (!_.isUndefined(options)) {
|
||||
@ -250,8 +247,9 @@
|
||||
.c('field', {'var':'FORM_TYPE', 'type': 'hidden'})
|
||||
.c('value').t(Strophe.NS.MAM).up().up();
|
||||
|
||||
if (options['with'] && !options.groupchat) {
|
||||
stanza.c('field', {'var':'with'}).c('value').t(options['with']).up().up();
|
||||
if (options['with'] && !options.groupchat) { // eslint-disable-line dot-notation
|
||||
stanza.c('field', {'var':'with'}).c('value')
|
||||
.t(options['with']).up().up(); // eslint-disable-line dot-notation
|
||||
}
|
||||
_.each(['start', 'end'], function (t) {
|
||||
if (options[t]) {
|
||||
@ -352,11 +350,11 @@
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const onFeatureAdded = function (feature) {
|
||||
/* Event handlers */
|
||||
_converse.on('serviceDiscovered', (feature) => {
|
||||
const prefs = feature.get('preferences') || {};
|
||||
if (feature.get('var') === Strophe.NS.MAM &&
|
||||
prefs['default'] !== _converse.message_archiving &&
|
||||
prefs['default'] !== _converse.message_archiving && // eslint-disable-line dot-notation
|
||||
!_.isUndefined(_converse.message_archiving) ) {
|
||||
// Ask the server for archiving preferences
|
||||
_converse.connection.sendIQ(
|
||||
@ -365,8 +363,11 @@
|
||||
_.partial(_converse.onMAMError, feature)
|
||||
);
|
||||
}
|
||||
};
|
||||
_converse.on('serviceDiscovered', onFeatureAdded.bind(_converse.features));
|
||||
});
|
||||
|
||||
_converse.on('addClientFeatures', () => {
|
||||
_converse.connection.disco.addFeature(Strophe.NS.MAM);
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
@ -32,7 +32,8 @@
|
||||
"tpl!room_panel",
|
||||
"tpl!spinner",
|
||||
"awesomplete",
|
||||
"converse-chatview"
|
||||
"converse-chatview",
|
||||
"converse-disco"
|
||||
], factory);
|
||||
}(this, function (
|
||||
$,
|
||||
@ -130,19 +131,6 @@
|
||||
this.__super__._tearDown.call(this, arguments);
|
||||
},
|
||||
|
||||
Features: {
|
||||
addClientFeatures () {
|
||||
const { _converse } = this.__super__;
|
||||
this.__super__.addClientFeatures.apply(this, arguments);
|
||||
if (_converse.allow_muc_invitations) {
|
||||
_converse.connection.disco.addFeature('jabber:x:conference'); // Invites
|
||||
}
|
||||
if (_converse.allow_muc) {
|
||||
_converse.connection.disco.addFeature(Strophe.NS.MUC);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ChatBoxes: {
|
||||
model (attrs, options) {
|
||||
const { _converse } = this.__super__;
|
||||
@ -182,6 +170,33 @@
|
||||
}
|
||||
},
|
||||
|
||||
featureAdded (feature) {
|
||||
const { _converse } = this.__super__;
|
||||
if ((feature.get('var') === Strophe.NS.MUC) && (_converse.allow_muc)) {
|
||||
this.setMUCDomain(feature.get('from'));
|
||||
}
|
||||
},
|
||||
|
||||
getMUCDomainFromDisco () {
|
||||
/* Check whether service discovery for the user's domain
|
||||
* returned MUC information and use that to automatically
|
||||
* set the MUC domain for the "Rooms" panel of the
|
||||
* controlbox.
|
||||
*/
|
||||
const { _converse } = this.__super__;
|
||||
_converse.api.waitUntil('discoInitialized').then(() => {
|
||||
_converse.api.listen.on('serviceDiscovered', this.featureAdded, this);
|
||||
// Features could have been added before the controlbox was
|
||||
// initialized. We're only interested in MUC
|
||||
const feature = _converse.disco_entities[_converse.domain].features.findWhere({
|
||||
'var': Strophe.NS.MUC
|
||||
});
|
||||
if (feature) {
|
||||
this.featureAdded(feature);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onConnected () {
|
||||
const { _converse } = this.__super__;
|
||||
this.__super__.onConnected.apply(this, arguments);
|
||||
@ -189,34 +204,20 @@
|
||||
return;
|
||||
}
|
||||
if (_.isUndefined(_converse.muc_domain)) {
|
||||
_converse.features.off('add', this.featureAdded, this);
|
||||
_converse.features.on('add', this.featureAdded, this);
|
||||
// Features could have been added before the controlbox was
|
||||
// initialized. We're only interested in MUC
|
||||
const feature = _converse.features.findWhere({
|
||||
'var': Strophe.NS.MUC
|
||||
});
|
||||
if (feature) {
|
||||
this.featureAdded(feature);
|
||||
}
|
||||
this.getMUCDomainFromDisco();
|
||||
} else {
|
||||
this.setMUCDomain(_converse.muc_domain);
|
||||
}
|
||||
},
|
||||
|
||||
setMUCDomain (domain) {
|
||||
const { _converse } = this.__super__;
|
||||
_converse.muc_domain = domain;
|
||||
this.roomspanel.model.save({'muc_domain': domain});
|
||||
const $server= this.$el.find('input.new-chatroom-server');
|
||||
if (!$server.is(':focus')) {
|
||||
$server.val(this.roomspanel.model.get('muc_domain'));
|
||||
}
|
||||
},
|
||||
|
||||
featureAdded (feature) {
|
||||
const { _converse } = this.__super__;
|
||||
if ((feature.get('var') === Strophe.NS.MUC) && (_converse.allow_muc)) {
|
||||
this.setMUCDomain(feature.get('from'));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -1974,7 +1975,7 @@
|
||||
return false;
|
||||
} else {
|
||||
return this.model.messages.where({
|
||||
'sender': this.model.get('nick'),
|
||||
'sender': 'me',
|
||||
'message': this.model.getMessageBody(message)
|
||||
}).filter(
|
||||
(msg) => Math.abs(moment(msg.get('time')).diff(moment.unix(ts))) < 2000
|
||||
@ -2778,7 +2779,17 @@
|
||||
}
|
||||
});
|
||||
|
||||
function reconnectToChatRooms () {
|
||||
/* Event handlers */
|
||||
_converse.on('addClientFeatures', () => {
|
||||
if (_converse.allow_muc) {
|
||||
_converse.connection.disco.addFeature(Strophe.NS.MUC);
|
||||
}
|
||||
if (_converse.allow_muc_invitations) {
|
||||
_converse.connection.disco.addFeature('jabber:x:conference'); // Invites
|
||||
}
|
||||
});
|
||||
|
||||
_converse.on('reconnected', function reconnectToChatRooms () {
|
||||
/* Upon a reconnection event from converse, join again
|
||||
* all the open chat rooms.
|
||||
*/
|
||||
@ -2790,8 +2801,7 @@
|
||||
view.fetchMessages();
|
||||
}
|
||||
});
|
||||
}
|
||||
_converse.on('reconnected', reconnectToChatRooms);
|
||||
});
|
||||
|
||||
function disconnectChatRooms () {
|
||||
/* When disconnecting, or reconnecting, mark all chat rooms as
|
||||
|
@ -34,7 +34,7 @@
|
||||
// However, some servers don't advertise while still keeping the
|
||||
// connection option due to pings.
|
||||
//
|
||||
// var feature = _converse.features.findWhere({'var': Strophe.NS.PING});
|
||||
// var feature = _converse.disco_entities[_converse.domain].features.findWhere({'var': Strophe.NS.PING});
|
||||
_converse.lastStanzaDate = new Date();
|
||||
if (_.isNil(jid)) {
|
||||
jid = Strophe.getDomainFromJid(_converse.bare_jid);
|
||||
|
@ -21,16 +21,6 @@
|
||||
//
|
||||
// New functions which don't exist yet can also be added.
|
||||
|
||||
Features: {
|
||||
addClientFeatures () {
|
||||
const { _converse } = this.__super__;
|
||||
this.__super__.addClientFeatures.apply(this, arguments);
|
||||
if (_converse.use_vcards) {
|
||||
_converse.connection.disco.addFeature(Strophe.NS.VCARD);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
RosterContacts: {
|
||||
createRequestingContact (presence) {
|
||||
const { _converse } = this.__super__;
|
||||
@ -50,7 +40,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
initialize () {
|
||||
/* The initialize function gets called as soon as the plugin is
|
||||
* loaded by converse.js's plugin machinery.
|
||||
@ -135,6 +124,13 @@
|
||||
}
|
||||
};
|
||||
|
||||
/* Event handlers */
|
||||
_converse.on('addClientFeatures', () => {
|
||||
if (_converse.use_vcards) {
|
||||
_converse.connection.disco.addFeature(Strophe.NS.VCARD);
|
||||
}
|
||||
});
|
||||
|
||||
const updateVCardForChatBox = function (chatbox) {
|
||||
if (!_converse.use_vcards) { return; }
|
||||
const jid = chatbox.model.get('jid'),
|
||||
@ -161,7 +157,6 @@
|
||||
};
|
||||
_converse.on('chatBoxInitialized', updateVCardForChatBox);
|
||||
|
||||
|
||||
const onContactAdd = function (contact) {
|
||||
if (!contact.get('vcard_updated')) {
|
||||
// This will update the vcard, which triggers a change
|
||||
@ -173,7 +168,7 @@
|
||||
_converse.roster.on("add", onContactAdd);
|
||||
});
|
||||
|
||||
const fetchOwnVCard = function () {
|
||||
_converse.on('statusInitialized', function fetchOwnVCard () {
|
||||
if (_converse.xmppstatus.get('fullname') === undefined) {
|
||||
_converse.getVCard(
|
||||
null, // No 'to' attr when getting one's own vCard
|
||||
@ -182,8 +177,7 @@
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
_converse.on('statusInitialized', fetchOwnVCard);
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
Loading…
Reference in New Issue
Block a user