api.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /**
  2. * @typedef {import('./model.js').default} ChatBox
  3. */
  4. import _converse from '../../shared/_converse.js';
  5. import api from '../../shared/api/index.js';
  6. import log from "@converse/log";
  7. import { PRIVATE_CHAT_TYPE } from '../../shared/constants.js';
  8. export default {
  9. /**
  10. * The "chats" namespace (used for one-on-one chats)
  11. *
  12. * @namespace api.chats
  13. * @memberOf api
  14. */
  15. chats: {
  16. /**
  17. * @method api.chats.create
  18. * @param {string|string[]} jids An jid or array of jids
  19. * @param {object} [attrs] An object containing configuration attributes.
  20. * @returns {Promise<ChatBox|ChatBox[]>}
  21. */
  22. async create (jids, attrs) {
  23. if (typeof jids === 'string') {
  24. if (attrs && !attrs?.fullname) {
  25. const contact = await api.contacts.get(jids);
  26. attrs.fullname = contact?.attributes?.fullname;
  27. }
  28. const chatbox = api.chats.get(jids, attrs, true);
  29. if (!chatbox) {
  30. log.error("Could not open chatbox for JID: "+jids);
  31. return;
  32. }
  33. return chatbox;
  34. }
  35. if (Array.isArray(jids)) {
  36. return Promise.all(jids.map(async jid => {
  37. const contact = await api.contacts.get(jids);
  38. attrs.fullname = contact?.attributes?.fullname;
  39. return api.chats.get(jid, attrs, true).maybeShow();
  40. }));
  41. }
  42. log.error("chats.create: You need to provide at least one JID");
  43. return null;
  44. },
  45. /**
  46. * Opens a new one-on-one chat.
  47. *
  48. * @method api.chats.open
  49. * @param {String|string[]} jids - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
  50. * @param {Object} [attrs] - Attributes to be set on the _converse.ChatBox model.
  51. * @param {Boolean} [attrs.minimized] - Should the chat be created in minimized state.
  52. * @param {Boolean} [force=false] - By default, a minimized
  53. * chat won't be maximized (in `overlayed` view mode) and in
  54. * `fullscreen` view mode a newly opened chat won't replace
  55. * another chat already in the foreground.
  56. * Set `force` to `true` if you want to force the chat to be
  57. * maximized or shown.
  58. * @returns {Promise} Promise which resolves with the
  59. * _converse.ChatBox representing the chat.
  60. *
  61. * @example
  62. * // To open a single chat, provide the JID of the contact you're chatting with in that chat:
  63. * converse.plugins.add('myplugin', {
  64. * initialize: function() {
  65. * const _converse = this._converse;
  66. * // Note, buddy@example.org must be in your contacts roster!
  67. * api.chats.open('buddy@example.com').then(chat => {
  68. * // Now you can do something with the chat model
  69. * });
  70. * }
  71. * });
  72. *
  73. * @example
  74. * // To open an array of chats, provide an array of JIDs:
  75. * converse.plugins.add('myplugin', {
  76. * initialize: function () {
  77. * const _converse = this._converse;
  78. * // Note, these users must first be in your contacts roster!
  79. * api.chats.open(['buddy1@example.com', 'buddy2@example.com']).then(chats => {
  80. * // Now you can do something with the chat models
  81. * });
  82. * }
  83. * });
  84. */
  85. async open (jids, attrs, force) {
  86. if (typeof jids === 'string') {
  87. const chat = await api.chats.get(jids, attrs, true);
  88. if (chat) {
  89. return chat.maybeShow(force);
  90. }
  91. return chat;
  92. } else if (Array.isArray(jids)) {
  93. return Promise.all(
  94. jids.map(j => api.chats.get(j, attrs, true).then(c => c && c.maybeShow(force)))
  95. .filter(c => c)
  96. );
  97. }
  98. const err_msg = "chats.open: You need to provide at least one JID";
  99. log.error(err_msg);
  100. throw new Error(err_msg);
  101. },
  102. /**
  103. * Retrieves a chat or all chats.
  104. *
  105. * @method api.chats.get
  106. * @param {String|string[]} jids - e.g. 'buddy@example.com' or ['buddy1@example.com', 'buddy2@example.com']
  107. * @param {Object} [attrs] - Attributes to be set on the _converse.ChatBox model.
  108. * @param {Boolean} [create=false] - Whether the chat should be created if it's not found.
  109. * @returns {Promise<ChatBox[]>}
  110. *
  111. * @example
  112. * // To return a single chat, provide the JID of the contact you're chatting with in that chat:
  113. * const model = await api.chats.get('buddy@example.com');
  114. *
  115. * @example
  116. * // To return an array of chats, provide an array of JIDs:
  117. * const models = await api.chats.get(['buddy1@example.com', 'buddy2@example.com']);
  118. *
  119. * @example
  120. * // To return all open chats, call the method without any parameters::
  121. * const models = await api.chats.get();
  122. *
  123. */
  124. async get (jids, attrs={}, create=false) {
  125. await api.waitUntil('chatBoxesFetched');
  126. /** @param {string} jid */
  127. async function _get (jid) {
  128. let model = await api.chatboxes.get(jid);
  129. if (!model && create) {
  130. model = await api.chatboxes.create(jid, attrs, _converse.exports.ChatBox);
  131. } else {
  132. model = (model && model.get('type') === PRIVATE_CHAT_TYPE) ? model : null;
  133. if (model && Object.keys(attrs).length) {
  134. model.save(attrs);
  135. }
  136. }
  137. return model;
  138. }
  139. if (jids === undefined) {
  140. const chats = await api.chatboxes.get();
  141. return chats.filter(c => (c.get('type') === PRIVATE_CHAT_TYPE));
  142. } else if (typeof jids === 'string') {
  143. return _get(jids);
  144. }
  145. return Promise.all(jids.map(jid => _get(jid)));
  146. }
  147. }
  148. }