model-with-contact.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import { getOpenPromise } from '@converse/openpromise';
  2. import { Strophe } from 'strophe.js';
  3. import _converse from './_converse.js';
  4. import api from './api/index.js';
  5. /**
  6. * @template {import('./types').ModelExtender} T
  7. * @param {T} BaseModel
  8. */
  9. export default function ModelWithContact(BaseModel) {
  10. return class ModelWithContact extends BaseModel {
  11. /**
  12. * @typedef {import('../plugins/roster/contact').default} RosterContact
  13. * @typedef {import('./_converse.js').XMPPStatus} XMPPStatus
  14. */
  15. initialize() {
  16. super.initialize();
  17. this.rosterContactAdded = getOpenPromise();
  18. /**
  19. * @public
  20. * @type {RosterContact|XMPPStatus}
  21. */
  22. this.contact = null;
  23. }
  24. /**
  25. * @param {string} jid
  26. */
  27. async setModelContact(jid) {
  28. if (this.contact?.get('jid') === jid) return;
  29. const { session, state } = _converse;
  30. let contact;
  31. if (Strophe.getBareJidFromJid(jid) === session.get('bare_jid')) {
  32. contact = state.xmppstatus;
  33. } else {
  34. contact = await api.contacts.get(jid);
  35. if (!contact && !(await api.blocklist.get()).get(jid)) {
  36. await api.contacts.add({ jid, subscription: 'none' }, false, false);
  37. }
  38. }
  39. if (contact) {
  40. this.contact = contact;
  41. this.set('nickname', contact.get('nickname'));
  42. this.listenTo(this.contact, 'vcard:add', (changed) => {
  43. this.trigger('contact:change', changed);
  44. });
  45. this.listenTo(this.contact, 'change', (changed) => {
  46. if (changed.nickname) {
  47. this.set('nickname', changed.nickname);
  48. }
  49. this.trigger('contact:change', changed);
  50. });
  51. this.rosterContactAdded.resolve();
  52. this.trigger('contactAdded', this.contact);
  53. }
  54. }
  55. };
  56. }