Converse converse.js

Source: headless/plugins/vcard/api.js

  1. import log from "@converse/headless/log";
  2. import { _converse, api, converse } from "../../core.js";
  3. import { createStanza, getVCard } from './utils.js';
  4. const { dayjs, u } = converse.env;
  5. export default {
  6. /**
  7. * The XEP-0054 VCard API
  8. *
  9. * This API lets you access and update user VCards
  10. *
  11. * @namespace _converse.api.vcard
  12. * @memberOf _converse.api
  13. */
  14. vcard: {
  15. /**
  16. * Enables setting new values for a VCard.
  17. *
  18. * Sends out an IQ stanza to set the user's VCard and if
  19. * successful, it updates the {@link _converse.VCard}
  20. * for the passed in JID.
  21. *
  22. * @method _converse.api.vcard.set
  23. * @param { string } jid The JID for which the VCard should be set
  24. * @param { object } data A map of VCard keys and values
  25. * @example
  26. * let jid = _converse.bare_jid;
  27. * _converse.api.vcard.set( jid, {
  28. * 'fn': 'John Doe',
  29. * 'nickname': 'jdoe'
  30. * }).then(() => {
  31. * // Succes
  32. * }).catch((e) => {
  33. * // Failure, e is your error object
  34. * }).
  35. */
  36. async set (jid, data) {
  37. if (!jid) {
  38. throw Error("No jid provided for the VCard data");
  39. }
  40. const div = document.createElement('div');
  41. const vcard_el = u.toStanza(`
  42. <vCard xmlns="vcard-temp">
  43. <FN>${data.fn}</FN>
  44. <NICKNAME>${data.nickname}</NICKNAME>
  45. <URL>${data.url}</URL>
  46. <ROLE>${data.role}</ROLE>
  47. <EMAIL><INTERNET/><PREF/><USERID>${data.email}</USERID></EMAIL>
  48. <PHOTO>
  49. <TYPE>${data.image_type}</TYPE>
  50. <BINVAL>${data.image}</BINVAL>
  51. </PHOTO>
  52. </vCard>`, div);
  53. let result;
  54. try {
  55. result = await api.sendIQ(createStanza("set", jid, vcard_el));
  56. } catch (e) {
  57. throw (e);
  58. }
  59. await api.vcard.update(jid, true);
  60. return result;
  61. },
  62. /**
  63. * @method _converse.api.vcard.get
  64. * @param {Model|string} model Either a `Model` instance, or a string JID.
  65. * If a `Model` instance is passed in, then it must have either a `jid`
  66. * attribute or a `muc_jid` attribute.
  67. * @param { boolean } [force] A boolean indicating whether the vcard should be
  68. * fetched from the server even if it's been fetched before.
  69. * @returns {promise} A Promise which resolves with the VCard data for a particular JID or for
  70. * a `Model` instance which represents an entity with a JID (such as a roster contact,
  71. * chat or chatroom occupant).
  72. *
  73. * @example
  74. * const { api } = _converse;
  75. * api.waitUntil('rosterContactsFetched').then(() => {
  76. * api.vcard.get('someone@example.org').then(
  77. * (vcard) => {
  78. * // Do something with the vcard...
  79. * }
  80. * );
  81. * });
  82. */
  83. get (model, force) {
  84. if (typeof model === 'string') {
  85. return getVCard(model);
  86. }
  87. const error_date = model.get('vcard_error');
  88. const already_tried_today = error_date && dayjs(error_date).isSame(new Date(), "day");
  89. if (force || !model.get('vcard_updated') && !already_tried_today) {
  90. const jid = model.get('jid');
  91. if (!jid) {
  92. log.error("No JID to get vcard for");
  93. }
  94. return getVCard(jid);
  95. } else {
  96. return Promise.resolve({});
  97. }
  98. },
  99. /**
  100. * Fetches the VCard associated with a particular `Model` instance
  101. * (by using its `jid` or `muc_jid` attribute) and then updates the model with the
  102. * returned VCard data.
  103. *
  104. * @method _converse.api.vcard.update
  105. * @param { Model } model A `Model` instance
  106. * @param { boolean } [force] A boolean indicating whether the vcard should be
  107. * fetched again even if it's been fetched before.
  108. * @returns {promise} A promise which resolves once the update has completed.
  109. * @example
  110. * const { api } = _converse;
  111. * api.waitUntil('rosterContactsFetched').then(async () => {
  112. * const chatbox = await api.chats.get('someone@example.org');
  113. * api.vcard.update(chatbox);
  114. * });
  115. */
  116. async update (model, force) {
  117. const data = await this.get(model, force);
  118. model = typeof model === 'string' ? _converse.vcards.get(model) : model;
  119. if (!model) {
  120. log.error(`Could not find a VCard model for ${model}`);
  121. return;
  122. }
  123. if (Object.keys(data).length) {
  124. delete data['stanza']
  125. model.save(data);
  126. }
  127. }
  128. }
  129. }