Commit 802c9d1f authored by JC Brand's avatar JC Brand

Make it configurable how the affiliations delta is computed.

When inviting someone to a members-only room, you only want to add an
affiliation of 'member' if they don't already have any other affiliation.

So we need to ignore the "new" member if they're already on *any* of the lists.
parent 58f07cf1
...@@ -532,7 +532,7 @@ ...@@ -532,7 +532,7 @@
); );
}, },
computeAffiliationsDelta: function (new_map, old_map, remove_absentees) { computeAffiliationsDelta: function (exclude_existing, remove_absentees, new_map, old_map) {
/* Given two affiliation maps (JIDs mapped to /* Given two affiliation maps (JIDs mapped to
* affiliations), return a new map containing * affiliations), return a new map containing
* those JIDs that are new, changed or removed * those JIDs that are new, changed or removed
...@@ -542,28 +542,36 @@ ...@@ -542,28 +542,36 @@
* same, for removed members, the affiliation is set to 'none'. * same, for removed members, the affiliation is set to 'none'.
* *
* Parameters: * Parameters:
* (Object) new_map: Map containing the new affiliations * (Boolean) exclude_existing: Indicates whether JIDs from
* (Object) old_map: Map containing the old affiliations * the new map which are also in the old map
* (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.
* (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 map which are not in the new map
* 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
* (Object) old_map: Map containing the old affiliations
*/ */
var delta = {}; var delta = {};
var new_jids = _.keys(new_map); var new_jids = _.keys(new_map);
var old_jids = _.keys(old_map); var old_jids = _.keys(old_map);
var same_jids = _.intersection(new_jids, old_jids); var same_jids = _.intersection(new_jids, old_jids);
// Get the new affiliations
_.each(_.difference(new_jids, old_jids), function (jid) {
delta[jid] = new_map[jid];
});
if (!exclude_existing) {
// Get the changed affiliations // Get the changed affiliations
_.each(same_jids, function (jid) { _.each(same_jids, function (jid) {
if (new_map[jid] !== old_map[jid]) { if (new_map[jid] !== old_map[jid]) {
delta[jid] = new_map[jid]; delta[jid] = new_map[jid];
} }
}); });
// Get the new affiliations }
_.each(_.difference(new_jids, old_jids), function (jid) {
delta[jid] = new_map[jid];
});
if (remove_absentees) { if (remove_absentees) {
// Get the removed affiliations // Get the removed affiliations
_.each(_.difference(old_jids, new_jids), function (jid) { _.each(_.difference(old_jids, new_jids), function (jid) {
...@@ -600,7 +608,31 @@ ...@@ -600,7 +608,31 @@
return converse.connection.sendIQ(iq, onSuccess, onError); return converse.connection.sendIQ(iq, onSuccess, onError);
}, },
updateMemberLists: function (members, affiliations, remove_absentees) { getJidsWithAffiliations: function (affiliations) {
/* Returns a map of JIDs that have the affiliations
* as provided.
*/
if (typeof affiliations === "string") {
affiliations = [affiliations];
}
var that = this;
var deferred = new $.Deferred();
var promises = [];
_.each(affiliations, function (affiliation) {
promises.push(that.requestMemberList(affiliation));
});
$.when.apply($, promises).always(function () {
var old_members = _.flatten(_.map(arguments, that.parseMemberListIQ));
old_members = _.reduce(old_members, function (memo, member) {
memo[member.jid] = member.affiliation;
return memo;
}, {});
deferred.resolve(old_members);
});
return deferred.promise();
},
updateMemberLists: function (members, affiliations, deltaFunc) {
/* Fetch the lists of users with the given affiliations. /* Fetch the lists of users with the given affiliations.
* Then compute the delta between those users and * Then compute the delta between those users and
* the passed in members, and if it exists, send the delta * the passed in members, and if it exists, send the delta
...@@ -610,10 +642,8 @@ ...@@ -610,10 +642,8 @@
* (Object) members: Map of member jids and affiliations. * (Object) members: Map of member jids and affiliations.
* (String|Array) affiliation: An array of affiliations or * (String|Array) affiliation: An array of affiliations or
* a string if only one affiliation. * a string if only one affiliation.
* (Boolean) remove_absentees: When computing the list * (Function) deltaFunc: The function to compute the delta
* delta, consider members from the old list that * between old and new member lists.
* are not in the new list as removed (therefore their
* affiliation will get set to 'none').
* *
* Returns: * Returns:
* A promise which is resolved once the list has been * A promise which is resolved once the list has been
...@@ -622,21 +652,12 @@ ...@@ -622,21 +652,12 @@
*/ */
var that = this; var that = this;
var deferred = new $.Deferred(); var deferred = new $.Deferred();
if (typeof affiliations === "string") { this.getJidsWithAffiliations(affiliations).then(function (old_members) {
affiliations = [affiliations]; that.setAffiliations(
} deltaFunc(members, old_members),
var promises = []; deferred.resolve,
_.each(affiliations, function (affiliation) { deferred.reject
promises.push(that.requestMemberList(affiliation)); );
});
$.when.apply($, promises).always(function () {
var old_members = _.flatten(_.map(arguments, that.parseMemberListIQ));
old_members = _.reduce(old_members, function (memo, member) {
memo[member.jid] = member.affiliation;
return memo;
}, {});
var delta = that.computeAffiliationsDelta(members, old_members, remove_absentees);
that.setAffiliations(delta, deferred.resolve, deferred.reject);
}); });
return deferred.promise(); return deferred.promise();
}, },
...@@ -650,11 +671,12 @@ ...@@ -650,11 +671,12 @@
*/ */
if (this.model.get('membersonly')) { if (this.model.get('membersonly')) {
// When inviting to a members-only room, we first add // When inviting to a members-only room, we first add
// the person to the member list, otherwise they won't // the person to the member list by giving them an
// be able to join. // affiliation of 'member' (if they're not affiliated
var map = {}; // already), otherwise they won't be able to join.
map[recipient] = 'member'; var map = {}; map[recipient] = 'member';
this.updateMemberLists(map, ['member', 'owner', 'admin'], false); var deltaFunc = _.partial(this.computeAffiliationsDelta, true, false);
this.updateMemberLists(map, ['member', 'owner', 'admin'], deltaFunc);
} }
var attrs = { var attrs = {
'xmlns': 'jabber:x:conference', 'xmlns': 'jabber:x:conference',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment