192 lines
7.2 KiB
JavaScript
192 lines
7.2 KiB
JavaScript
|
import ChatHeading from 'plugins/chatview/heading.js';
|
||
|
import MUCInviteModal from 'modals/muc-invite.js';
|
||
|
import RoomDetailsModal from 'modals/muc-details.js';
|
||
|
import debounce from 'lodash/debounce';
|
||
|
import tpl_muc_head from './templates/muc_head.js';
|
||
|
import { Model } from '@converse/skeletor/src/model.js';
|
||
|
import { __ } from 'i18n';
|
||
|
import { _converse, api, converse } from "@converse/headless/core";
|
||
|
import { getHeadingDropdownItem, getHeadingStandaloneButton } from 'plugins/chatview/utils.js';
|
||
|
|
||
|
|
||
|
export default class MUCHeading extends ChatHeading {
|
||
|
|
||
|
async connectedCallback () {
|
||
|
super.connectedCallback();
|
||
|
this.model = _converse.chatboxes.get(this.getAttribute('jid'));
|
||
|
this.debouncedRender = debounce(this.render, 100);
|
||
|
this.listenTo(this.model, 'change', this.debouncedRender);
|
||
|
|
||
|
const user_settings = await _converse.api.user.settings.getModel();
|
||
|
this.listenTo(user_settings, 'change:mucs_with_hidden_subject', this.debouncedRender);
|
||
|
|
||
|
await this.model.initialized;
|
||
|
this.listenTo(this.model.features, 'change:open', this.debouncedRender);
|
||
|
this.model.occupants.forEach(o => this.onOccupantAdded(o));
|
||
|
this.listenTo(this.model.occupants, 'add', this.onOccupantAdded);
|
||
|
this.listenTo(this.model.occupants, 'change:affiliation', this.onOccupantAffiliationChanged);
|
||
|
this.render();
|
||
|
}
|
||
|
|
||
|
onOccupantAdded (occupant) {
|
||
|
if (occupant.get('jid') === _converse.bare_jid) {
|
||
|
this.debouncedRender();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
onOccupantAffiliationChanged (occupant) {
|
||
|
if (occupant.get('jid') === _converse.bare_jid) {
|
||
|
this.debouncedRender();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
showRoomDetailsModal (ev) {
|
||
|
ev.preventDefault();
|
||
|
api.modal.show(RoomDetailsModal, { 'model': this.model }, ev);
|
||
|
}
|
||
|
|
||
|
showInviteModal (ev) {
|
||
|
ev.preventDefault();
|
||
|
api.modal.show(MUCInviteModal, { 'model': new Model(), 'chatroomview': this }, ev);
|
||
|
}
|
||
|
|
||
|
toggleTopic (ev) {
|
||
|
ev?.preventDefault?.();
|
||
|
this.model.toggleSubjectHiddenState();
|
||
|
}
|
||
|
|
||
|
getAndRenderConfigurationForm () {
|
||
|
_converse.chatboxviews.get(this.getAttribute('jid'))?.getAndRenderConfigurationForm();
|
||
|
}
|
||
|
|
||
|
showModeratorToolsModal () {
|
||
|
_converse.chatboxviews.get(this.getAttribute('jid'))?.showModeratorToolsModal();
|
||
|
}
|
||
|
|
||
|
destroy () {
|
||
|
_converse.chatboxviews.get(this.getAttribute('jid'))?.destroy();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a list of objects which represent buttons for the groupchat header.
|
||
|
* @emits _converse#getHeadingButtons
|
||
|
*/
|
||
|
getHeadingButtons (subject_hidden) {
|
||
|
const buttons = [];
|
||
|
buttons.push({
|
||
|
'i18n_text': __('Details'),
|
||
|
'i18n_title': __('Show more information about this groupchat'),
|
||
|
'handler': 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': ev => this.getAndRenderConfigurationForm(ev),
|
||
|
'a_class': 'configure-chatroom-button',
|
||
|
'icon_class': 'fa-wrench',
|
||
|
'name': 'configure'
|
||
|
});
|
||
|
}
|
||
|
|
||
|
if (this.model.invitesAllowed()) {
|
||
|
buttons.push({
|
||
|
'i18n_text': __('Invite'),
|
||
|
'i18n_title': __('Invite someone to join this groupchat'),
|
||
|
'handler': ev => this.showInviteModal(ev),
|
||
|
'a_class': 'open-invite-modal',
|
||
|
'icon_class': 'fa-user-plus',
|
||
|
'name': 'invite'
|
||
|
});
|
||
|
}
|
||
|
|
||
|
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': ev => this.toggleTopic(ev),
|
||
|
'a_class': 'hide-topic',
|
||
|
'icon_class': 'fa-minus-square',
|
||
|
'name': 'toggle-topic'
|
||
|
});
|
||
|
}
|
||
|
|
||
|
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': () => this.showModeratorToolsModal(),
|
||
|
'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 chatview = _converse.chatboxviews.get(this.getAttribute('jid'));
|
||
|
if (chatview) {
|
||
|
return _converse.api.hook('getHeadingButtons', chatview, buttons);
|
||
|
} else {
|
||
|
return buttons; // Happens during tests
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the groupchat heading TemplateResult to be rendered.
|
||
|
*/
|
||
|
async generateHeadingTemplate () {
|
||
|
const subject_hidden = await this.model.isSubjectHidden();
|
||
|
const heading_btns = await this.getHeadingButtons(subject_hidden);
|
||
|
const standalone_btns = heading_btns.filter(b => b.standalone);
|
||
|
const dropdown_btns = heading_btns.filter(b => !b.standalone);
|
||
|
return tpl_muc_head(
|
||
|
Object.assign(this.model.toJSON(), {
|
||
|
_converse,
|
||
|
subject_hidden,
|
||
|
'dropdown_btns': dropdown_btns.map(b => getHeadingDropdownItem(b)),
|
||
|
'standalone_btns': standalone_btns.map(b => getHeadingStandaloneButton(b)),
|
||
|
'title': this.model.getDisplayName()
|
||
|
})
|
||
|
);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
api.elements.define('converse-muc-heading', MUCHeading);
|