contactview.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import { Model } from '@converse/skeletor';
  2. import { _converse, converse, api } from '@converse/headless';
  3. import { CustomElement } from 'shared/components/element.js';
  4. import tplRequestingContact from './templates/requesting_contact.js';
  5. import tplRosterItem from './templates/roster_item.js';
  6. import tplUnsavedContact from './templates/unsaved_contact.js';
  7. import { __ } from 'i18n';
  8. import { blockContact, removeContact } from './utils.js';
  9. const { Strophe } = converse.env;
  10. export default class RosterContact extends CustomElement {
  11. static get properties() {
  12. return {
  13. model: { type: Object },
  14. };
  15. }
  16. constructor() {
  17. super();
  18. this.model = null;
  19. }
  20. initialize() {
  21. this.listenTo(this.model, 'change', () => this.requestUpdate());
  22. this.listenTo(this.model, 'highlight', () => this.requestUpdate());
  23. this.listenTo(this.model, 'vcard:add', () => this.requestUpdate());
  24. this.listenTo(this.model, 'vcard:change', () => this.requestUpdate());
  25. this.listenTo(this.model, 'presenceChanged', () => this.requestUpdate());
  26. }
  27. render() {
  28. if (this.model.get('requesting') === true) {
  29. return tplRequestingContact(this);
  30. } else if (this.model.get('subscription') === 'none') {
  31. return tplUnsavedContact(this);
  32. } else {
  33. return tplRosterItem(this);
  34. }
  35. }
  36. /**
  37. * @param {MouseEvent} ev
  38. */
  39. openChat(ev) {
  40. ev?.preventDefault?.();
  41. api.chats.open(this.model.get('jid'), {}, true);
  42. }
  43. /**
  44. * @param {MouseEvent} ev
  45. */
  46. addContact(ev) {
  47. ev?.preventDefault?.();
  48. api.modal.show('converse-add-contact-modal', { model: new Model() }, ev);
  49. }
  50. /**
  51. * @param {MouseEvent} ev
  52. */
  53. async removeContact(ev) {
  54. ev?.preventDefault?.();
  55. // TODO: ask user whether they want to unauthorize the contact's
  56. // presence request as well.
  57. await removeContact(this.model);
  58. }
  59. /**
  60. * @param {MouseEvent} ev
  61. */
  62. async blockContact(ev) {
  63. ev?.preventDefault?.();
  64. await blockContact(this.model);
  65. }
  66. /**
  67. * @param {MouseEvent} ev
  68. */
  69. async acceptRequest(ev) {
  70. ev?.preventDefault?.();
  71. api.modal.show(
  72. 'converse-accept-contact-request-modal',
  73. { model: new Model(), contact: this.model },
  74. ev
  75. );
  76. }
  77. /**
  78. * @param {MouseEvent} ev
  79. */
  80. async declineRequest(ev) {
  81. ev?.preventDefault?.();
  82. const domain = _converse.session.get('domain');
  83. const blocking_supported = await api.disco.supports(Strophe.NS.BLOCKING, domain);
  84. const result = await api.confirm(
  85. __('Decline contact request'),
  86. [__('Are you sure you want to decline this contact request?')],
  87. blocking_supported
  88. ? [
  89. {
  90. label: __('Block this user from sending you further messages'),
  91. name: 'block',
  92. type: 'checkbox',
  93. },
  94. ]
  95. : []
  96. );
  97. if (result) {
  98. const chat = await api.chats.get(this.model.get('jid'));
  99. chat?.close();
  100. this.model.unauthorize();
  101. if (blocking_supported && Array.isArray(result)) {
  102. const should_block = result.find((i) => i.name === 'block')?.value === 'on';
  103. if (should_block) {
  104. api.blocklist.add(this.model.get('jid'));
  105. }
  106. }
  107. this.model.destroy();
  108. }
  109. return this;
  110. }
  111. }
  112. api.elements.define('converse-roster-contact', RosterContact);