MUC: Add support for status code 333
This commit is contained in:
parent
945d7e9891
commit
1419b4fc96
51
spec/muc.js
51
spec/muc.js
@ -2778,6 +2778,57 @@ describe("Groupchats", function () {
|
||||
done();
|
||||
}));
|
||||
|
||||
it("informs users if they have exited the groupchat due to a technical reason",
|
||||
mock.initConverse(
|
||||
['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
|
||||
/* <presence
|
||||
* from='harfleur@chat.shakespeare.lit/pistol'
|
||||
* to='pistol@shakespeare.lit/harfleur'
|
||||
* type='unavailable'>
|
||||
* <x xmlns='http://jabber.org/protocol/muc#user'>
|
||||
* <item affiliation='none' role='none'>
|
||||
* <actor nick='Fluellen'/>
|
||||
* <reason>Avaunt, you cullion!</reason>
|
||||
* </item>
|
||||
* <status code='110'/>
|
||||
* <status code='307'/>
|
||||
* </x>
|
||||
* </presence>
|
||||
*/
|
||||
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
|
||||
var presence = $pres().attrs({
|
||||
from:'lounge@montague.lit/romeo',
|
||||
to:'romeo@montague.lit/pda',
|
||||
type:'unavailable'
|
||||
})
|
||||
.c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
|
||||
.c('item').attrs({
|
||||
affiliation: 'none',
|
||||
jid: 'romeo@montague.lit/pda',
|
||||
role: 'none'
|
||||
})
|
||||
.c('reason').t('Flux capacitor overload!').up()
|
||||
.up()
|
||||
.c('status').attrs({code:'110'}).up()
|
||||
.c('status').attrs({code:'333'}).up()
|
||||
.c('status').attrs({code:'307'}).nodeTree;
|
||||
|
||||
_converse.connection._dataRecv(mock.createRequest(presence));
|
||||
|
||||
const view = _converse.chatboxviews.get('lounge@montague.lit');
|
||||
expect(u.isVisible(view.el.querySelector('.chat-area'))).toBeFalsy();
|
||||
expect(u.isVisible(view.el.querySelector('.occupants'))).toBeFalsy();
|
||||
const chat_body = view.el.querySelector('.chatroom-body');
|
||||
expect(chat_body.querySelectorAll('.disconnect-msg').length).toBe(2);
|
||||
expect(chat_body.querySelector('.disconnect-msg:first-child').textContent.trim()).toBe(
|
||||
'You have exited this groupchat due to a technical problem');
|
||||
expect(chat_body.querySelector('.disconnect-msg:nth-child(2)').textContent.trim()).toBe(
|
||||
'The reason given is: "Flux capacitor overload!".');
|
||||
done();
|
||||
}));
|
||||
|
||||
|
||||
it("can be saved to, and retrieved from, browserStorage",
|
||||
mock.initConverse(
|
||||
|
@ -23,6 +23,8 @@ export const AFFILIATIONS = ['owner', 'admin', 'member', 'outcast', 'none'];
|
||||
converse.MUC_TRAFFIC_STATES = ['entered', 'exited'];
|
||||
converse.MUC_ROLE_CHANGES = ['op', 'deop', 'voice', 'mute'];
|
||||
|
||||
const ACTION_INFO_CODES = ['301', '303', '333', '307', '321', '322'];
|
||||
|
||||
const MUC_ROLE_WEIGHTS = {
|
||||
'moderator': 1,
|
||||
'participant': 2,
|
||||
@ -183,13 +185,13 @@ converse.plugins.add('converse-muc', {
|
||||
|
||||
disconnect_messages: {
|
||||
301: __('You have been banned from this groupchat'),
|
||||
333: __('You have exited this groupchat due to a technical problem'),
|
||||
307: __('You have been kicked from this groupchat'),
|
||||
321: __("You have been removed from this groupchat because of an affiliation change"),
|
||||
322: __("You have been removed from this groupchat because the groupchat has changed to members-only and you're not a member"),
|
||||
332: __("You have been removed from this groupchat because the service hosting it is being shut down")
|
||||
},
|
||||
|
||||
action_info_codes: ['301', '303', '307', '321', '322']
|
||||
}
|
||||
|
||||
|
||||
@ -2061,6 +2063,8 @@ converse.plugins.add('converse-muc', {
|
||||
return actor ? __("%1$s has been banned by %2$s", nick, actor) : __("%1$s has been banned", nick);
|
||||
} else if (code === '303') {
|
||||
return ___("%1$s\'s nickname has changed", nick);
|
||||
} else if (code === '333') {
|
||||
return ___("%1$s has exited the room due to a technical issue");
|
||||
} else if (code === '307') {
|
||||
return actor ? __("%1$s has been kicked out by %2$s", nick, actor) : __("%1$s has been kicked out", nick);
|
||||
} else if (code === '321') {
|
||||
@ -2147,6 +2151,52 @@ converse.plugins.add('converse-muc', {
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Create an info message based on a received MUC status code
|
||||
* @private
|
||||
* @method _converse.ChatRoom#createInfoMessage
|
||||
* @param { string } code - The MUC status code
|
||||
* @param { XMLElement } stanza - The original stanza that contains the code
|
||||
* @param { Boolean } is_self - Whether this stanza refers to our own presence
|
||||
*/
|
||||
createInfoMessage (code, stanza, is_self) {
|
||||
const data = { 'type': 'info', };
|
||||
|
||||
if (code === '110' || (code === '100' && !is_self)) {
|
||||
return;
|
||||
} else if (code in _converse.muc.info_messages) {
|
||||
data.message = _converse.muc.info_messages[code];
|
||||
} else if (!is_self && ACTION_INFO_CODES.includes(code)) {
|
||||
const nick = Strophe.getResourceFromJid(stanza.getAttribute('from'));
|
||||
const item = stanza.querySelector(`x[xmlns="${Strophe.NS.MUC_USER}"] item`);
|
||||
data.actor = item ? item.querySelector('actor')?.getAttribute('nick') : undefined;
|
||||
data.reason = item ? item.querySelector('reason')?.textContent : undefined;
|
||||
data.message = this.getActionInfoMessage(code, nick, data.actor);
|
||||
} else if (is_self && (code in _converse.muc.new_nickname_messages)) {
|
||||
let nick;
|
||||
if (is_self && code === "210") {
|
||||
nick = Strophe.getResourceFromJid(stanza.getAttribute('from'));
|
||||
} else if (is_self && code === "303") {
|
||||
nick = stanza.querySelector(`x[xmlns="${Strophe.NS.MUC_USER}"] item`).getAttribute('nick');
|
||||
}
|
||||
this.save('nick', nick);
|
||||
data.message = __(_converse.muc.new_nickname_messages[code], nick);
|
||||
}
|
||||
if (data.message) {
|
||||
if (code === "201" && this.messages.findWhere(data)) {
|
||||
return;
|
||||
} else if (code in _converse.muc.info_messages &&
|
||||
this.messages.length &&
|
||||
this.messages.pop().get('message') === data.message) {
|
||||
// XXX: very naive duplication checking
|
||||
return;
|
||||
}
|
||||
this.createMessage(data);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Create info messages based on a received presence or message stanza
|
||||
* @private
|
||||
@ -2154,47 +2204,13 @@ converse.plugins.add('converse-muc', {
|
||||
* @param { XMLElement } stanza
|
||||
*/
|
||||
createInfoMessages (stanza) {
|
||||
const is_self = stanza.querySelector("status[code='110']") !== null;
|
||||
const x = sizzle(`x[xmlns="${Strophe.NS.MUC_USER}"]`, stanza).pop();
|
||||
if (!x) {
|
||||
return;
|
||||
const codes = sizzle(`x[xmlns="${Strophe.NS.MUC_USER}"] status`, stanza).map(s => s.getAttribute('code'));
|
||||
if (codes.includes('333') && codes.includes('307')) {
|
||||
// See: https://github.com/xsf/xeps/pull/969/files#diff-ac5113766e59219806793c1f7d967f1bR4966
|
||||
codes.splice(codes.indexOf('307'), 1);
|
||||
}
|
||||
sizzle('status', x).map(s => s.getAttribute('code')).forEach(code => {
|
||||
const data = {
|
||||
'type': 'info',
|
||||
};
|
||||
if (code === '110' || (code === '100' && !is_self)) {
|
||||
return;
|
||||
} else if (code in _converse.muc.info_messages) {
|
||||
data.message = _converse.muc.info_messages[code];
|
||||
} else if (!is_self && _converse.muc.action_info_codes.includes(code)) {
|
||||
const nick = Strophe.getResourceFromJid(stanza.getAttribute('from'));
|
||||
const item = x.querySelector('item');
|
||||
data.actor = item ? invoke(item.querySelector('actor'), 'getAttribute', 'nick') : undefined;
|
||||
data.reason = item ? item.querySelector('reason')?.textContent : undefined;
|
||||
data.message = this.getActionInfoMessage(code, nick, data.actor);
|
||||
} else if (is_self && (code in _converse.muc.new_nickname_messages)) {
|
||||
let nick;
|
||||
if (is_self && code === "210") {
|
||||
nick = Strophe.getResourceFromJid(stanza.getAttribute('from'));
|
||||
} else if (is_self && code === "303") {
|
||||
nick = stanza.querySelector('x item').getAttribute('nick');
|
||||
}
|
||||
this.save('nick', nick);
|
||||
data.message = __(_converse.muc.new_nickname_messages[code], nick);
|
||||
}
|
||||
if (data.message) {
|
||||
if (code === "201" && this.messages.findWhere(data)) {
|
||||
return;
|
||||
} else if (code in _converse.muc.info_messages &&
|
||||
this.messages.length &&
|
||||
this.messages.pop().get('message') === data.message) {
|
||||
// XXX: very naive duplication checking
|
||||
return;
|
||||
}
|
||||
this.createMessage(data);
|
||||
}
|
||||
});
|
||||
const is_self = codes.includes('110');
|
||||
codes.forEach(code => this.createInfoMessage(code, stanza, is_self));
|
||||
},
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user