|
@@ -206,7 +206,7 @@ converse.plugins.add('converse-disco', {
|
|
|
if (stanza.querySelector(`feature[var="${Strophe.NS.DISCO_ITEMS}"]`)) {
|
|
|
this.queryForItems();
|
|
|
}
|
|
|
- _.forEach(stanza.querySelectorAll('feature'), feature => {
|
|
|
+ Array.from(stanza.querySelectorAll('feature')).forEach(feature => {
|
|
|
this.features.create({
|
|
|
'var': feature.getAttribute('var'),
|
|
|
'from': stanza.getAttribute('from')
|
|
@@ -243,6 +243,7 @@ converse.plugins.add('converse-disco', {
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+
|
|
|
function addClientFeatures () {
|
|
|
// See https://xmpp.org/registrar/disco-categories.html
|
|
|
_converse.api.disco.own.identities.add('client', 'web', 'Converse');
|
|
@@ -263,39 +264,52 @@ converse.plugins.add('converse-disco', {
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
function initStreamFeatures () {
|
|
|
- const bare_jid = Strophe.getBareJidFromJid(_converse.jid);
|
|
|
- const id = `converse.stream-features-${bare_jid}`;
|
|
|
- if (!_converse.stream_features || _converse.stream_features.browserStorage.name !== id) {
|
|
|
+ // Initialize the stream_features collection, and if we're
|
|
|
+ // re-attaching to a pre-existing BOSH session, we restore the
|
|
|
+ // features from cache.
|
|
|
+ // Otherwise the features will be created once we've received them
|
|
|
+ // from the server (see populateStreamFeatures).
|
|
|
+ if (!_converse.stream_features) {
|
|
|
+ const bare_jid = Strophe.getBareJidFromJid(_converse.jid);
|
|
|
+ const id = `converse.stream-features-${bare_jid}`;
|
|
|
+ _converse.api.promises.add('streamFeaturesAdded');
|
|
|
_converse.stream_features = new _converse.Collection();
|
|
|
_converse.stream_features.browserStorage = _converse.createStore(id, "session");
|
|
|
- _converse.stream_features.fetch({
|
|
|
- success (collection) {
|
|
|
- if (collection.length === 0 && _converse.connection.features) {
|
|
|
- Array.from(_converse.connection.features.childNodes)
|
|
|
- .forEach(feature => {
|
|
|
- _converse.stream_features.create({
|
|
|
- 'name': feature.nodeName,
|
|
|
- 'xmlns': feature.getAttribute('xmlns')
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
- /**
|
|
|
- * Triggered as soon as Converse has processed the stream features as advertised by
|
|
|
- * the server. If you want to check whether a stream feature is supported before
|
|
|
- * proceeding, then you'll first want to wait for this event.
|
|
|
- * @event _converse#streamFeaturesAdded
|
|
|
- * @example _converse.api.listen.on('streamFeaturesAdded', () => { ... });
|
|
|
- */
|
|
|
- _converse.api.trigger('streamFeaturesAdded');
|
|
|
- },
|
|
|
- error (m, e) {
|
|
|
- log.error(e);
|
|
|
- }
|
|
|
- });
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ function populateStreamFeatures () {
|
|
|
+ // Strophe.js sets the <stream:features> element on the
|
|
|
+ // Strophe.Connection instance (_converse.connection).
|
|
|
+ //
|
|
|
+ // Once this is done, we populate the _converse.stream_features collection
|
|
|
+ // and trigger streamFeaturesAdded.
|
|
|
+ initStreamFeatures();
|
|
|
+ Array.from(_converse.connection.features.childNodes).forEach(feature => {
|
|
|
+ _converse.stream_features.create({
|
|
|
+ 'name': feature.nodeName,
|
|
|
+ 'xmlns': feature.getAttribute('xmlns')
|
|
|
+ });
|
|
|
+ });
|
|
|
+ notifyStreamFeaturesAdded();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ function notifyStreamFeaturesAdded () {
|
|
|
+ /**
|
|
|
+ * Triggered as soon as the stream features are known.
|
|
|
+ * If you want to check whether a stream feature is supported before proceeding,
|
|
|
+ * then you'll first want to wait for this event.
|
|
|
+ * @event _converse#streamFeaturesAdded
|
|
|
+ * @example _converse.api.listen.on('streamFeaturesAdded', () => { ... });
|
|
|
+ */
|
|
|
+ _converse.api.trigger('streamFeaturesAdded');
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
const plugin = this;
|
|
|
plugin._identities = [];
|
|
|
plugin._features = [];
|
|
@@ -355,9 +369,15 @@ converse.plugins.add('converse-disco', {
|
|
|
|
|
|
/******************** Event Handlers ********************/
|
|
|
|
|
|
- // Re-create promise upon reconnection
|
|
|
- _converse.api.listen.on('userSessionInitialized', initStreamFeatures);
|
|
|
- _converse.api.listen.on('beforeResourceBinding', initStreamFeatures);
|
|
|
+ _converse.api.listen.on('userSessionInitialized', async () => {
|
|
|
+ initStreamFeatures();
|
|
|
+ if (_converse.connfeedback.get('connection_status') === Strophe.Status.ATTACHED) {
|
|
|
+ // When re-attaching to a BOSH session, we fetch the stream features from the cache.
|
|
|
+ await new Promise((success, error) => _converse.stream_features.fetch({ success, error }));
|
|
|
+ notifyStreamFeaturesAdded();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ _converse.api.listen.on('beforeResourceBinding', populateStreamFeatures);
|
|
|
|
|
|
_converse.api.listen.on('reconnected', initializeDisco);
|
|
|
_converse.api.listen.on('connected', initializeDisco);
|