muc.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Converse.js (A browser based XMPP chat client)
  2. // http://conversejs.org
  3. //
  4. // This is the utilities module.
  5. //
  6. // Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
  7. // Licensed under the Mozilla Public License (MPLv2)
  8. //
  9. /*global define, escape, Jed */
  10. (function (root, factory) {
  11. define(["../converse-core", "./core"], factory);
  12. }(this, function (converse, u) {
  13. "use strict";
  14. const { Strophe, sizzle, _ } = converse.env;
  15. u.computeAffiliationsDelta = function computeAffiliationsDelta (exclude_existing, remove_absentees, new_list, old_list) {
  16. /* Given two lists of objects with 'jid', 'affiliation' and
  17. * 'reason' properties, return a new list containing
  18. * those objects that are new, changed or removed
  19. * (depending on the 'remove_absentees' boolean).
  20. *
  21. * The affiliations for new and changed members stay the
  22. * same, for removed members, the affiliation is set to 'none'.
  23. *
  24. * The 'reason' property is not taken into account when
  25. * comparing whether affiliations have been changed.
  26. *
  27. * Parameters:
  28. * (Boolean) exclude_existing: Indicates whether JIDs from
  29. * the new list which are also in the old list
  30. * (regardless of affiliation) should be excluded
  31. * from the delta. One reason to do this
  32. * would be when you want to add a JID only if it
  33. * doesn't have *any* existing affiliation at all.
  34. * (Boolean) remove_absentees: Indicates whether JIDs
  35. * from the old list which are not in the new list
  36. * should be considered removed and therefore be
  37. * included in the delta with affiliation set
  38. * to 'none'.
  39. * (Array) new_list: Array containing the new affiliations
  40. * (Array) old_list: Array containing the old affiliations
  41. */
  42. const new_jids = _.map(new_list, 'jid');
  43. const old_jids = _.map(old_list, 'jid');
  44. // Get the new affiliations
  45. let delta = _.map(
  46. _.difference(new_jids, old_jids),
  47. (jid) => new_list[_.indexOf(new_jids, jid)]
  48. );
  49. if (!exclude_existing) {
  50. // Get the changed affiliations
  51. delta = delta.concat(_.filter(new_list, function (item) {
  52. const idx = _.indexOf(old_jids, item.jid);
  53. if (idx >= 0) {
  54. return item.affiliation !== old_list[idx].affiliation;
  55. }
  56. return false;
  57. }));
  58. }
  59. if (remove_absentees) {
  60. // Get the removed affiliations
  61. delta = delta.concat(
  62. _.map(
  63. _.difference(old_jids, new_jids),
  64. (jid) => ({'jid': jid, 'affiliation': 'none'})
  65. )
  66. );
  67. }
  68. return delta;
  69. };
  70. u.parseMemberListIQ = function parseMemberListIQ (iq) {
  71. /* Given an IQ stanza with a member list, create an array of member objects.
  72. */
  73. return _.map(
  74. sizzle(`query[xmlns="${Strophe.NS.MUC_ADMIN}"] item`, iq),
  75. (item) => {
  76. const data = {
  77. 'affiliation': item.getAttribute('affiliation'),
  78. }
  79. const jid = item.getAttribute('jid');
  80. if (u.isValidJID(jid)) {
  81. data['jid'] = jid;
  82. } else {
  83. // XXX: Prosody sends nick for the jid attribute value
  84. // Perhaps for anonymous room?
  85. data['nick'] = jid;
  86. }
  87. const nick = item.getAttribute('nick');
  88. if (nick) {
  89. data['nick'] = nick;
  90. }
  91. const role = item.getAttribute('role');
  92. if (role) {
  93. data['role'] = nick;
  94. }
  95. return data;
  96. }
  97. );
  98. };
  99. }));