|
@@ -86,6 +86,7 @@ const CORE_PLUGINS = [
|
|
|
'converse-roster',
|
|
|
'converse-rsm',
|
|
|
'converse-smacks',
|
|
|
+ 'converse-status',
|
|
|
'converse-vcard'
|
|
|
];
|
|
|
|
|
@@ -560,11 +561,6 @@ function clearSession () {
|
|
|
_converse.session.browserStorage._clear();
|
|
|
delete _converse.session;
|
|
|
}
|
|
|
- if (_converse.shouldClearCache() && _converse.xmppstatus) {
|
|
|
- _converse.xmppstatus.destroy();
|
|
|
- _converse.xmppstatus.browserStorage._clear();
|
|
|
- delete _converse.xmppstatus;
|
|
|
- }
|
|
|
/**
|
|
|
* Triggered once the user session has been cleared,
|
|
|
* for example when the user has logged out or when Converse has
|
|
@@ -739,6 +735,33 @@ _converse.setUserJID = async function (jid) {
|
|
|
}
|
|
|
|
|
|
|
|
|
+function enableCarbons () {
|
|
|
+ /* Ask the XMPP server to enable Message Carbons
|
|
|
+ * See XEP-0280 https://xmpp.org/extensions/xep-0280.html#enabling
|
|
|
+ */
|
|
|
+ if (!_converse.message_carbons || !_converse.session || _converse.session.get('carbons_enabled')) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const carbons_iq = new Strophe.Builder('iq', {
|
|
|
+ 'from': _converse.connection.jid,
|
|
|
+ 'id': 'enablecarbons',
|
|
|
+ 'type': 'set'
|
|
|
+ })
|
|
|
+ .c('enable', {xmlns: Strophe.NS.CARBONS});
|
|
|
+ _converse.connection.addHandler((iq) => {
|
|
|
+ if (iq.querySelectorAll('error').length > 0) {
|
|
|
+ _converse.log(
|
|
|
+ 'An error occurred while trying to enable message carbons.',
|
|
|
+ Strophe.LogLevel.WARN);
|
|
|
+ } else {
|
|
|
+ _converse.session.save({'carbons_enabled': true});
|
|
|
+ _converse.log('Message carbons have been enabled.');
|
|
|
+ }
|
|
|
+ }, null, "iq", null, "enablecarbons");
|
|
|
+ _converse.connection.send(carbons_iq);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
async function onConnected (reconnecting) {
|
|
|
/* Called as soon as a new connection has been established, either
|
|
|
* by logging in or by attaching to an existing BOSH session.
|
|
@@ -751,9 +774,33 @@ async function onConnected (reconnecting) {
|
|
|
* user's JID resource for this session.
|
|
|
* @event _converse#afterResourceBinding
|
|
|
*/
|
|
|
- await _converse.api.trigger('afterResourceBinding', {'synchronous': true});
|
|
|
- _converse.enableCarbons();
|
|
|
- _converse.initStatus(reconnecting)
|
|
|
+ await _converse.api.trigger('afterResourceBinding', reconnecting, {'synchronous': true});
|
|
|
+ enableCarbons();
|
|
|
+
|
|
|
+ if (reconnecting) {
|
|
|
+ /**
|
|
|
+ * After the connection has dropped and converse.js has reconnected.
|
|
|
+ * Any Strophe stanza handlers (as registered via `converse.listen.stanza`) will
|
|
|
+ * have to be registered anew.
|
|
|
+ * @event _converse#reconnected
|
|
|
+ * @example _converse.api.listen.on('reconnected', () => { ... });
|
|
|
+ */
|
|
|
+ _converse.api.trigger('reconnected');
|
|
|
+ } else {
|
|
|
+ /**
|
|
|
+ * Triggered once converse.js has been initialized.
|
|
|
+ * See also {@link _converse#event:pluginsInitialized}.
|
|
|
+ * @event _converse#initialized
|
|
|
+ */
|
|
|
+ _converse.api.trigger('initialized');
|
|
|
+ /**
|
|
|
+ * Triggered after the connection has been established and Converse
|
|
|
+ * has got all its ducks in a row.
|
|
|
+ * @event _converse#initialized
|
|
|
+ */
|
|
|
+ _converse.api.trigger('connected');
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
|
|
@@ -895,7 +942,6 @@ _converse.initialize = async function (settings, callback) {
|
|
|
cleanup();
|
|
|
|
|
|
settings = settings !== undefined ? settings : {};
|
|
|
- const init_promise = u.getResolveablePromise();
|
|
|
PROMISES.forEach(addPromise);
|
|
|
|
|
|
if ('onpagehide' in window) {
|
|
@@ -955,7 +1001,6 @@ _converse.initialize = async function (settings, callback) {
|
|
|
* https://github.com/jcbrand/converse.js/issues/521
|
|
|
*/
|
|
|
this.send_initial_presence = true;
|
|
|
- this.msg_counter = 0;
|
|
|
this.user_settings = settings; // Save the user settings so that they can be used by plugins
|
|
|
|
|
|
// Module-level functions
|
|
@@ -963,107 +1008,6 @@ _converse.initialize = async function (settings, callback) {
|
|
|
|
|
|
this.generateResource = () => `/converse.js-${Math.floor(Math.random()*139749528).toString()}`;
|
|
|
|
|
|
- /**
|
|
|
- * Send out a Client State Indication (XEP-0352)
|
|
|
- * @private
|
|
|
- * @method sendCSI
|
|
|
- * @memberOf _converse
|
|
|
- * @param { String } stat - The user's chat status
|
|
|
- */
|
|
|
- this.sendCSI = function (stat) {
|
|
|
- _converse.api.send($build(stat, {xmlns: Strophe.NS.CSI}));
|
|
|
- _converse.inactive = (stat === _converse.INACTIVE) ? true : false;
|
|
|
- };
|
|
|
-
|
|
|
- this.onUserActivity = function () {
|
|
|
- /* Resets counters and flags relating to CSI and auto_away/auto_xa */
|
|
|
- if (_converse.idle_seconds > 0) {
|
|
|
- _converse.idle_seconds = 0;
|
|
|
- }
|
|
|
- if (!_.get(_converse.connection, 'authenticated')) {
|
|
|
- // We can't send out any stanzas when there's no authenticated connection.
|
|
|
- // This can happen when the connection reconnects.
|
|
|
- return;
|
|
|
- }
|
|
|
- if (_converse.inactive) {
|
|
|
- _converse.sendCSI(_converse.ACTIVE);
|
|
|
- }
|
|
|
- if (_converse.idle) {
|
|
|
- _converse.idle = false;
|
|
|
- _converse.xmppstatus.sendPresence();
|
|
|
- }
|
|
|
- if (_converse.auto_changed_status === true) {
|
|
|
- _converse.auto_changed_status = false;
|
|
|
- // XXX: we should really remember the original state here, and
|
|
|
- // then set it back to that...
|
|
|
- _converse.xmppstatus.set('status', _converse.default_state);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- this.onEverySecond = function () {
|
|
|
- /* An interval handler running every second.
|
|
|
- * Used for CSI and the auto_away and auto_xa features.
|
|
|
- */
|
|
|
- if (!_.get(_converse.connection, 'authenticated')) {
|
|
|
- // We can't send out any stanzas when there's no authenticated connection.
|
|
|
- // This can happen when the connection reconnects.
|
|
|
- return;
|
|
|
- }
|
|
|
- const stat = _converse.xmppstatus.get('status');
|
|
|
- _converse.idle_seconds++;
|
|
|
- if (_converse.csi_waiting_time > 0 &&
|
|
|
- _converse.idle_seconds > _converse.csi_waiting_time &&
|
|
|
- !_converse.inactive) {
|
|
|
- _converse.sendCSI(_converse.INACTIVE);
|
|
|
- }
|
|
|
- if (_converse.idle_presence_timeout > 0 &&
|
|
|
- _converse.idle_seconds > _converse.idle_presence_timeout &&
|
|
|
- !_converse.idle) {
|
|
|
- _converse.idle = true;
|
|
|
- _converse.xmppstatus.sendPresence();
|
|
|
- }
|
|
|
- if (_converse.auto_away > 0 &&
|
|
|
- _converse.idle_seconds > _converse.auto_away &&
|
|
|
- stat !== 'away' && stat !== 'xa' && stat !== 'dnd') {
|
|
|
- _converse.auto_changed_status = true;
|
|
|
- _converse.xmppstatus.set('status', 'away');
|
|
|
- } else if (_converse.auto_xa > 0 &&
|
|
|
- _converse.idle_seconds > _converse.auto_xa &&
|
|
|
- stat !== 'xa' && stat !== 'dnd') {
|
|
|
- _converse.auto_changed_status = true;
|
|
|
- _converse.xmppstatus.set('status', 'xa');
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- this.registerIntervalHandler = function () {
|
|
|
- /* Set an interval of one second and register a handler for it.
|
|
|
- * Required for the auto_away, auto_xa and csi_waiting_time features.
|
|
|
- */
|
|
|
- if (
|
|
|
- _converse.auto_away < 1 &&
|
|
|
- _converse.auto_xa < 1 &&
|
|
|
- _converse.csi_waiting_time < 1 &&
|
|
|
- _converse.idle_presence_timeout < 1
|
|
|
- ) {
|
|
|
- // Waiting time of less then one second means features aren't used.
|
|
|
- return;
|
|
|
- }
|
|
|
- _converse.idle_seconds = 0;
|
|
|
- _converse.auto_changed_status = false; // Was the user's status changed by Converse?
|
|
|
- window.addEventListener('click', _converse.onUserActivity);
|
|
|
- window.addEventListener('focus', _converse.onUserActivity);
|
|
|
- window.addEventListener('keypress', _converse.onUserActivity);
|
|
|
- window.addEventListener('mousemove', _converse.onUserActivity);
|
|
|
- const options = {'once': true, 'passive': true};
|
|
|
- window.addEventListener(_converse.unloadevent, _converse.onUserActivity, options);
|
|
|
- window.addEventListener(_converse.unloadevent, () => {
|
|
|
- if (_converse.session) {
|
|
|
- _converse.session.save('active', false);
|
|
|
- }
|
|
|
- });
|
|
|
- _converse.everySecondTrigger = window.setInterval(_converse.onEverySecond, 1000);
|
|
|
- };
|
|
|
-
|
|
|
this.setConnectionStatus = function (connection_status, message) {
|
|
|
_converse.connfeedback.set({
|
|
|
'connection_status': connection_status,
|
|
@@ -1071,21 +1015,6 @@ _converse.initialize = async function (settings, callback) {
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- /**
|
|
|
- * Reject or cancel another user's subscription to our presence updates.
|
|
|
- * @method rejectPresenceSubscription
|
|
|
- * @private
|
|
|
- * @memberOf _converse
|
|
|
- * @param { String } jid - The Jabber ID of the user whose subscription is being canceled
|
|
|
- * @param { String } message - An optional message to the user
|
|
|
- */
|
|
|
- this.rejectPresenceSubscription = function (jid, message) {
|
|
|
- const pres = $pres({to: jid, type: "unsubscribed"});
|
|
|
- if (message && message !== "") { pres.c("status").t(message); }
|
|
|
- _converse.api.send(pres);
|
|
|
- };
|
|
|
-
|
|
|
-
|
|
|
/**
|
|
|
* Gets called once strophe's status reaches Strophe.Status.DISCONNECTED.
|
|
|
* Will either start a teardown process for converse.js or attempt
|
|
@@ -1134,11 +1063,15 @@ _converse.initialize = async function (settings, callback) {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+ /**
|
|
|
+ * Callback method called by Strophe as the Strophe.Connection goes
|
|
|
+ * through various states while establishing or tearing down a
|
|
|
+ * connection.
|
|
|
+ * @method _converse#onConnectStatusChanged
|
|
|
+ * @private
|
|
|
+ * @memberOf _converse
|
|
|
+ */
|
|
|
this.onConnectStatusChanged = function (status, message) {
|
|
|
- /* Callback method called by Strophe as the Strophe.Connection goes
|
|
|
- * through various states while establishing or tearing down a
|
|
|
- * connection.
|
|
|
- */
|
|
|
_converse.log(`Status changed to: ${_converse.CONNECTION_STATUS[status]}`);
|
|
|
if (status === Strophe.Status.CONNECTED || status === Strophe.Status.ATTACHED) {
|
|
|
_converse.setConnectionStatus(status);
|
|
@@ -1193,49 +1126,6 @@ _converse.initialize = async function (settings, callback) {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- this.incrementMsgCounter = function () {
|
|
|
- this.msg_counter += 1;
|
|
|
- const unreadMsgCount = this.msg_counter;
|
|
|
- let title = document.title;
|
|
|
- if (!title) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (title.search(/^Messages \(\d+\) /) === -1) {
|
|
|
- title = `Messages (${unreadMsgCount}) ${title}`;
|
|
|
- } else {
|
|
|
- title = title.replace(/^Messages \(\d+\) /, `Messages (${unreadMsgCount})`);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- this.clearMsgCounter = function () {
|
|
|
- this.msg_counter = 0;
|
|
|
- let title = document.title;
|
|
|
- if (!title) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (title.search(/^Messages \(\d+\) /) !== -1) {
|
|
|
- title = title.replace(/^Messages \(\d+\) /, "");
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- this.initStatus = (reconnecting) => {
|
|
|
- // If there's no xmppstatus obj, then we were never connected to
|
|
|
- // begin with, so we set reconnecting to false.
|
|
|
- reconnecting = _converse.xmppstatus === undefined ? false : reconnecting;
|
|
|
- if (reconnecting) {
|
|
|
- _converse.onStatusInitialized(reconnecting);
|
|
|
- } else {
|
|
|
- const id = `converse.xmppstatus-${_converse.bare_jid}`;
|
|
|
- _converse.xmppstatus = new this.XMPPStatus({'id': id});
|
|
|
- _converse.xmppstatus.browserStorage = _converse.createStore(id, "session");
|
|
|
- _converse.xmppstatus.fetch({
|
|
|
- 'success': () => _converse.onStatusInitialized(reconnecting),
|
|
|
- 'error': () => _converse.onStatusInitialized(reconnecting),
|
|
|
- 'silent': true
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
this.saveWindowState = function (ev) {
|
|
|
// XXX: eventually we should be able to just use
|
|
|
// document.visibilityState (when we drop support for older
|
|
@@ -1255,9 +1145,6 @@ _converse.initialize = async function (settings, callback) {
|
|
|
} else {
|
|
|
state = document.hidden ? "hidden" : "visible";
|
|
|
}
|
|
|
- if (state === 'visible') {
|
|
|
- _converse.clearMsgCounter();
|
|
|
- }
|
|
|
_converse.windowState = state;
|
|
|
/**
|
|
|
* Triggered when window state has changed.
|
|
@@ -1284,73 +1171,6 @@ _converse.initialize = async function (settings, callback) {
|
|
|
_converse.api.trigger('registeredGlobalEventHandlers');
|
|
|
};
|
|
|
|
|
|
- this.enableCarbons = function () {
|
|
|
- /* Ask the XMPP server to enable Message Carbons
|
|
|
- * See XEP-0280 https://xmpp.org/extensions/xep-0280.html#enabling
|
|
|
- */
|
|
|
- if (!this.message_carbons || !this.session || this.session.get('carbons_enabled')) {
|
|
|
- return;
|
|
|
- }
|
|
|
- const carbons_iq = new Strophe.Builder('iq', {
|
|
|
- 'from': this.connection.jid,
|
|
|
- 'id': 'enablecarbons',
|
|
|
- 'type': 'set'
|
|
|
- })
|
|
|
- .c('enable', {xmlns: Strophe.NS.CARBONS});
|
|
|
- this.connection.addHandler((iq) => {
|
|
|
- if (iq.querySelectorAll('error').length > 0) {
|
|
|
- _converse.log(
|
|
|
- 'An error occurred while trying to enable message carbons.',
|
|
|
- Strophe.LogLevel.WARN);
|
|
|
- } else {
|
|
|
- this.session.save({'carbons_enabled': true});
|
|
|
- _converse.log('Message carbons have been enabled.');
|
|
|
- }
|
|
|
- }, null, "iq", null, "enablecarbons");
|
|
|
- this.connection.send(carbons_iq);
|
|
|
- };
|
|
|
-
|
|
|
-
|
|
|
- this.sendInitialPresence = function () {
|
|
|
- if (_converse.send_initial_presence) {
|
|
|
- _converse.xmppstatus.sendPresence();
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- this.onStatusInitialized = function (reconnecting) {
|
|
|
- /**
|
|
|
- * Triggered when the user's own chat status has been initialized.
|
|
|
- * @event _converse#statusInitialized
|
|
|
- * @example _converse.api.listen.on('statusInitialized', status => { ... });
|
|
|
- * @example _converse.api.waitUntil('statusInitialized').then(() => { ... });
|
|
|
- */
|
|
|
- _converse.api.trigger('statusInitialized', reconnecting);
|
|
|
- if (reconnecting) {
|
|
|
- /**
|
|
|
- * After the connection has dropped and converse.js has reconnected.
|
|
|
- * Any Strophe stanza handlers (as registered via `converse.listen.stanza`) will
|
|
|
- * have to be registered anew.
|
|
|
- * @event _converse#reconnected
|
|
|
- * @example _converse.api.listen.on('reconnected', () => { ... });
|
|
|
- */
|
|
|
- _converse.api.trigger('reconnected');
|
|
|
- } else {
|
|
|
- init_promise.resolve();
|
|
|
- /**
|
|
|
- * Triggered once converse.js has been initialized.
|
|
|
- * See also {@link _converse#event:pluginsInitialized}.
|
|
|
- * @event _converse#initialized
|
|
|
- */
|
|
|
- _converse.api.trigger('initialized');
|
|
|
- /**
|
|
|
- * Triggered after the connection has been established and Converse
|
|
|
- * has got all its ducks in a row.
|
|
|
- * @event _converse#initialized
|
|
|
- */
|
|
|
- _converse.api.trigger('connected');
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
this.bindResource = async function () {
|
|
|
/**
|
|
|
* Synchronous event triggered before we send an IQ to bind the user's
|
|
@@ -1373,79 +1193,11 @@ _converse.initialize = async function (settings, callback) {
|
|
|
});
|
|
|
this.connfeedback = new this.ConnectionFeedback();
|
|
|
|
|
|
-
|
|
|
- this.XMPPStatus = Backbone.Model.extend({
|
|
|
- defaults: {
|
|
|
- "status": _converse.default_state
|
|
|
- },
|
|
|
-
|
|
|
- initialize () {
|
|
|
- this.on('change', item => {
|
|
|
- if (!_.isObject(item.changed)) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if ('status' in item.changed || 'status_message' in item.changed) {
|
|
|
- this.sendPresence(this.get('status'), this.get('status_message'));
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- getNickname () {
|
|
|
- return _converse.nickname;
|
|
|
- },
|
|
|
-
|
|
|
- getFullname () {
|
|
|
- // Gets overridden in converse-vcard
|
|
|
- return '';
|
|
|
- },
|
|
|
-
|
|
|
- constructPresence (type, status_message) {
|
|
|
- let presence;
|
|
|
- type = _.isString(type) ? type : (this.get('status') || _converse.default_state);
|
|
|
- status_message = _.isString(status_message) ? status_message : this.get('status_message');
|
|
|
- // Most of these presence types are actually not explicitly sent,
|
|
|
- // but I add all of them here for reference and future proofing.
|
|
|
- if ((type === 'unavailable') ||
|
|
|
- (type === 'probe') ||
|
|
|
- (type === 'error') ||
|
|
|
- (type === 'unsubscribe') ||
|
|
|
- (type === 'unsubscribed') ||
|
|
|
- (type === 'subscribe') ||
|
|
|
- (type === 'subscribed')) {
|
|
|
- presence = $pres({'type': type});
|
|
|
- } else if (type === 'offline') {
|
|
|
- presence = $pres({'type': 'unavailable'});
|
|
|
- } else if (type === 'online') {
|
|
|
- presence = $pres();
|
|
|
- } else {
|
|
|
- presence = $pres().c('show').t(type).up();
|
|
|
- }
|
|
|
- if (status_message) {
|
|
|
- presence.c('status').t(status_message).up();
|
|
|
- }
|
|
|
- presence.c('priority').t(
|
|
|
- _.isNaN(Number(_converse.priority)) ? 0 : _converse.priority
|
|
|
- ).up();
|
|
|
- if (_converse.idle) {
|
|
|
- const idle_since = new Date();
|
|
|
- idle_since.setSeconds(idle_since.getSeconds() - _converse.idle_seconds);
|
|
|
- presence.c('idle', {xmlns: Strophe.NS.IDLE, since: idle_since.toISOString()});
|
|
|
- }
|
|
|
- return presence;
|
|
|
- },
|
|
|
-
|
|
|
- sendPresence (type, status_message) {
|
|
|
- _converse.api.send(this.constructPresence(type, status_message));
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
// Initialization
|
|
|
// --------------
|
|
|
await finishInitialization();
|
|
|
if (_converse.isTestEnv()) {
|
|
|
return _converse;
|
|
|
- } else {
|
|
|
- return init_promise;
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -1671,70 +1423,6 @@ _converse.api = {
|
|
|
return promise;
|
|
|
},
|
|
|
|
|
|
- /**
|
|
|
- * Set and get the user's chat status, also called their *availability*.
|
|
|
- *
|
|
|
- * @namespace _converse.api.user.status
|
|
|
- * @memberOf _converse.api.user
|
|
|
- */
|
|
|
- status: {
|
|
|
- /** Return the current user's availability status.
|
|
|
- *
|
|
|
- * @method _converse.api.user.status.get
|
|
|
- * @example _converse.api.user.status.get();
|
|
|
- */
|
|
|
- get () {
|
|
|
- return _converse.xmppstatus.get('status');
|
|
|
- },
|
|
|
- /**
|
|
|
- * The user's status can be set to one of the following values:
|
|
|
- *
|
|
|
- * @method _converse.api.user.status.set
|
|
|
- * @param {string} value The user's chat status (e.g. 'away', 'dnd', 'offline', 'online', 'unavailable' or 'xa')
|
|
|
- * @param {string} [message] A custom status message
|
|
|
- *
|
|
|
- * @example this._converse.api.user.status.set('dnd');
|
|
|
- * @example this._converse.api.user.status.set('dnd', 'In a meeting');
|
|
|
- */
|
|
|
- set (value, message) {
|
|
|
- const data = {'status': value};
|
|
|
- if (!_.includes(Object.keys(_converse.STATUS_WEIGHTS), value)) {
|
|
|
- throw new Error(
|
|
|
- 'Invalid availability value. See https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.2.1'
|
|
|
- );
|
|
|
- }
|
|
|
- if (_.isString(message)) {
|
|
|
- data.status_message = message;
|
|
|
- }
|
|
|
- _converse.xmppstatus.sendPresence(value);
|
|
|
- _converse.xmppstatus.save(data);
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * Set and retrieve the user's custom status message.
|
|
|
- *
|
|
|
- * @namespace _converse.api.user.status.message
|
|
|
- * @memberOf _converse.api.user.status
|
|
|
- */
|
|
|
- message: {
|
|
|
- /**
|
|
|
- * @method _converse.api.user.status.message.get
|
|
|
- * @returns {string} The status message
|
|
|
- * @example const message = _converse.api.user.status.message.get()
|
|
|
- */
|
|
|
- get () {
|
|
|
- return _converse.xmppstatus.get('status_message');
|
|
|
- },
|
|
|
- /**
|
|
|
- * @method _converse.api.user.status.message.set
|
|
|
- * @param {string} status The status message
|
|
|
- * @example _converse.api.user.status.message.set('In a meeting');
|
|
|
- */
|
|
|
- set (status) {
|
|
|
- _converse.xmppstatus.save({ status_message: status });
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
},
|
|
|
|
|
|
/**
|