126 lines
4.6 KiB
JavaScript
126 lines
4.6 KiB
JavaScript
import { _converse, api, converse } from "@converse/headless/core.js";
|
|
import { Collection } from "@converse/skeletor/src/collection";
|
|
|
|
const { Strophe, $iq } = converse.env;
|
|
|
|
|
|
function onDiscoInfoRequest (stanza) {
|
|
const node = stanza.getElementsByTagName('query')[0].getAttribute('node');
|
|
const attrs = {xmlns: Strophe.NS.DISCO_INFO};
|
|
if (node) { attrs.node = node; }
|
|
|
|
const iqresult = $iq({'type': 'result', 'id': stanza.getAttribute('id')});
|
|
const from = stanza.getAttribute('from');
|
|
if (from !== null) {
|
|
iqresult.attrs({'to': from});
|
|
}
|
|
iqresult.c('query', attrs);
|
|
_converse.disco._identities.forEach(identity => {
|
|
const attrs = {
|
|
'category': identity.category,
|
|
'type': identity.type
|
|
};
|
|
if (identity.name) {
|
|
attrs.name = identity.name;
|
|
}
|
|
if (identity.lang) {
|
|
attrs['xml:lang'] = identity.lang;
|
|
}
|
|
iqresult.c('identity', attrs).up();
|
|
});
|
|
_converse.disco._features.forEach(feature => iqresult.c('feature', {'var': feature}).up());
|
|
api.send(iqresult.tree());
|
|
return true;
|
|
}
|
|
|
|
|
|
function addClientFeatures () {
|
|
// See https://xmpp.org/registrar/disco-categories.html
|
|
api.disco.own.identities.add('client', 'web', 'Converse');
|
|
|
|
api.disco.own.features.add(Strophe.NS.CHATSTATES);
|
|
api.disco.own.features.add(Strophe.NS.DISCO_INFO);
|
|
api.disco.own.features.add(Strophe.NS.ROSTERX); // Limited support
|
|
if (api.settings.get("message_carbons")) {
|
|
api.disco.own.features.add(Strophe.NS.CARBONS);
|
|
}
|
|
/**
|
|
* Triggered in converse-disco once the core disco features of
|
|
* Converse have been added.
|
|
* @event _converse#addClientFeatures
|
|
* @example _converse.api.listen.on('addClientFeatures', () => { ... });
|
|
*/
|
|
api.trigger('addClientFeatures');
|
|
return this;
|
|
}
|
|
|
|
|
|
export async function initializeDisco () {
|
|
addClientFeatures();
|
|
_converse.connection.addHandler(
|
|
stanza => onDiscoInfoRequest(stanza),
|
|
Strophe.NS.DISCO_INFO,
|
|
'iq', 'get', null, null
|
|
);
|
|
|
|
_converse.disco_entities = new _converse.DiscoEntities();
|
|
const id = `converse.disco-entities-${_converse.bare_jid}`;
|
|
_converse.disco_entities.browserStorage = _converse.createStore(id, 'session');
|
|
const collection = await _converse.disco_entities.fetchEntities();
|
|
if (collection.length === 0 || !collection.get(_converse.domain)) {
|
|
// If we don't have an entity for our own XMPP server,
|
|
// create one.
|
|
_converse.disco_entities.create({'jid': _converse.domain});
|
|
}
|
|
/**
|
|
* Triggered once the `converse-disco` plugin has been initialized and the
|
|
* `_converse.disco_entities` collection will be available and populated with at
|
|
* least the service discovery features of the user's own server.
|
|
* @event _converse#discoInitialized
|
|
* @example _converse.api.listen.on('discoInitialized', () => { ... });
|
|
*/
|
|
api.trigger('discoInitialized');
|
|
}
|
|
|
|
export function initStreamFeatures () {
|
|
// 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}`;
|
|
api.promises.add('streamFeaturesAdded');
|
|
_converse.stream_features = new Collection();
|
|
_converse.stream_features.browserStorage = _converse.createStore(id, "session");
|
|
}
|
|
}
|
|
|
|
export 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', () => { ... });
|
|
*/
|
|
api.trigger('streamFeaturesAdded');
|
|
}
|
|
|
|
export 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();
|
|
}
|