converse.js
Version:
Browser based XMPP chat client
224 lines (198 loc) • 7.97 kB
JavaScript
import { _converse, api, converse } from "@converse/headless";
import './modals/config.js';
import './modals/muc-details.js';
import './modals/nickname.js';
import { CustomElement } from 'shared/components/element.js';
import { __ } from 'i18n';
import { destroyMUC, showModeratorToolsModal } from './utils.js';
import tplMUCHead from './templates/muc-head.js';
import './styles/muc-head.scss';
export default class MUCHeading extends CustomElement {
/**
* @typedef {import('@converse/headless/types/plugins/muc/occupant').default} MUCOccupant
*/
async initialize () {
const { chatboxes } = _converse.state;
this.model = chatboxes.get(this.getAttribute('jid'));
this.listenTo(this.model, 'change', () => this.requestUpdate());
this.listenTo(this.model, 'vcard:add', () => this.requestUpdate());
this.listenTo(this.model, 'vcard:change', () => this.requestUpdate());
this.user_settings = await _converse.api.user.settings.getModel();
this.listenTo(this.user_settings, 'change:mucs_with_hidden_subject', () => this.requestUpdate());
await this.model.initialized;
const own_occupant = this.model.occupants.findOccupant({ jid: _converse.session.get('bare_jid') });
if (own_occupant) this.updateIfOwnOccupant(own_occupant);
this.listenTo(this.model.occupants, "add", this.updateIfOwnOccupant);
this.listenTo(this.model.occupants, "change:affiliation", this.updateIfOwnOccupant);
this.listenTo(this.model.occupants, "change:role", this.updateIfOwnOccupant);
this.listenTo(this.model.session, "change:connection_status", () => this.requestUpdate());
this.requestUpdate();
}
render () {
return this.model ? tplMUCHead(this) : '';
}
/**
* @param {MUCOccupant} occupant
*/
updateIfOwnOccupant (occupant) {
const bare_jid = _converse.session.get('bare_jid');
if (occupant.get('jid') === bare_jid) {
this.requestUpdate();
}
}
/**
* @param {Event} ev
*/
showRoomDetailsModal (ev) {
ev.preventDefault();
api.modal.show('converse-muc-details-modal', { model: this.model }, ev);
}
/**
* @param {Event} ev
*/
showNicknameModal (ev) {
ev.preventDefault();
api.modal.show('converse-muc-nickname-modal', { model: this.model }, ev);
}
/**
* @param {Event} ev
*/
toggleTopic (ev) {
ev?.preventDefault?.();
this.model.toggleSubjectHiddenState();
}
/**
* @param {Event} ev
*/
toggleOccupants (ev) {
ev?.preventDefault?.();
ev?.stopPropagation?.();
this.model.save({'hidden_occupants': !this.model.get('hidden_occupants')});
}
/**
* @param {Event} ev
*/
showConfigModal(ev) {
ev.preventDefault();
api.modal.show('converse-muc-config-modal', { model: this.model }, ev);
}
/**
* @param {Event} ev
*/
close (ev) {
ev.preventDefault();
this.model.close();
}
/**
* @param {Event} ev
*/
destroy (ev) {
ev.preventDefault();
destroyMUC(this.model);
}
/**
* Returns a list of objects which represent buttons for the groupchat header.
* @emits _converse#getHeadingButtons
*
* @param {boolean} subject_hidden
*/
getHeadingButtons (subject_hidden) {
const buttons = [];
buttons.push({
'i18n_text': __('Details'),
'i18n_title': __('Show more information about this groupchat'),
'handler': /** @param {Event} ev */(ev) => this.showRoomDetailsModal(ev),
'a_class': 'show-muc-details-modal',
'icon_class': 'fa-info-circle',
'name': 'details'
});
if (this.model.getOwnAffiliation() === 'owner') {
buttons.push({
'i18n_text': __('Configure'),
'i18n_title': __('Configure this groupchat'),
'handler': /** @param {Event} ev */(ev) => this.showConfigModal(ev),
'a_class': 'configure-chatroom-button',
'icon_class': 'fa-wrench',
'name': 'configure'
});
}
buttons.push({
'i18n_text': __('Nickname'),
'i18n_title': __("Change the nickname you're using in this groupchat"),
'handler': /** @param {Event} ev */(ev) => this.showNicknameModal(ev),
'a_class': 'open-nickname-modal',
'icon_class': 'fa-smile',
'name': 'nickname'
});
const subject = this.model.get('subject');
if (subject && subject.text) {
buttons.push({
'i18n_text': subject_hidden ? __('Show topic') : __('Hide topic'),
'i18n_title': subject_hidden
? __('Show the topic message in the heading')
: __('Hide the topic in the heading'),
'handler': /** @param {Event} ev */(ev) => this.toggleTopic(ev),
'a_class': 'hide-topic',
'icon_class': 'fa-minus-square',
'name': 'toggle-topic'
});
}
buttons.push({
'i18n_text': this.model.get('hidden_occupants') ? __('Show participants') : __('Hide participants'),
'i18n_title': this.model.get('hidden_occupants')
? __('Show the groupchat participants')
: __('Hide the groupchat participants'),
'handler': /** @param {Event} ev */(ev) => this.toggleOccupants(ev),
'icon_class': 'fa-users',
});
const conn_status = this.model.session.get('connection_status');
if (conn_status === converse.ROOMSTATUS.ENTERED) {
const allowed_commands = this.model.getAllowedCommands();
if (allowed_commands.includes('modtools')) {
buttons.push({
'i18n_text': __('Moderate'),
'i18n_title': __('Moderate this groupchat'),
'handler': () => showModeratorToolsModal(this.model),
'a_class': 'moderate-chatroom-button',
'icon_class': 'fa-user-cog',
'name': 'moderate'
});
}
if (allowed_commands.includes('destroy')) {
buttons.push({
'i18n_text': __('Destroy'),
'i18n_title': __('Remove this groupchat'),
'handler': (ev) => this.destroy(ev),
'a_class': 'destroy-chatroom-button',
'icon_class': 'fa-trash',
'name': 'destroy'
});
}
}
if (!api.settings.get('singleton')) {
buttons.push({
'i18n_text': __('Leave'),
'i18n_title': __('Leave and close this groupchat'),
'handler': async (ev) => {
ev.stopPropagation();
const messages = [__('Are you sure you want to leave this groupchat?')];
const result = await api.confirm(__('Confirm'), messages);
result && this.close(ev);
},
'a_class': 'close-chatbox-button',
'standalone': api.settings.get('view_mode') === 'overlayed',
'icon_class': 'fa-sign-out-alt',
'name': 'signout'
});
}
const { chatboxviews } = _converse.state;
const el = chatboxviews.get(this.getAttribute('jid'));
if (el) {
// This hook is described in src/plugins/chatview/heading.js
return _converse.api.hook('getHeadingButtons', el, buttons);
} else {
return Promise.resolve(buttons); // Happens during tests
}
}
}
api.elements.define('converse-muc-heading', MUCHeading);