Group MUC utility methods in muc_utils object
as opposed to having them in the `u` object
This commit is contained in:
parent
8523cae8d0
commit
e915321e33
17
spec/muc.js
17
spec/muc.js
|
@ -4421,25 +4421,26 @@
|
|||
var remove_absentees = false;
|
||||
var new_list = [];
|
||||
var old_list = [];
|
||||
var delta = u.computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list);
|
||||
const muc_utils = converse.env.muc_utils;
|
||||
var delta = muc_utils.computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list);
|
||||
expect(delta.length).toBe(0);
|
||||
|
||||
new_list = [{'jid': 'wiccarocks@shakespeare.lit', 'affiliation': 'member'}];
|
||||
old_list = [{'jid': 'wiccarocks@shakespeare.lit', 'affiliation': 'member'}];
|
||||
delta = u.computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list);
|
||||
delta = muc_utils.computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list);
|
||||
expect(delta.length).toBe(0);
|
||||
|
||||
// When remove_absentees is false, then affiliations in the old
|
||||
// list which are not in the new one won't be removed.
|
||||
old_list = [{'jid': 'oldhag666@shakespeare.lit', 'affiliation': 'owner'},
|
||||
{'jid': 'wiccarocks@shakespeare.lit', 'affiliation': 'member'}];
|
||||
delta = u.computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list);
|
||||
delta = muc_utils.computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list);
|
||||
expect(delta.length).toBe(0);
|
||||
|
||||
// With exclude_existing set to false, any changed affiliations
|
||||
// will be included in the delta (i.e. existing affiliations are included in the comparison).
|
||||
old_list = [{'jid': 'wiccarocks@shakespeare.lit', 'affiliation': 'owner'}];
|
||||
delta = u.computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list);
|
||||
delta = muc_utils.computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list);
|
||||
expect(delta.length).toBe(1);
|
||||
expect(delta[0].jid).toBe('wiccarocks@shakespeare.lit');
|
||||
expect(delta[0].affiliation).toBe('member');
|
||||
|
@ -4449,12 +4450,12 @@
|
|||
remove_absentees = true;
|
||||
old_list = [{'jid': 'oldhag666@shakespeare.lit', 'affiliation': 'owner'},
|
||||
{'jid': 'wiccarocks@shakespeare.lit', 'affiliation': 'member'}];
|
||||
delta = u.computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list);
|
||||
delta = muc_utils.computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list);
|
||||
expect(delta.length).toBe(1);
|
||||
expect(delta[0].jid).toBe('oldhag666@shakespeare.lit');
|
||||
expect(delta[0].affiliation).toBe('none');
|
||||
|
||||
delta = u.computeAffiliationsDelta(exclude_existing, remove_absentees, [], old_list);
|
||||
delta = muc_utils.computeAffiliationsDelta(exclude_existing, remove_absentees, [], old_list);
|
||||
expect(delta.length).toBe(2);
|
||||
expect(delta[0].jid).toBe('oldhag666@shakespeare.lit');
|
||||
expect(delta[0].affiliation).toBe('none');
|
||||
|
@ -4465,11 +4466,11 @@
|
|||
// affiliation, we set 'exclude_existing' to true
|
||||
exclude_existing = true;
|
||||
old_list = [{'jid': 'wiccarocks@shakespeare.lit', 'affiliation': 'owner'}];
|
||||
delta = u.computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list);
|
||||
delta = muc_utils.computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list);
|
||||
expect(delta.length).toBe(0);
|
||||
|
||||
old_list = [{'jid': 'wiccarocks@shakespeare.lit', 'affiliation': 'admin'}];
|
||||
delta = u.computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list);
|
||||
delta = muc_utils.computeAffiliationsDelta(exclude_existing, remove_absentees, new_list, old_list);
|
||||
expect(delta.length).toBe(0);
|
||||
done();
|
||||
}));
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
*/
|
||||
import "./converse-disco";
|
||||
import "./converse-emoji";
|
||||
import "./utils/muc";
|
||||
import { clone, get, intersection, invoke, isElement, isObject, isString, uniq, zipObject } from "lodash";
|
||||
import converse from "./converse-core";
|
||||
import log from "./log";
|
||||
import muc_utils from "./utils/muc";
|
||||
import stanza_utils from "./utils/stanza";
|
||||
import u from "./utils/form";
|
||||
|
||||
|
@ -1121,7 +1121,7 @@ converse.plugins.add('converse-muc', {
|
|||
log.warn(result);
|
||||
return err;
|
||||
}
|
||||
return u.parseMemberListIQ(result).filter(p => p);
|
||||
return muc_utils.parseMemberListIQ(result).filter(p => p);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1141,7 +1141,7 @@ converse.plugins.add('converse-muc', {
|
|||
const all_affiliations = ['member', 'admin', 'owner'];
|
||||
const aff_lists = await Promise.all(all_affiliations.map(a => this.getAffiliationList(a)));
|
||||
const old_members = aff_lists.reduce((acc, val) => (u.isErrorObject(val) ? acc: [...val, ...acc]), []);
|
||||
await this.setAffiliations(u.computeAffiliationsDelta(true, false, members, old_members));
|
||||
await this.setAffiliations(muc_utils.computeAffiliationsDelta(true, false, members, old_members));
|
||||
if (_converse.muc_fetch_members) {
|
||||
return this.occupants.fetchMembers();
|
||||
}
|
||||
|
@ -2121,6 +2121,8 @@ converse.plugins.add('converse-muc', {
|
|||
|
||||
|
||||
/************************ BEGIN API ************************/
|
||||
converse.env.muc_utils = muc_utils;
|
||||
|
||||
// We extend the default converse.js API to add methods specific to MUC groupchats.
|
||||
Object.assign(_converse.api, {
|
||||
/**
|
||||
|
|
|
@ -6,110 +6,104 @@
|
|||
// Copyright (c) 2013-2019, Jan-Carel Brand <jc@opkode.com>
|
||||
// Licensed under the Mozilla Public License (MPLv2)
|
||||
//
|
||||
import { difference, indexOf } from "lodash";
|
||||
import converse from "@converse/headless/converse-core";
|
||||
import u from "./core";
|
||||
|
||||
const { Strophe, sizzle, _ } = converse.env;
|
||||
|
||||
const { Strophe, sizzle } = converse.env;
|
||||
|
||||
/**
|
||||
* Given two lists of objects with 'jid', 'affiliation' and
|
||||
* 'reason' properties, return a new list containing
|
||||
* those objects that are new, changed or removed
|
||||
* (depending on the 'remove_absentees' boolean).
|
||||
*
|
||||
* The affiliations for new and changed members stay the
|
||||
* same, for removed members, the affiliation is set to 'none'.
|
||||
*
|
||||
* The 'reason' property is not taken into account when
|
||||
* comparing whether affiliations have been changed.
|
||||
* @private
|
||||
* @method u#computeAffiliationsDelta
|
||||
* @param { boolean } exclude_existing - Indicates whether JIDs from
|
||||
* the new list which are also in the old list
|
||||
* (regardless of affiliation) should be excluded
|
||||
* from the delta. One reason to do this
|
||||
* would be when you want to add a JID only if it
|
||||
* doesn't have *any* existing affiliation at all.
|
||||
* @param { boolean } remove_absentees - Indicates whether JIDs
|
||||
* from the old list which are not in the new list
|
||||
* should be considered removed and therefore be
|
||||
* included in the delta with affiliation set
|
||||
* to 'none'.
|
||||
* @param { array } new_list - Array containing the new affiliations
|
||||
* @param { array } old_list - Array containing the old affiliations
|
||||
* @returns { array }
|
||||
* The MUC utils object. Contains utility functions related to multi-user chat.
|
||||
* @namespace stanza_utils
|
||||
*/
|
||||
u.computeAffiliationsDelta = function computeAffiliationsDelta (exclude_existing, remove_absentees, new_list, old_list) {
|
||||
const new_jids = new_list.map(o => o.jid);
|
||||
const old_jids = old_list.map(o => o.jid);
|
||||
|
||||
// Get the new affiliations
|
||||
let delta = _.map(
|
||||
_.difference(new_jids, old_jids),
|
||||
(jid) => new_list[_.indexOf(new_jids, jid)]
|
||||
);
|
||||
if (!exclude_existing) {
|
||||
// Get the changed affiliations
|
||||
delta = delta.concat(_.filter(new_list, function (item) {
|
||||
const idx = _.indexOf(old_jids, item.jid);
|
||||
if (idx >= 0) {
|
||||
return item.affiliation !== old_list[idx].affiliation;
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
if (remove_absentees) {
|
||||
// Get the removed affiliations
|
||||
delta = delta.concat(
|
||||
_.map(
|
||||
_.difference(old_jids, new_jids),
|
||||
(jid) => ({'jid': jid, 'affiliation': 'none'})
|
||||
)
|
||||
);
|
||||
}
|
||||
return delta;
|
||||
};
|
||||
|
||||
/**
|
||||
* Given an IQ stanza with a member list, create an array of objects containing
|
||||
* known member data (e.g. jid, nick, role, affiliation).
|
||||
* @private
|
||||
* @method u#parseMemberListIQ
|
||||
* @returns { MemberListItem[] }
|
||||
*/
|
||||
u.parseMemberListIQ = function parseMemberListIQ (iq) {
|
||||
return sizzle(`query[xmlns="${Strophe.NS.MUC_ADMIN}"] item`, iq).map(
|
||||
(item) => {
|
||||
/**
|
||||
* @typedef {Object} MemberListItem
|
||||
* Either the JID or the nickname (or both) will be available.
|
||||
* @property {string} affiliation
|
||||
* @property {string} [role]
|
||||
* @property {string} [jid]
|
||||
* @property {string} [nick]
|
||||
*/
|
||||
const data = {
|
||||
'affiliation': item.getAttribute('affiliation'),
|
||||
}
|
||||
const jid = item.getAttribute('jid');
|
||||
if (u.isValidJID(jid)) {
|
||||
data['jid'] = jid;
|
||||
} else {
|
||||
// XXX: Prosody sends nick for the jid attribute value
|
||||
// Perhaps for anonymous room?
|
||||
data['nick'] = jid;
|
||||
}
|
||||
const nick = item.getAttribute('nick');
|
||||
if (nick) {
|
||||
data['nick'] = nick;
|
||||
}
|
||||
const role = item.getAttribute('role');
|
||||
if (role) {
|
||||
data['role'] = nick;
|
||||
}
|
||||
return data;
|
||||
const muc_utils = {
|
||||
/**
|
||||
* Given two lists of objects with 'jid', 'affiliation' and
|
||||
* 'reason' properties, return a new list containing
|
||||
* those objects that are new, changed or removed
|
||||
* (depending on the 'remove_absentees' boolean).
|
||||
*
|
||||
* The affiliations for new and changed members stay the
|
||||
* same, for removed members, the affiliation is set to 'none'.
|
||||
*
|
||||
* The 'reason' property is not taken into account when
|
||||
* comparing whether affiliations have been changed.
|
||||
* @private
|
||||
* @method muc_utils#computeAffiliationsDelta
|
||||
* @param { boolean } exclude_existing - Indicates whether JIDs from
|
||||
* the new list which are also in the old list
|
||||
* (regardless of affiliation) should be excluded
|
||||
* from the delta. One reason to do this
|
||||
* would be when you want to add a JID only if it
|
||||
* doesn't have *any* existing affiliation at all.
|
||||
* @param { boolean } remove_absentees - Indicates whether JIDs
|
||||
* from the old list which are not in the new list
|
||||
* should be considered removed and therefore be
|
||||
* included in the delta with affiliation set
|
||||
* to 'none'.
|
||||
* @param { array } new_list - Array containing the new affiliations
|
||||
* @param { array } old_list - Array containing the old affiliations
|
||||
* @returns { array }
|
||||
*/
|
||||
computeAffiliationsDelta (exclude_existing, remove_absentees, new_list, old_list) {
|
||||
const new_jids = new_list.map(o => o.jid);
|
||||
const old_jids = old_list.map(o => o.jid);
|
||||
// Get the new affiliations
|
||||
let delta = difference(new_jids, old_jids).map(jid => new_list[indexOf(new_jids, jid)]);
|
||||
if (!exclude_existing) {
|
||||
// Get the changed affiliations
|
||||
delta = delta.concat(new_list.filter(item => {
|
||||
const idx = indexOf(old_jids, item.jid);
|
||||
return idx >= 0 ? (item.affiliation !== old_list[idx].affiliation) : false;
|
||||
}));
|
||||
}
|
||||
);
|
||||
};
|
||||
if (remove_absentees) { // Get the removed affiliations
|
||||
delta = delta.concat(difference(old_jids, new_jids).map(jid => ({'jid': jid, 'affiliation': 'none'})));
|
||||
}
|
||||
return delta;
|
||||
},
|
||||
|
||||
/**
|
||||
* Given an IQ stanza with a member list, create an array of objects containing
|
||||
* known member data (e.g. jid, nick, role, affiliation).
|
||||
* @private
|
||||
* @method muc_utils#parseMemberListIQ
|
||||
* @returns { MemberListItem[] }
|
||||
*/
|
||||
parseMemberListIQ (iq) {
|
||||
return sizzle(`query[xmlns="${Strophe.NS.MUC_ADMIN}"] item`, iq).map(
|
||||
(item) => {
|
||||
/**
|
||||
* @typedef {Object} MemberListItem
|
||||
* Either the JID or the nickname (or both) will be available.
|
||||
* @property {string} affiliation
|
||||
* @property {string} [role]
|
||||
* @property {string} [jid]
|
||||
* @property {string} [nick]
|
||||
*/
|
||||
const data = {
|
||||
'affiliation': item.getAttribute('affiliation'),
|
||||
}
|
||||
const jid = item.getAttribute('jid');
|
||||
if (u.isValidJID(jid)) {
|
||||
data['jid'] = jid;
|
||||
} else {
|
||||
// XXX: Prosody sends nick for the jid attribute value
|
||||
// Perhaps for anonymous room?
|
||||
data['nick'] = jid;
|
||||
}
|
||||
const nick = item.getAttribute('nick');
|
||||
if (nick) {
|
||||
data['nick'] = nick;
|
||||
}
|
||||
const role = item.getAttribute('role');
|
||||
if (role) {
|
||||
data['role'] = nick;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
export default muc_utils;
|
||||
|
|
Loading…
Reference in New Issue
Block a user