Add an external API for sending presences
This commit is contained in:
parent
edf7f6b8d3
commit
c1efb0d2b4
@ -140,8 +140,9 @@
|
||||
const view = _converse.xmppstatusview;
|
||||
modal.el.querySelector('label[for="radio-busy"]').click(); // Change status to "dnd"
|
||||
modal.el.querySelector('[type="submit"]').click();
|
||||
const last_stanza = _converse.connection.sent_stanzas.pop();
|
||||
expect(Strophe.serialize(last_stanza)).toBe(
|
||||
const sent_stanzas = _converse.connection.sent_stanzas;
|
||||
const sent_presence = await u.waitUntil(() => sent_stanzas.filter(s => Strophe.serialize(s).match('presence')).pop());
|
||||
expect(Strophe.serialize(sent_presence)).toBe(
|
||||
`<presence xmlns="jabber:client">`+
|
||||
`<show>dnd</show>`+
|
||||
`<priority>0</priority>`+
|
||||
@ -169,8 +170,9 @@
|
||||
const msg = 'I am happy';
|
||||
modal.el.querySelector('input[name="status_message"]').value = msg;
|
||||
modal.el.querySelector('[type="submit"]').click();
|
||||
const last_stanza = _converse.connection.sent_stanzas.pop();
|
||||
expect(Strophe.serialize(last_stanza)).toBe(
|
||||
const sent_stanzas = _converse.connection.sent_stanzas;
|
||||
const sent_presence = await u.waitUntil(() => sent_stanzas.filter(s => Strophe.serialize(s).match('presence')).pop());
|
||||
expect(Strophe.serialize(sent_presence)).toBe(
|
||||
`<presence xmlns="jabber:client">`+
|
||||
`<status>I am happy</status>`+
|
||||
`<priority>0</priority>`+
|
||||
|
@ -8,6 +8,7 @@
|
||||
], factory);
|
||||
} (this, function (jasmine, mock, test_utils) {
|
||||
"use strict";
|
||||
const Strophe = converse.env.Strophe;
|
||||
const u = converse.env.utils;
|
||||
// See: https://xmpp.org/rfcs/rfc3921.html
|
||||
|
||||
@ -37,7 +38,7 @@
|
||||
}));
|
||||
|
||||
it("has a given priority", mock.initConverse((done, _converse) => {
|
||||
let pres = _converse.xmppstatus.constructPresence('online', 'Hello world');
|
||||
let pres = _converse.xmppstatus.constructPresence('online', null, 'Hello world');
|
||||
expect(pres.toLocaleString()).toBe(
|
||||
`<presence xmlns="jabber:client">`+
|
||||
`<status>Hello world</status>`+
|
||||
@ -46,7 +47,7 @@
|
||||
`</presence>`
|
||||
);
|
||||
_converse.priority = 2;
|
||||
pres = _converse.xmppstatus.constructPresence('away', 'Going jogging');
|
||||
pres = _converse.xmppstatus.constructPresence('away', null, 'Going jogging');
|
||||
expect(pres.toLocaleString()).toBe(
|
||||
`<presence xmlns="jabber:client">`+
|
||||
`<show>away</show>`+
|
||||
@ -57,7 +58,7 @@
|
||||
);
|
||||
|
||||
delete _converse.priority;
|
||||
pres = _converse.xmppstatus.constructPresence('dnd', 'Doing taxes');
|
||||
pres = _converse.xmppstatus.constructPresence('dnd', null, 'Doing taxes');
|
||||
expect(pres.toLocaleString()).toBe(
|
||||
`<presence xmlns="jabber:client">`+
|
||||
`<show>dnd</show>`+
|
||||
@ -75,8 +76,6 @@
|
||||
async (done, _converse) => {
|
||||
|
||||
test_utils.openControlBox(_converse);
|
||||
const view = _converse.xmppstatusview;
|
||||
spyOn(view.model, 'sendPresence').and.callThrough();
|
||||
spyOn(_converse.connection, 'send').and.callThrough();
|
||||
|
||||
const cbview = _converse.chatboxviews.get('controlbox');
|
||||
@ -86,8 +85,10 @@
|
||||
const msg = 'My custom status';
|
||||
modal.el.querySelector('input[name="status_message"]').value = msg;
|
||||
modal.el.querySelector('[type="submit"]').click();
|
||||
expect(view.model.sendPresence).toHaveBeenCalled();
|
||||
expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())
|
||||
|
||||
const sent_stanzas = _converse.connection.sent_stanzas;
|
||||
let sent_presence = await u.waitUntil(() => sent_stanzas.filter(s => Strophe.serialize(s).match('presence')).pop());
|
||||
expect(Strophe.serialize(sent_presence))
|
||||
.toBe(`<presence xmlns="jabber:client">`+
|
||||
`<status>My custom status</status>`+
|
||||
`<priority>0</priority>`+
|
||||
@ -100,10 +101,16 @@
|
||||
await u.waitUntil(() => modal.el.getAttribute('aria-hidden') === "false", 1000);
|
||||
modal.el.querySelector('label[for="radio-busy"]').click(); // Change status to "dnd"
|
||||
modal.el.querySelector('[type="submit"]').click();
|
||||
expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())
|
||||
.toBe(`<presence xmlns="jabber:client"><show>dnd</show><status>My custom status</status><priority>0</priority>`+
|
||||
await u.waitUntil(() => sent_stanzas.filter(s => Strophe.serialize(s).match('presence')).length === 2);
|
||||
sent_presence = sent_stanzas.filter(s => Strophe.serialize(s).match('presence')).pop();
|
||||
expect(Strophe.serialize(sent_presence))
|
||||
.toBe(
|
||||
`<presence xmlns="jabber:client">`+
|
||||
`<show>dnd</show>`+
|
||||
`<status>My custom status</status>`+
|
||||
`<priority>0</priority>`+
|
||||
`<c hash="sha-1" node="https://conversejs.org" ver="Hxbsr5fazs62i+O0GxIXf2OEDNs=" xmlns="http://jabber.org/protocol/caps"/>`+
|
||||
`</presence>`)
|
||||
`</presence>`)
|
||||
done();
|
||||
}));
|
||||
});
|
||||
|
@ -1,14 +1,16 @@
|
||||
(function (root, factory) {
|
||||
define(["jasmine", "mock"], factory);
|
||||
} (this, function (jasmine, mock) {
|
||||
const u = converse.env.utils;
|
||||
|
||||
return describe("The XMPPStatus model", function () {
|
||||
|
||||
it("won't send <show>online</show> when setting a custom status message", mock.initConverse((done, _converse) => {
|
||||
it("won't send <show>online</show> when setting a custom status message",
|
||||
mock.initConverse(async (done, _converse) => {
|
||||
_converse.xmppstatus.save({'status': 'online'});
|
||||
spyOn(_converse.connection, 'send');
|
||||
_converse.api.user.status.message.set("I'm also happy!");
|
||||
expect(_converse.connection.send).toHaveBeenCalled();
|
||||
await u.waitUntil(() => _converse.connection.send.calls.count());
|
||||
const stanza = _converse.connection.send.calls.argsFor(0)[0].tree();
|
||||
expect(stanza.childNodes.length).toBe(3);
|
||||
expect(stanza.querySelectorAll('status').length).toBe(1);
|
||||
|
@ -834,7 +834,7 @@ converse.plugins.add('converse-rosterview', {
|
||||
u.addClass('fa-spin', ev.target);
|
||||
_converse.roster.data.save('version', null);
|
||||
await _converse.roster.fetchFromServer();
|
||||
_converse.xmppstatus.sendPresence();
|
||||
api.user.presence.send();
|
||||
u.removeClass('fa-spin', ev.target);
|
||||
},
|
||||
|
||||
|
@ -90,7 +90,6 @@ const PROMISES = [
|
||||
'connectionInitialized',
|
||||
'initialized',
|
||||
'pluginsInitialized',
|
||||
'statusInitialized'
|
||||
];
|
||||
|
||||
// Core plugins are whitelisted automatically
|
||||
@ -712,7 +711,6 @@ export const api = _converse.api = {
|
||||
* * [rosterContactsFetched](/docs/html/events.html#rosterContactsFetched)
|
||||
* * [rosterGroupsFetched](/docs/html/events.html#rosterGroupsFetched)
|
||||
* * [rosterInitialized](/docs/html/events.html#rosterInitialized)
|
||||
* * [statusInitialized](/docs/html/events.html#statusInitialized)
|
||||
* * [roomsPanelRendered](/docs/html/events.html#roomsPanelRendered)
|
||||
*
|
||||
* The various plugins might also provide promises, and they do this by using the
|
||||
|
@ -852,7 +852,7 @@ converse.plugins.add('converse-muc', {
|
||||
}
|
||||
}
|
||||
if (api.connection.connected()) {
|
||||
this.sendUnavailablePresence(exit_msg);
|
||||
api.user.presence.send('unavailable', this.getRoomJIDAndNick(), exit_msg);
|
||||
}
|
||||
u.safeSave(this.session, {'connection_status': converse.ROOMSTATUS.DISCONNECTED});
|
||||
this.removeHandlers();
|
||||
@ -877,18 +877,6 @@ converse.plugins.add('converse-muc', {
|
||||
return self && self.isModerator() && api.disco.supports(Strophe.NS.MODERATE, this.get('jid'));
|
||||
},
|
||||
|
||||
sendUnavailablePresence (exit_msg) {
|
||||
const presence = $pres({
|
||||
type: "unavailable",
|
||||
from: _converse.connection.jid,
|
||||
to: this.getRoomJIDAndNick()
|
||||
});
|
||||
if (exit_msg !== null) {
|
||||
presence.c("status", exit_msg);
|
||||
}
|
||||
_converse.connection.sendPresence(presence);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return an array of unique nicknames based on all occupants and messages in this MUC.
|
||||
* @private
|
||||
|
@ -80,7 +80,7 @@ converse.plugins.add('converse-roster', {
|
||||
|
||||
_converse.sendInitialPresence = function () {
|
||||
if (_converse.send_initial_presence) {
|
||||
_converse.xmppstatus.sendPresence();
|
||||
api.user.presence.send();
|
||||
}
|
||||
};
|
||||
|
||||
@ -771,7 +771,7 @@ converse.plugins.add('converse-roster', {
|
||||
//
|
||||
// As a workaround for now we simply send our presence again,
|
||||
// otherwise we're treated as offline.
|
||||
_converse.xmppstatus.sendPresence();
|
||||
api.user.presence.send();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -23,6 +23,7 @@ converse.plugins.add('converse-status', {
|
||||
default_state: 'online',
|
||||
priority: 0,
|
||||
});
|
||||
api.promises.add(['statusInitialized']);
|
||||
|
||||
_converse.XMPPStatus = Model.extend({
|
||||
defaults () {
|
||||
@ -35,7 +36,7 @@ converse.plugins.add('converse-status', {
|
||||
return;
|
||||
}
|
||||
if ('status' in item.changed || 'status_message' in item.changed) {
|
||||
this.sendPresence(this.get('status'), this.get('status_message'));
|
||||
api.user.presence.send(this.get('status'), null, this.get('status_message'));
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -49,12 +50,11 @@ converse.plugins.add('converse-status', {
|
||||
return '';
|
||||
},
|
||||
|
||||
constructPresence (type, status_message) {
|
||||
let presence;
|
||||
constructPresence (type, to=null, status_message) {
|
||||
type = isString(type) ? type : (this.get('status') || api.settings.get("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.
|
||||
let presence;
|
||||
const attrs = {to};
|
||||
if ((type === 'unavailable') ||
|
||||
(type === 'probe') ||
|
||||
(type === 'error') ||
|
||||
@ -62,14 +62,17 @@ converse.plugins.add('converse-status', {
|
||||
(type === 'unsubscribed') ||
|
||||
(type === 'subscribe') ||
|
||||
(type === 'subscribed')) {
|
||||
presence = $pres({'type': type});
|
||||
attrs['type'] = type;
|
||||
presence = $pres(attrs);
|
||||
} else if (type === 'offline') {
|
||||
presence = $pres({'type': 'unavailable'});
|
||||
attrs['type'] = 'unavailable';
|
||||
presence = $pres(attrs);
|
||||
} else if (type === 'online') {
|
||||
presence = $pres();
|
||||
presence = $pres(attrs);
|
||||
} else {
|
||||
presence = $pres().c('show').t(type).up();
|
||||
presence = $pres(attrs).c('show').t(type).up();
|
||||
}
|
||||
|
||||
if (status_message) {
|
||||
presence.c('status').t(status_message).up();
|
||||
}
|
||||
@ -82,10 +85,6 @@ converse.plugins.add('converse-status', {
|
||||
presence.c('idle', {xmlns: Strophe.NS.IDLE, since: idle_since.toISOString()});
|
||||
}
|
||||
return presence;
|
||||
},
|
||||
|
||||
sendPresence (type, status_message) {
|
||||
api.send(this.constructPresence(type, status_message));
|
||||
}
|
||||
});
|
||||
|
||||
@ -118,7 +117,7 @@ converse.plugins.add('converse-status', {
|
||||
}
|
||||
if (_converse.idle) {
|
||||
_converse.idle = false;
|
||||
_converse.xmppstatus.sendPresence();
|
||||
api.user.presence.send();
|
||||
}
|
||||
if (_converse.auto_changed_status === true) {
|
||||
_converse.auto_changed_status = false;
|
||||
@ -148,7 +147,7 @@ converse.plugins.add('converse-status', {
|
||||
_converse.idle_seconds > api.settings.get("idle_presence_timeout") &&
|
||||
!_converse.idle) {
|
||||
_converse.idle = true;
|
||||
_converse.xmppstatus.sendPresence();
|
||||
api.user.presence.send();
|
||||
}
|
||||
if (api.settings.get("auto_away") > 0 &&
|
||||
_converse.idle_seconds > api.settings.get("auto_away") &&
|
||||
@ -245,21 +244,39 @@ converse.plugins.add('converse-status', {
|
||||
|
||||
/************************ BEGIN API ************************/
|
||||
Object.assign(_converse.api.user, {
|
||||
/**
|
||||
* @namespace _converse.api.user.presence
|
||||
* @memberOf _converse.api.user
|
||||
*/
|
||||
presence: {
|
||||
/**
|
||||
* Send out a presence stanza
|
||||
* @method _converse.api.user.presence.send
|
||||
* @param { String } type
|
||||
* @param { String } to
|
||||
* @param { String } [status] - An optional status message
|
||||
*/
|
||||
async send (type, to, status) {
|
||||
await api.waitUntil('statusInitialized');
|
||||
api.send(_converse.xmppstatus.constructPresence(type, to, status));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
/**
|
||||
* 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:
|
||||
*
|
||||
@ -267,8 +284,8 @@ converse.plugins.add('converse-status', {
|
||||
* @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');
|
||||
* @example _converse.api.user.status.set('dnd');
|
||||
* @example _converse.api.user.status.set('dnd', 'In a meeting');
|
||||
*/
|
||||
set (value, message) {
|
||||
const data = {'status': value};
|
||||
@ -280,7 +297,6 @@ converse.plugins.add('converse-status', {
|
||||
if (isString(message)) {
|
||||
data.status_message = message;
|
||||
}
|
||||
_converse.xmppstatus.sendPresence(value);
|
||||
_converse.xmppstatus.save(data);
|
||||
},
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user