Specify the reason (if given) when setting someone's affiliation

This changed required me to go back to an array of maps instead of a single map
to store jids and affiliations.
This commit is contained in:
JC Brand 2016-12-07 11:30:28 +00:00
parent b516ae51e7
commit 77d3e64f42
2 changed files with 49 additions and 31 deletions

View File

@ -1531,7 +1531,9 @@
expect(sent_IQs.pop().toLocaleString()).toBe( expect(sent_IQs.pop().toLocaleString()).toBe(
"<iq to='coven@chat.shakespeare.lit' type='set' xmlns='jabber:client' id='"+IQ_ids.pop()+"'>"+ "<iq to='coven@chat.shakespeare.lit' type='set' xmlns='jabber:client' id='"+IQ_ids.pop()+"'>"+
"<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 chat room</reason>"+
"</item>"+
"</query>"+ "</query>"+
"</iq>"); "</iq>");

View File

@ -532,50 +532,58 @@
); );
}, },
computeAffiliationsDelta: function (exclude_existing, remove_absentees, new_map, old_map) { computeAffiliationsDelta: function (exclude_existing, remove_absentees, new_list, old_list) {
/* Given two affiliation maps (JIDs mapped to /* Given two lists of objects with 'jid', 'affiliation' and
* affiliations), return a new map containing * 'reason' properties, return a new list containing
* those JIDs that are new, changed or removed * those objects that are new, changed or removed
* (depending on the 'remove_absentees' boolean). * (depending on the 'remove_absentees' boolean).
* *
* The affiliations for new and changed members stay the * The affiliations for new and changed members stay the
* same, for removed members, the affiliation is set to 'none'. * 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.
*
* Parameters: * Parameters:
* (Boolean) exclude_existing: Indicates whether JIDs from * (Boolean) exclude_existing: Indicates whether JIDs from
* the new map which are also in the old map * the new list which are also in the old list
* (regardless of affiliation) should be excluded * (regardless of affiliation) should be excluded
* from the delta. One reason to do this * from the delta. One reason to do this
* would be when you want to add a JID only if it * would be when you want to add a JID only if it
* doesn't have *any* existing affiliation at all. * doesn't have *any* existing affiliation at all.
* (Boolean) remove_absentees: Indicates whether JIDs * (Boolean) remove_absentees: Indicates whether JIDs
* from the old map which are not in the new map * from the old list which are not in the new list
* should be considered removed and therefore be * should be considered removed and therefore be
* included in the delta with affiliation set * included in the delta with affiliation set
* to 'none'. * to 'none'.
* (Object) new_map: Map containing the new affiliations * (Array) new_list: Array containing the new affiliations
* (Object) old_map: Map containing the old affiliations * (Array) old_list: Array containing the old affiliations
*/ */
var delta = {}; var new_jids = _.pluck(new_list, 'jid');
var new_jids = _.keys(new_map); var old_jids = _.pluck(old_list, 'jid');
var old_jids = _.keys(old_map);
var same_jids = _.intersection(new_jids, old_jids);
// Get the new affiliations // Get the new affiliations
_.each(_.difference(new_jids, old_jids), function (jid) { var delta = _.map(_.difference(new_jids, old_jids), function (jid) {
delta[jid] = new_map[jid]; return new_list[_.indexOf(new_jids, jid)];
}); });
if (!exclude_existing) { if (!exclude_existing) {
// Get the changed affiliations // Get the changed affiliations
_.each(same_jids, function (jid) { var same_list = _.intersection(new_jids, old_jids);
if (new_map[jid] !== old_map[jid]) { delta = delta.concat(_.filter(same_list, function (item) {
delta[jid] = new_map[jid]; var old_item;
var idx = _.indexOf(old_jids, item);
if (idx >= 0) {
old_item = old_list[idx];
return item.jid !== old_item.jid &&
item.affiliation !== old_item.affiliation;
} }
}); return false;
}));
} }
if (remove_absentees) { if (remove_absentees) {
// Get the removed affiliations // Get the removed affiliations
_.each(_.difference(old_jids, new_jids), function (jid) { delta = _.map(_.difference(old_jids, new_jids), function (jid) {
delta[jid] = 'none'; return {'jid': jid, 'affiliation': 'none'};
}); });
} }
return delta; return delta;
@ -599,24 +607,28 @@
} }
var iq = $iq({to: this.model.get('jid'), type: "set"}) var iq = $iq({to: this.model.get('jid'), type: "set"})
.c("query", {xmlns: Strophe.NS.MUC_ADMIN}); .c("query", {xmlns: Strophe.NS.MUC_ADMIN});
_.each(_.keys(members), function (jid) { _.each(members, function (member) {
iq.c("item", { iq.c("item", {
'affiliation': members[jid], 'affiliation': member.affiliation,
'jid': jid 'jid': member.jid
}); });
if (!_.isUndefined(member.reason)) {
iq.c("reason", member.reason).up();
}
iq.up();
}); });
return converse.connection.sendIQ(iq, onSuccess, onError); return converse.connection.sendIQ(iq, onSuccess, onError);
}, },
marshallAffiliationIQs: function (iqs) { marshallAffiliationIQs: function () {
/* Marshall a list of IQ stanzas into a map of JIDs and /* Marshall a list of IQ stanzas into a map of JIDs and
* affiliations. * affiliations.
*
* Parameters:
* Any amount of XMLElement objects, representing the IQ
* stanzas.
*/ */
var affiliations = _.flatten(_.map(iqs, this.parseMemberListIQ)); return _.flatten(_.map(arguments, this.parseMemberListIQ));
return _.reduce(affiliations, function (memo, member) {
memo[member.jid] = member.affiliation;
return memo;
}, {});
}, },
getJidsWithAffiliations: function (affiliations) { getJidsWithAffiliations: function (affiliations) {
@ -682,7 +694,11 @@
// already), otherwise they won't be able to join. // already), otherwise they won't be able to join.
var map = {}; map[recipient] = 'member'; var map = {}; map[recipient] = 'member';
var deltaFunc = _.partial(this.computeAffiliationsDelta, true, false); var deltaFunc = _.partial(this.computeAffiliationsDelta, true, false);
this.updateMemberLists(map, ['member', 'owner', 'admin'], deltaFunc); this.updateMemberLists(
[{'jid': recipient, 'affiliation': 'member', 'reason': reason}],
['member', 'owner', 'admin'],
deltaFunc
);
} }
var attrs = { var attrs = {
'xmlns': 'jabber:x:conference', 'xmlns': 'jabber:x:conference',