api.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /**
  2. * @typedef {import('./muc.js').default} MUC
  3. */
  4. import _converse from '../../shared/_converse.js';
  5. import chatboxes from '../../plugins/chatboxes/api.js';
  6. import log from "@converse/log";
  7. import promise_api from '../../shared/api/promise.js';
  8. import { CHATROOMS_TYPE } from '../../shared/constants.js';
  9. import { Strophe } from 'strophe.js';
  10. import { getJIDFromURI } from '../../utils/jid.js';
  11. import { settings_api as settings } from '../../shared/settings/api.js';
  12. const { waitUntil } = promise_api;
  13. /**
  14. * The "rooms" namespace groups methods relevant to chatrooms
  15. * (aka groupchats).
  16. *
  17. * @namespace api.rooms
  18. * @memberOf api
  19. */
  20. const rooms = {
  21. /**
  22. * Creates a new MUC chatroom (aka groupchat)
  23. *
  24. * Similar to {@link api.rooms.open}, but creates
  25. * the chatroom in the background (i.e. doesn't cause a view to open).
  26. *
  27. * @method api.rooms.create
  28. * @param {(string[]|string)} jids The JID or array of
  29. * JIDs of the chatroom(s) to create
  30. * @param {object} [attrs] attrs The room attributes
  31. * @returns {Promise<MUC[]|MUC>} Promise which resolves with the Model representing the chat.
  32. */
  33. create (jids, attrs = {}) {
  34. attrs = typeof attrs === 'string' ? { 'nick': attrs } : attrs || {};
  35. if (!attrs.nick && settings.get('muc_nickname_from_jid')) {
  36. const bare_jid = _converse.session.get('bare_jid');
  37. attrs.nick = Strophe.getNodeFromJid(bare_jid);
  38. }
  39. if (jids === undefined) {
  40. throw new TypeError('rooms.create: You need to provide at least one JID');
  41. } else if (typeof jids === 'string') {
  42. return rooms.get(getJIDFromURI(jids), attrs, true);
  43. }
  44. return Promise.all(jids.map((jid) => /** @type {Promise<MUC>} */(rooms.get(getJIDFromURI(jid), attrs, true))));
  45. },
  46. /**
  47. * Opens a MUC chatroom (aka groupchat)
  48. *
  49. * Similar to {@link api.chats.open}, but for groupchats.
  50. *
  51. * @method api.rooms.open
  52. * @param {string|string[]} jids The room JID or JIDs (if not specified, all
  53. * currently open rooms will be returned).
  54. * @param {object} attrs A map containing any extra room attributes.
  55. * @param {string} [attrs.nick] The current user's nickname for the MUC
  56. * @param {boolean} [attrs.hidden]
  57. * @param {boolean} [attrs.auto_configure] A boolean, indicating
  58. * whether the room should be configured automatically or not.
  59. * If set to `true`, then it makes sense to pass in configuration settings.
  60. * @param {object} [attrs.roomconfig] A map of configuration settings to be used when the room gets
  61. * configured automatically. Currently it doesn't make sense to specify
  62. * `roomconfig` values if `auto_configure` is set to `false`.
  63. * For a list of configuration values that can be passed in, refer to these values
  64. * in the [XEP-0045 MUC specification](https://xmpp.org/extensions/xep-0045.html#registrar-formtype-owner).
  65. * The values should be named without the `muc#roomconfig_` prefix.
  66. * @param {boolean} [attrs.minimized] A boolean, indicating whether the room should be opened minimized or not.
  67. * @param {boolean} [force=false] - By default, a minimized
  68. * room won't be maximized (in `overlayed` view mode) and in
  69. * `fullscreen` view mode a newly opened room won't replace
  70. * another chat already in the foreground.
  71. * Set `force` to `true` if you want to force the room to be
  72. * maximized or shown.
  73. * @returns {Promise<MUC[]|MUC>} Promise which resolves with the Model representing the chat.
  74. *
  75. * @example
  76. * api.rooms.open('group@muc.example.com')
  77. *
  78. * @example
  79. * // To return an array of rooms, provide an array of room JIDs:
  80. * api.rooms.open(['group1@muc.example.com', 'group2@muc.example.com'])
  81. *
  82. * @example
  83. * // To setup a custom nickname when joining the room, provide the optional nick argument:
  84. * api.rooms.open('group@muc.example.com', {'nick': 'mycustomnick'})
  85. *
  86. * @example
  87. * // For example, opening a room with a specific default configuration:
  88. * api.rooms.open(
  89. * 'myroom@conference.example.org',
  90. * { 'nick': 'coolguy69',
  91. * 'auto_configure': true,
  92. * 'roomconfig': {
  93. * 'changesubject': false,
  94. * 'membersonly': true,
  95. * 'persistentroom': true,
  96. * 'publicroom': true,
  97. * 'roomdesc': 'Comfy room for hanging out',
  98. * 'whois': 'anyone'
  99. * }
  100. * }
  101. * );
  102. */
  103. async open (jids, attrs = {}, force = false) {
  104. await waitUntil('chatBoxesFetched');
  105. if (jids === undefined) {
  106. const err_msg = 'rooms.open: You need to provide at least one JID';
  107. log.error(err_msg);
  108. throw new TypeError(err_msg);
  109. } else if (typeof jids === 'string') {
  110. const room = /** @type {MUC} */(await rooms.get(jids, attrs, true));
  111. !attrs.hidden && room?.maybeShow(force);
  112. return room;
  113. } else {
  114. const rooms = await Promise.all(jids.map((jid) => rooms.get(jid, attrs, true)));
  115. rooms.forEach((r) => !attrs.hidden && r.maybeShow(force));
  116. return rooms;
  117. }
  118. },
  119. /**
  120. * Fetches the object representing a MUC chatroom (aka groupchat)
  121. *
  122. * @method api.rooms.get
  123. * @param {string|string[]} [jids] The room JID (if not specified, all rooms will be returned).
  124. * @param {object} [attrs] A map containing any extra room attributes
  125. * to be set if `create` is set to `true`
  126. * @param {string} [attrs.nick] Specify the nickname
  127. * @param {string} [attrs.password ] Specify a password if needed to enter a new room
  128. * @param {boolean} create A boolean indicating whether the room should be created
  129. * if not found (default: `false`)
  130. * @returns {Promise<MUC[]|MUC>}
  131. * @example
  132. * api.waitUntil('roomsAutoJoined').then(() => {
  133. * const create_if_not_found = true;
  134. * api.rooms.get(
  135. * 'group@muc.example.com',
  136. * {'nick': 'dread-pirate-roberts', 'password': 'secret'},
  137. * create_if_not_found
  138. * )
  139. * });
  140. */
  141. async get (jids, attrs = {}, create = false) {
  142. await waitUntil('chatBoxesFetched');
  143. /** @param {string} jid */
  144. async function _get(jid) {
  145. jid = getJIDFromURI(jid);
  146. let model = await chatboxes.get(jid);
  147. if (!model && create) {
  148. model = await chatboxes.create(jid, attrs, _converse.exports.MUC);
  149. } else {
  150. model = model && model.get('type') === CHATROOMS_TYPE ? model : null;
  151. if (model && Object.keys(attrs).length) {
  152. model.save(attrs);
  153. }
  154. }
  155. return model;
  156. }
  157. if (jids === undefined) {
  158. const chats = await chatboxes.get();
  159. return chats.filter((c) => c.get('type') === CHATROOMS_TYPE);
  160. } else if (typeof jids === 'string') {
  161. return _get(jids);
  162. }
  163. return Promise.all(jids.map((jid) => _get(jid)));
  164. },
  165. };
  166. const rooms_api = { rooms };
  167. export default rooms_api;