New config setting: muc_fetch_members
This commit is contained in:
parent
c5193be44b
commit
c4ad02d4e3
|
@ -21,6 +21,7 @@
|
||||||
- New config option [clear_messages_on_reconnection](https://conversejs.org/docs/html/configuration.html#clear-messages-on-reconnection)
|
- New config option [clear_messages_on_reconnection](https://conversejs.org/docs/html/configuration.html#clear-messages-on-reconnection)
|
||||||
- New config option [enable_smacks](https://conversejs.org/docs/html/configuration.html#enable-smacks)
|
- New config option [enable_smacks](https://conversejs.org/docs/html/configuration.html#enable-smacks)
|
||||||
- New config option [message_limit](https://conversejs.org/docs/html/configuration.html#message-limit)
|
- New config option [message_limit](https://conversejs.org/docs/html/configuration.html#message-limit)
|
||||||
|
- New config option [muc_fetch_members](https://conversejs.org/docs/html/configuration.html#muc-fetch-members)
|
||||||
- New config option [muc_mention_autocomplete_min_chars](https://conversejs.org/docs/html/configuration.html#muc-mention-autocomplete-min-chars)
|
- New config option [muc_mention_autocomplete_min_chars](https://conversejs.org/docs/html/configuration.html#muc-mention-autocomplete-min-chars)
|
||||||
- New config option [muc_show_join_leave_status](https://conversejs.org/docs/html/configuration.html#muc-show-join-leave-status)
|
- New config option [muc_show_join_leave_status](https://conversejs.org/docs/html/configuration.html#muc-show-join-leave-status)
|
||||||
- New config option [singleton](https://conversejs.org/docs/html/configuration.html#singleton)
|
- New config option [singleton](https://conversejs.org/docs/html/configuration.html#singleton)
|
||||||
|
|
|
@ -451,6 +451,7 @@ Example:
|
||||||
|
|
||||||
.. _`bosh-service-url`:
|
.. _`bosh-service-url`:
|
||||||
|
|
||||||
|
|
||||||
bosh_service_url
|
bosh_service_url
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
@ -954,6 +955,28 @@ other domains.
|
||||||
If you want to restrict MUCs to only this domain, then set `locked_domain`_ to
|
If you want to restrict MUCs to only this domain, then set `locked_domain`_ to
|
||||||
``true``.
|
``true``.
|
||||||
|
|
||||||
|
|
||||||
|
muc_fetch_members
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
* Default: ``true``
|
||||||
|
|
||||||
|
Determines whether Converse.js will fetch the member lists for a MUC
|
||||||
|
(multi-user chat) when the user first enters it.
|
||||||
|
|
||||||
|
Here's the relevant part from the MUC XEP: https://xmpp.org/extensions/xep-0045.html#getmemberlist
|
||||||
|
|
||||||
|
The MUC service won't necessarily allow any user to fetch member lists,
|
||||||
|
but can usually be configured to do so.
|
||||||
|
|
||||||
|
The member lists consists of three lists of users who have the affiliations
|
||||||
|
``member``, ``admin`` and ``owner`` respectively.
|
||||||
|
|
||||||
|
By fetching member lists, Converse.js will always show these users as
|
||||||
|
participants of the MUC, which makes it behave a bit more like modern chat
|
||||||
|
apps.
|
||||||
|
|
||||||
|
|
||||||
muc_history_max_stanzas
|
muc_history_max_stanzas
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
|
88
spec/muc.js
88
spec/muc.js
|
@ -400,13 +400,34 @@
|
||||||
|
|
||||||
describe("A Groupchat", function () {
|
describe("A Groupchat", function () {
|
||||||
|
|
||||||
|
|
||||||
|
describe("upon being entered", function () {
|
||||||
|
it("will fetch the member list if muc_fetch_members is true",
|
||||||
|
mock.initConverse(
|
||||||
|
null, ['rosterGroupsFetched'], {'muc_fetch_members': true},
|
||||||
|
async function (done, _converse) {
|
||||||
|
|
||||||
|
spyOn(_converse.ChatRoomOccupants.prototype, 'fetchMembers').and.callThrough();
|
||||||
|
await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
|
||||||
|
let view = _converse.chatboxviews.get('lounge@montague.lit');
|
||||||
|
expect(view.model.occupants.fetchMembers).toHaveBeenCalled();
|
||||||
|
|
||||||
|
_converse.muc_fetch_members = false;
|
||||||
|
await test_utils.openAndEnterChatRoom(_converse, 'orchard@montague.lit', 'romeo');
|
||||||
|
view = _converse.chatboxviews.get('orchard@montague.lit');
|
||||||
|
expect(view.model.occupants.fetchMembers.calls.count()).toBe(1);
|
||||||
|
done();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
it("clears cached messages when it gets closed",
|
it("clears cached messages when it gets closed",
|
||||||
mock.initConverse(
|
mock.initConverse(
|
||||||
null, ['rosterGroupsFetched'], {},
|
null, ['rosterGroupsFetched'], {},
|
||||||
async function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
|
||||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
|
const muc_jid = 'lounge@montague.lit';
|
||||||
const view = _converse.chatboxviews.get('lounge@montague.lit');
|
await test_utils.openAndEnterChatRoom(_converse, muc_jid , 'romeo');
|
||||||
|
const view = _converse.chatboxviews.get(muc_jid);
|
||||||
const message = 'Hello world',
|
const message = 'Hello world',
|
||||||
nick = mock.chatroom_names[0],
|
nick = mock.chatroom_names[0],
|
||||||
msg = $msg({
|
msg = $msg({
|
||||||
|
@ -4185,14 +4206,10 @@
|
||||||
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||||
async function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
|
||||||
var sent_IQs = [], IQ_ids = [];
|
spyOn(_converse.ChatRoomOccupants.prototype, 'fetchMembers').and.callThrough();
|
||||||
const sendIQ = _converse.connection.sendIQ;
|
const sendIQ = _converse.connection.sendIQ;
|
||||||
const IQ_stanzas = _converse.connection.IQ_stanzas;
|
const IQ_stanzas = _converse.connection.IQ_stanzas;
|
||||||
const muc_jid = 'coven@chat.shakespeare.lit';
|
const muc_jid = 'coven@chat.shakespeare.lit';
|
||||||
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
|
||||||
sent_IQs.push(iq);
|
|
||||||
IQ_ids.push(sendIQ.bind(this)(iq, callback, errback));
|
|
||||||
});
|
|
||||||
|
|
||||||
await _converse.api.rooms.open(muc_jid, {'nick': 'romeo'});
|
await _converse.api.rooms.open(muc_jid, {'nick': 'romeo'});
|
||||||
let stanza = await u.waitUntil(() => _.filter(
|
let stanza = await u.waitUntil(() => _.filter(
|
||||||
|
@ -4206,11 +4223,18 @@
|
||||||
`<query xmlns="http://jabber.org/protocol/disco#info"/>`+
|
`<query xmlns="http://jabber.org/protocol/disco#info"/>`+
|
||||||
`</iq>`);
|
`</iq>`);
|
||||||
|
|
||||||
const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
|
const sent_IQs = _converse.connection.IQ_stanzas;
|
||||||
|
const last_sent_IQ = sent_IQs.pop();
|
||||||
|
expect(Strophe.serialize(last_sent_IQ)).toBe(
|
||||||
|
`<iq from="romeo@montague.lit/orchard" id="${last_sent_IQ.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
|
||||||
|
`<query xmlns="http://jabber.org/protocol/disco#info"/>`+
|
||||||
|
`</iq>`);
|
||||||
|
|
||||||
|
const view = _converse.chatboxviews.get(muc_jid);
|
||||||
// State that the chat is members-only via the features IQ
|
// State that the chat is members-only via the features IQ
|
||||||
const features_stanza = $iq({
|
const features_stanza = $iq({
|
||||||
from: 'coven@chat.shakespeare.lit',
|
from: 'coven@chat.shakespeare.lit',
|
||||||
'id': IQ_ids.pop(),
|
'id': last_sent_IQ.getAttribute('id'),
|
||||||
'to': 'romeo@montague.lit/desktop',
|
'to': 'romeo@montague.lit/desktop',
|
||||||
'type': 'result'
|
'type': 'result'
|
||||||
})
|
})
|
||||||
|
@ -4244,24 +4268,23 @@
|
||||||
|
|
||||||
// Check in reverse order that we requested all three lists
|
// Check in reverse order that we requested all three lists
|
||||||
// (member, owner and admin).
|
// (member, owner and admin).
|
||||||
const admin_iq_id = IQ_ids.pop();
|
const admin_iq = sent_IQs.pop();
|
||||||
const owner_iq_id = IQ_ids.pop();
|
const owner_iq = sent_IQs.pop();
|
||||||
const member_iq_id = IQ_ids.pop();
|
const member_iq = sent_IQs.pop();
|
||||||
|
expect(Strophe.serialize(admin_iq)).toBe(
|
||||||
expect(sent_IQs.pop().toLocaleString()).toBe(
|
`<iq id="${admin_iq.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
|
||||||
`<iq id="${admin_iq_id}" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
|
|
||||||
`<query xmlns="http://jabber.org/protocol/muc#admin">`+
|
`<query xmlns="http://jabber.org/protocol/muc#admin">`+
|
||||||
`<item affiliation="admin"/>`+
|
`<item affiliation="admin"/>`+
|
||||||
`</query>`+
|
`</query>`+
|
||||||
`</iq>`);
|
`</iq>`);
|
||||||
expect(sent_IQs.pop().toLocaleString()).toBe(
|
expect(Strophe.serialize(owner_iq)).toBe(
|
||||||
`<iq id="${owner_iq_id}" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
|
`<iq id="${owner_iq.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
|
||||||
`<query xmlns="http://jabber.org/protocol/muc#admin">`+
|
`<query xmlns="http://jabber.org/protocol/muc#admin">`+
|
||||||
`<item affiliation="owner"/>`+
|
`<item affiliation="owner"/>`+
|
||||||
`</query>`+
|
`</query>`+
|
||||||
`</iq>`);
|
`</iq>`);
|
||||||
expect(sent_IQs.pop().toLocaleString()).toBe(
|
expect(Strophe.serialize(member_iq)).toBe(
|
||||||
`<iq id="${member_iq_id}" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
|
`<iq id="${member_iq.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
|
||||||
`<query xmlns="http://jabber.org/protocol/muc#admin">`+
|
`<query xmlns="http://jabber.org/protocol/muc#admin">`+
|
||||||
`<item affiliation="member"/>`+
|
`<item affiliation="member"/>`+
|
||||||
`</query>`+
|
`</query>`+
|
||||||
|
@ -4281,9 +4304,9 @@
|
||||||
* </query>
|
* </query>
|
||||||
* </iq>
|
* </iq>
|
||||||
*/
|
*/
|
||||||
var member_list_stanza = $iq({
|
const member_list_stanza = $iq({
|
||||||
'from': 'coven@chat.shakespeare.lit',
|
'from': 'coven@chat.shakespeare.lit',
|
||||||
'id': member_iq_id,
|
'id': member_iq.getAttribute('id'),
|
||||||
'to': 'romeo@montague.lit/orchard',
|
'to': 'romeo@montague.lit/orchard',
|
||||||
'type': 'result'
|
'type': 'result'
|
||||||
}).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
|
}).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
|
||||||
|
@ -4295,9 +4318,9 @@
|
||||||
});
|
});
|
||||||
_converse.connection._dataRecv(test_utils.createRequest(member_list_stanza));
|
_converse.connection._dataRecv(test_utils.createRequest(member_list_stanza));
|
||||||
|
|
||||||
var admin_list_stanza = $iq({
|
const admin_list_stanza = $iq({
|
||||||
'from': 'coven@chat.shakespeare.lit',
|
'from': 'coven@chat.shakespeare.lit',
|
||||||
'id': admin_iq_id,
|
'id': admin_iq.getAttribute('id'),
|
||||||
'to': 'romeo@montague.lit/orchard',
|
'to': 'romeo@montague.lit/orchard',
|
||||||
'type': 'result'
|
'type': 'result'
|
||||||
}).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
|
}).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
|
||||||
|
@ -4308,9 +4331,9 @@
|
||||||
});
|
});
|
||||||
_converse.connection._dataRecv(test_utils.createRequest(admin_list_stanza));
|
_converse.connection._dataRecv(test_utils.createRequest(admin_list_stanza));
|
||||||
|
|
||||||
var owner_list_stanza = $iq({
|
const owner_list_stanza = $iq({
|
||||||
'from': 'coven@chat.shakespeare.lit',
|
'from': 'coven@chat.shakespeare.lit',
|
||||||
'id': owner_iq_id,
|
'id': owner_iq.getAttribute('id'),
|
||||||
'to': 'romeo@montague.lit/orchard',
|
'to': 'romeo@montague.lit/orchard',
|
||||||
'type': 'result'
|
'type': 'result'
|
||||||
}).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
|
}).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
|
||||||
|
@ -4319,20 +4342,31 @@
|
||||||
'jid': 'crone1@shakespeare.lit',
|
'jid': 'crone1@shakespeare.lit',
|
||||||
});
|
});
|
||||||
_converse.connection._dataRecv(test_utils.createRequest(owner_list_stanza));
|
_converse.connection._dataRecv(test_utils.createRequest(owner_list_stanza));
|
||||||
await u.waitUntil(() => IQ_ids.length, 300);
|
|
||||||
stanza = await u.waitUntil(() => _.filter(
|
stanza = await u.waitUntil(() => _.filter(
|
||||||
IQ_stanzas,
|
IQ_stanzas,
|
||||||
iq => iq.querySelector(
|
iq => iq.querySelector(
|
||||||
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/muc#admin"]`
|
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/muc#admin"]`
|
||||||
)).pop());
|
)).pop());
|
||||||
expect(stanza.outerHTML,
|
expect(stanza.outerHTML,
|
||||||
`<iq id="${IQ_ids.pop()}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
|
`<iq id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
|
||||||
`<query xmlns="http://jabber.org/protocol/muc#admin">`+
|
`<query xmlns="http://jabber.org/protocol/muc#admin">`+
|
||||||
`<item affiliation="member" jid="${invitee_jid}">`+
|
`<item affiliation="member" jid="${invitee_jid}">`+
|
||||||
`<reason>Please join this groupchat</reason>`+
|
`<reason>Please join this groupchat</reason>`+
|
||||||
`</item>`+
|
`</item>`+
|
||||||
`</query>`+
|
`</query>`+
|
||||||
`</iq>`);
|
`</iq>`);
|
||||||
|
|
||||||
|
const result = $iq({
|
||||||
|
'from': 'coven@chat.shakespeare.lit',
|
||||||
|
'id': stanza.getAttribute('id'),
|
||||||
|
'to': 'romeo@montague.lit/orchard',
|
||||||
|
'type': 'result'
|
||||||
|
});
|
||||||
|
_converse.connection._dataRecv(test_utils.createRequest(result));
|
||||||
|
|
||||||
|
await u.waitUntil(() => view.model.occupants.fetchMembers.calls.count());
|
||||||
|
|
||||||
// Finally check that the user gets invited.
|
// Finally check that the user gets invited.
|
||||||
expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
|
expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
|
||||||
`<message from="romeo@montague.lit/orchard" id="${sent_id}" to="${invitee_jid}" xmlns="jabber:client">`+
|
`<message from="romeo@montague.lit/orchard" id="${sent_id}" to="${invitee_jid}" xmlns="jabber:client">`+
|
||||||
|
|
|
@ -116,6 +116,7 @@ converse.plugins.add('converse-muc', {
|
||||||
'auto_register_muc_nickname': false,
|
'auto_register_muc_nickname': false,
|
||||||
'locked_muc_domain': false,
|
'locked_muc_domain': false,
|
||||||
'muc_domain': undefined,
|
'muc_domain': undefined,
|
||||||
|
'muc_fetch_members': true,
|
||||||
'muc_history_max_stanzas': undefined,
|
'muc_history_max_stanzas': undefined,
|
||||||
'muc_instant_rooms': true,
|
'muc_instant_rooms': true,
|
||||||
'muc_nickname_from_jid': false
|
'muc_nickname_from_jid': false
|
||||||
|
@ -417,7 +418,9 @@ converse.plugins.add('converse-muc', {
|
||||||
|
|
||||||
async onConnectionStatusChanged () {
|
async onConnectionStatusChanged () {
|
||||||
if (this.get('connection_status') === converse.ROOMSTATUS.ENTERED) {
|
if (this.get('connection_status') === converse.ROOMSTATUS.ENTERED) {
|
||||||
await this.occupants.fetchMembers();
|
if (_converse.muc_fetch_members) {
|
||||||
|
await this.occupants.fetchMembers();
|
||||||
|
}
|
||||||
// It's possible to fetch messages before entering a MUC,
|
// It's possible to fetch messages before entering a MUC,
|
||||||
// but we don't support this use-case currently. By
|
// but we don't support this use-case currently. By
|
||||||
// fetching messages after members we can immediately
|
// fetching messages after members we can immediately
|
||||||
|
@ -856,18 +859,11 @@ converse.plugins.add('converse-muc', {
|
||||||
* @param { object } members - A map of jids, affiliations and
|
* @param { object } members - A map of jids, affiliations and
|
||||||
* optionally reasons. Only those entries with the
|
* optionally reasons. Only those entries with the
|
||||||
* same affiliation as being currently set will be considered.
|
* same affiliation as being currently set will be considered.
|
||||||
* @returns
|
* @returns { Promise } A promise which resolves and fails depending on the XMPP server response.
|
||||||
* A promise which resolves and fails depending on the XMPP server response.
|
|
||||||
*/
|
*/
|
||||||
setAffiliation (affiliation, members) {
|
setAffiliation (affiliation, members) {
|
||||||
members = _.filter(members, (member) =>
|
members = members.filter(m => _.isUndefined(m.affiliation) || m.affiliation === affiliation);
|
||||||
// We only want those members who have the right
|
return Promise.all(members.map(m => this.sendAffiliationIQ(affiliation, m)));
|
||||||
// affiliation (or none, which implies the provided one).
|
|
||||||
_.isUndefined(member.affiliation) ||
|
|
||||||
member.affiliation === affiliation
|
|
||||||
);
|
|
||||||
const promises = _.map(members, _.bind(this.sendAffiliationIQ, this, affiliation));
|
|
||||||
return Promise.all(promises);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1050,18 +1046,20 @@ converse.plugins.add('converse-muc', {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send IQ stanzas to the server to modify the
|
* Send IQ stanzas to the server to modify affiliations for users in this groupchat.
|
||||||
* affiliations in this groupchat.
|
*
|
||||||
* See: https://xmpp.org/extensions/xep-0045.html#modifymember
|
* See: https://xmpp.org/extensions/xep-0045.html#modifymember
|
||||||
* @private
|
* @private
|
||||||
* @method _converse.ChatRoom#setAffiliations
|
* @method _converse.ChatRoom#setAffiliations
|
||||||
* @param { object } members - A map of jids, affiliations and optionally reasons
|
* @param { Object[] } members
|
||||||
* @param { function } onSuccess - callback for a succesful response
|
* @param { string } members[].jid - The JID of the user whose affiliation will change
|
||||||
* @param { function } onError - callback for an error response
|
* @param { Array } members[].affiliation - The new affiliation for this user
|
||||||
|
* @param { string } [members[].reason] - An optional reason for the affiliation change
|
||||||
|
* @returns { Promise }
|
||||||
*/
|
*/
|
||||||
setAffiliations (members) {
|
setAffiliations (members) {
|
||||||
const affiliations = _.uniq(_.map(members, 'affiliation'));
|
const affiliations = _.uniq(members.map(m => m.affiliation));
|
||||||
return Promise.all(_.map(affiliations, _.partial(this.setAffiliation.bind(this), _, members)));
|
return Promise.all(affiliations.map(a => this.setAffiliation(a, members)));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1101,10 +1099,15 @@ converse.plugins.add('converse-muc', {
|
||||||
this.occupants.findWhere({'nick': nick_or_jid});
|
this.occupants.findWhere({'nick': nick_or_jid});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a map of JIDs that have the affiliations
|
||||||
|
* as provided.
|
||||||
|
* @private
|
||||||
|
* @method _converse.ChatRoom#getJidsWithAffiliations
|
||||||
|
* @param { string|array } affiliation - An array of affiliations or
|
||||||
|
* a string if only one affiliation.
|
||||||
|
*/
|
||||||
async getJidsWithAffiliations (affiliations) {
|
async getJidsWithAffiliations (affiliations) {
|
||||||
/* Returns a map of JIDs that have the affiliations
|
|
||||||
* as provided.
|
|
||||||
*/
|
|
||||||
if (_.isString(affiliations)) {
|
if (_.isString(affiliations)) {
|
||||||
affiliations = [affiliations];
|
affiliations = [affiliations];
|
||||||
}
|
}
|
||||||
|
@ -1135,11 +1138,17 @@ converse.plugins.add('converse-muc', {
|
||||||
* updated or once it's been established there's no need
|
* updated or once it's been established there's no need
|
||||||
* to update the list.
|
* to update the list.
|
||||||
*/
|
*/
|
||||||
updateMemberLists (members, affiliations, deltaFunc) {
|
async updateMemberLists (members, affiliations, deltaFunc) {
|
||||||
this.getJidsWithAffiliations(affiliations)
|
try {
|
||||||
.then(old_members => this.setAffiliations(deltaFunc(members, old_members)))
|
const old_members = await this.getJidsWithAffiliations(affiliations);
|
||||||
.then(() => this.occupants.fetchMembers())
|
await this.setAffiliations(deltaFunc(members, old_members));
|
||||||
.catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR));
|
} catch (e) {
|
||||||
|
_converse.log(e, Strophe.LogLevel.ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_converse.muc_fetch_members) {
|
||||||
|
return this.occupants.fetchMembers();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -39,10 +39,11 @@ const { Strophe, sizzle, _ } = converse.env;
|
||||||
* to 'none'.
|
* to 'none'.
|
||||||
* @param { array } new_list - Array containing the new affiliations
|
* @param { array } new_list - Array containing the new affiliations
|
||||||
* @param { array } old_list - Array containing the old affiliations
|
* @param { array } old_list - Array containing the old affiliations
|
||||||
|
* @returns { array }
|
||||||
*/
|
*/
|
||||||
u.computeAffiliationsDelta = function computeAffiliationsDelta (exclude_existing, remove_absentees, new_list, old_list) {
|
u.computeAffiliationsDelta = function computeAffiliationsDelta (exclude_existing, remove_absentees, new_list, old_list) {
|
||||||
const new_jids = _.map(new_list, 'jid');
|
const new_jids = new_list.map(o => o.jid);
|
||||||
const old_jids = _.map(old_list, 'jid');
|
const old_jids = old_list.map(o => o.jid);
|
||||||
|
|
||||||
// Get the new affiliations
|
// Get the new affiliations
|
||||||
let delta = _.map(
|
let delta = _.map(
|
||||||
|
|
|
@ -287,7 +287,9 @@
|
||||||
|
|
||||||
const view = _converse.chatboxviews.get(muc_jid);
|
const view = _converse.chatboxviews.get(muc_jid);
|
||||||
await u.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.ENTERED));
|
await u.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.ENTERED));
|
||||||
await utils.returnMemberLists(_converse, muc_jid, members);
|
if (_converse.muc_fetch_members) {
|
||||||
|
await utils.returnMemberLists(_converse, muc_jid, members);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
utils.clearBrowserStorage = function () {
|
utils.clearBrowserStorage = function () {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user