Some light chat views refactoring

- Move `showModeratorToolsModal` method from view to utils
- Move `getNicknameRequiredTemplate` method from view to utils
- Move common `close` code to base class
This commit is contained in:
JC Brand 2021-05-07 10:14:33 +02:00
parent fdc81fa4ea
commit 18e3b618b4
6 changed files with 75 additions and 85 deletions

View File

@ -133,26 +133,11 @@ export default class ChatView extends BaseChatView {
}
}
async close (ev) {
ev?.preventDefault?.();
close (ev) {
if (_converse.router.history.getFragment() === 'converse/chat?jid=' + this.model.get('jid')) {
_converse.router.navigate('');
}
if (api.connection.connected()) {
// Immediately sending the chat state, because the
// model is going to be destroyed afterwards.
this.model.setChatState(_converse.INACTIVE);
this.model.sendChatState();
}
await this.model.close(ev);
/**
* Triggered once a chatbox has been closed.
* @event _converse#chatBoxClosed
* @type { _converse.ChatBoxView | _converse.ChatRoomView }
* @example _converse.api.listen.on('chatBoxClosed', view => { ... });
*/
api.trigger('chatBoxClosed', this);
return this;
return super.close(ev);
}
afterShown () {

View File

@ -6,7 +6,11 @@ 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';
import {
getHeadingDropdownItem,
getHeadingStandaloneButton,
showModeratorToolsModal
} from 'plugins/chatview/utils.js';
import './styles/muc-head.scss';
@ -61,10 +65,6 @@ export default class MUCHeading extends ChatHeading {
this.model.session.set('view', converse.MUC.VIEWS.CONFIG);
}
showModeratorToolsModal () {
_converse.chatboxviews.get(this.getAttribute('jid'))?.showModeratorToolsModal();
}
destroy () {
_converse.chatboxviews.get(this.getAttribute('jid'))?.destroy();
}
@ -127,7 +127,7 @@ export default class MUCHeading extends ChatHeading {
buttons.push({
'i18n_text': __('Moderate'),
'i18n_title': __('Moderate this groupchat'),
'handler': () => this.showModeratorToolsModal(),
'handler': () => showModeratorToolsModal(this.model),
'a_class': 'moderate-chatroom-button',
'icon_class': 'fa-user-cog',
'name': 'moderate'

View File

@ -3,41 +3,38 @@ import log from "@converse/headless/log";
import tpl_moderator_tools_modal from "../templates/moderator-tools.js";
import { AFFILIATIONS, ROLES } from "@converse/headless/plugins/muc/index.js";
import { __ } from 'i18n';
import { api, converse } from "@converse/headless/core";
import { _converse, api, converse } from "@converse/headless/core";
import { getAffiliationList, setAffiliation } from '@converse/headless/plugins/muc/affiliations/utils.js'
const { Strophe, sizzle } = converse.env;
const u = converse.env.utils;
let _converse;
export default BootstrapModal.extend({
const ModeratorToolsModal = BootstrapModal.extend({
id: "converse-modtools-modal",
persistent: true,
initialize (attrs) {
_converse = attrs._converse;
this.chatroomview = attrs.chatroomview;
this.muc = attrs.muc;
BootstrapModal.prototype.initialize.apply(this, arguments);
this.affiliations_filter = '';
this.roles_filter = '';
this.listenTo(this.model, 'change:role', () => {
this.users_with_role = this.chatroomview.model.getOccupantsWithRole(this.model.get('role'));
this.users_with_role = this.muc.getOccupantsWithRole(this.model.get('role'));
this.render();
});
this.listenTo(this.model, 'change:affiliation', async () => {
this.loading_users_with_affiliation = true;
this.users_with_affiliation = null;
this.render();
const chatroom = this.chatroomview.model;
const affiliation = this.model.get('affiliation');
if (this.shouldFetchAffiliationsList()) {
const muc_jid = chatroom.get('jid');
const muc_jid = this.muc.get('jid');
this.users_with_affiliation = await getAffiliationList(affiliation, muc_jid);
} else {
this.users_with_affiliation = chatroom.getOccupantsWithAffiliation(affiliation);
this.users_with_affiliation = this.muc.getOccupantsWithAffiliation(affiliation);
}
this.loading_users_with_affiliation = false;
this.render();
@ -45,7 +42,7 @@ export default BootstrapModal.extend({
},
toHTML () {
const occupant = this.chatroomview.model.occupants.findWhere({'jid': _converse.bare_jid});
const occupant = this.muc.occupants.findWhere({'jid': _converse.bare_jid});
return tpl_moderator_tools_modal(Object.assign(this.model.toJSON(), {
'affiliations_filter': this.affiliations_filter,
'assignAffiliation': ev => this.assignAffiliation(ev),
@ -100,7 +97,7 @@ export default BootstrapModal.extend({
if (affiliation === 'none') {
return false;
}
const chatroom = this.chatroomview.model;
const chatroom = this.muc;
const auto_fetched_affs = chatroom.occupants.getAutoFetchedAffiliationLists();
if (auto_fetched_affs.includes(affiliation)) {
return false;
@ -159,7 +156,7 @@ export default BootstrapModal.extend({
'reason': data.get('reason')
}
const current_affiliation = this.model.get('affiliation');
const muc_jid = this.chatroomview.model.get('jid');
const muc_jid = this.muc.get('jid');
try {
await setAffiliation(affiliation, muc_jid, [attrs]);
} catch (e) {
@ -174,7 +171,7 @@ export default BootstrapModal.extend({
return;
}
this.alert(__('Affiliation changed'), 'primary');
await this.chatroomview.model.occupants.fetchMembers()
await this.muc.occupants.fetchMembers()
this.model.set({'affiliation': null}, {'silent': true});
this.model.set({'affiliation': current_affiliation});
},
@ -183,11 +180,11 @@ export default BootstrapModal.extend({
ev.stopPropagation();
ev.preventDefault();
const data = new FormData(ev.target);
const occupant = this.chatroomview.model.getOccupant(data.get('jid') || data.get('nick'));
const occupant = this.muc.getOccupant(data.get('jid') || data.get('nick'));
const role = data.get('role');
const reason = data.get('reason');
const current_role = this.model.get('role');
this.chatroomview.model.setRole(occupant, role, reason,
this.muc.setRole(occupant, role, reason,
() => {
this.alert(__('Role changed'), 'primary');
this.model.set({'role': null}, {'silent': true});
@ -206,3 +203,5 @@ export default BootstrapModal.extend({
);
}
});
export default ModeratorToolsModal;

View File

@ -1,18 +1,11 @@
import BaseChatView from 'shared/chat/baseview.js';
import ModeratorToolsModal from './modals/moderator-tools.js';
import log from '@converse/headless/log';
import tpl_muc from './templates/muc.js';
import { Model } from '@converse/skeletor/src/model.js';
import { __ } from 'i18n';
import { _converse, api, converse } from '@converse/headless/core';
import { html, render } from "lit";
import { render } from "lit";
/**
* Mixin which turns a ChatBoxView into a ChatRoomView
* @mixin
* @namespace _converse.ChatRoomView
* @memberOf _converse
*/
export default class MUCView extends BaseChatView {
length = 300
is_chatroom = true
@ -23,6 +16,8 @@ export default class MUCView extends BaseChatView {
_converse.chatboxviews.add(jid, this);
this.initDebounced();
this.setAttribute('id', this.model.get('box_id'));
this.listenTo(_converse, 'windowStateChanged', this.onWindowStateChanged);
this.listenTo(this.model, 'change:composing_spoiler', this.renderMessageForm);
this.listenTo(this.model, 'change:hidden', () => this.afterShown());
@ -50,31 +45,10 @@ export default class MUCView extends BaseChatView {
}
render () {
this.setAttribute('id', this.model.get('box_id'));
render(
tpl_muc({
'getNicknameRequiredTemplate': () => this.getNicknameRequiredTemplate(),
'model': this.model,
}),
this
);
render(tpl_muc({ 'model': this.model }), this);
!this.model.get('hidden') && this.show();
}
showModeratorToolsModal (affiliation) {
if (!this.model.verifyRoles(['moderator'])) {
return;
}
let modal = api.modal.get(ModeratorToolsModal.id);
if (modal) {
modal.model.set('affiliation', affiliation);
} else {
const model = new Model({ 'affiliation': affiliation });
modal = api.modal.create(ModeratorToolsModal, { model, _converse, 'chatroomview': this });
}
modal.show();
}
/**
* Callback method that gets called after the chat has become visible.
* @private
@ -88,15 +62,15 @@ export default class MUCView extends BaseChatView {
}
/**
* Closes this chat box, which implies leaving the groupchat as well.
* Closes this chat, which implies leaving the MUC as well.
* @private
* @method _converse.ChatRoomView#close
*/
close () {
close (ev) {
if (_converse.router.history.getFragment() === 'converse/room?jid=' + this.model.get('jid')) {
_converse.router.navigate('');
}
return _converse.ChatBoxView.prototype.close.apply(this, arguments);
return super.close(ev);
}
async destroy () {
@ -130,15 +104,6 @@ export default class MUCView extends BaseChatView {
}
}
getNicknameRequiredTemplate () {
const jid = this.model.get('jid');
if (api.settings.get('muc_show_logs_before_join')) {
return html`<converse-muc-chatarea jid="${jid}"></converse-muc-chatarea>`;
} else {
return html`<converse-muc-nickname-form jid="${jid}"></converse-muc-nickname-form>`;
}
}
updateAfterTransition () {
const conn_status = this.model.session.get('connection_status');
if (conn_status === converse.ROOMSTATUS.CONNECTING) {

View File

@ -1,5 +1,7 @@
import ModeratorToolsModal from './modals/moderator-tools.js';
import log from "@converse/headless/log";
import tpl_spinner from 'templates/spinner.js';
import { Model } from '@converse/skeletor/src/model.js';
import { __ } from 'i18n';
import { _converse, api, converse } from "@converse/headless/core";
import { html } from "lit";
@ -68,6 +70,14 @@ export function fetchAndSetMUCDomain (controlboxview) {
}
}
export function getNicknameRequiredTemplate (model) {
const jid = model.get('jid');
if (api.settings.get('muc_show_logs_before_join')) {
return html`<converse-muc-chatarea jid="${jid}"></converse-muc-chatarea>`;
} else {
return html`<converse-muc-nickname-form jid="${jid}"></converse-muc-nickname-form>`;
}
}
export function getChatRoomBodyTemplate (o) {
const view = o.model.session.get('view');
@ -84,7 +94,7 @@ export function getChatRoomBodyTemplate (o) {
${ conn_status == RS.PASSWORD_REQUIRED ? html`<converse-muc-password-form class="muc-form-container" jid="${jid}"></converse-muc-password-form>` : '' }
${ conn_status == RS.ENTERED ? html`<converse-muc-chatarea jid="${jid}"></converse-muc-chatarea>` : '' }
${ conn_status == RS.CONNECTING ? tpl_spinner() : '' }
${ conn_status == RS.NICKNAME_REQUIRED ? o.getNicknameRequiredTemplate() : '' }
${ conn_status == RS.NICKNAME_REQUIRED ? getNicknameRequiredTemplate(o.model) : '' }
${ conn_status == RS.DISCONNECTED ? html`<converse-muc-disconnected jid="${jid}"></converse-muc-disconnected>` : '' }
${ conn_status == RS.BANNED ? html`<converse-muc-disconnected jid="${jid}"></converse-muc-disconnected>` : '' }
${ conn_status == RS.DESTROYED ? html`<converse-muc-destroyed jid="${jid}"></converse-muc-destroyed>` : '' }
@ -92,7 +102,6 @@ export function getChatRoomBodyTemplate (o) {
}
}
export function getAutoCompleteListItem (text, input) {
input = input.trim();
const element = document.createElement('li');
@ -232,6 +241,21 @@ function verifyAndSetAffiliation (muc, command, args, required_affiliations) {
}
function showModeratorToolsModal (muc, affiliation) {
if (!muc.verifyRoles(['moderator'])) {
return;
}
let modal = api.modal.get(ModeratorToolsModal.id);
if (modal) {
modal.model.set({ affiliation });
} else {
const model = new Model({ affiliation });
modal = api.modal.create(ModeratorToolsModal, { model, muc });
}
modal.show();
}
export function parseMessageForMUCCommands (muc, text) {
if (
api.settings.get('muc_disable_slash_commands') &&
@ -259,8 +283,7 @@ export function parseMessageForMUCCommands (muc, text) {
break;
}
case 'modtools': {
const chatview = _converse.chatboxviews.get(muc.get('jid'));
chatview.showModeratorToolsModal(args);
showModeratorToolsModal(muc, args);
break;
}
case 'deop': {

View File

@ -50,6 +50,24 @@ export default class BaseChatView extends ElementView {
this.afterShown();
}
async close (ev) {
ev?.preventDefault?.();
if (api.connection.connected()) {
// Immediately sending the chat state, because the
// model is going to be destroyed afterwards.
this.model.setChatState(_converse.INACTIVE);
this.model.sendChatState();
}
await this.model.close(ev);
/**
* Triggered once a chatbox has been closed.
* @event _converse#chatBoxClosed
* @type { _converse.ChatBoxView | _converse.ChatRoomView }
* @example _converse.api.listen.on('chatBoxClosed', view => { ... });
*/
api.trigger('chatBoxClosed', this);
}
emitBlurred (ev) {
if (this.contains(document.activeElement) || this.contains(ev.relatedTarget)) {
// Something else in this chatbox is still focused