|
@@ -3,29 +3,9 @@ import debounce from 'lodash/debounce';
|
|
import tpl_muc_bottom_panel from './templates/muc-bottom-panel.js';
|
|
import tpl_muc_bottom_panel from './templates/muc-bottom-panel.js';
|
|
import { __ } from 'i18n';
|
|
import { __ } from 'i18n';
|
|
import { _converse, api, converse } from "@converse/headless/core";
|
|
import { _converse, api, converse } from "@converse/headless/core";
|
|
-import { getAutoCompleteListItem } from './utils.js';
|
|
|
|
|
|
+import { getAutoCompleteListItem, parseMessageForMUCCommands } from './utils.js';
|
|
import { render } from 'lit-html';
|
|
import { render } from 'lit-html';
|
|
|
|
|
|
-const { Strophe, $pres } = converse.env;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-const COMMAND_TO_AFFILIATION = {
|
|
|
|
- 'admin': 'admin',
|
|
|
|
- 'ban': 'outcast',
|
|
|
|
- 'member': 'member',
|
|
|
|
- 'owner': 'owner',
|
|
|
|
- 'revoke': 'none'
|
|
|
|
-};
|
|
|
|
-const COMMAND_TO_ROLE = {
|
|
|
|
- 'deop': 'participant',
|
|
|
|
- 'kick': 'none',
|
|
|
|
- 'mute': 'visitor',
|
|
|
|
- 'op': 'moderator',
|
|
|
|
- 'voice': 'participant'
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-const u = converse.env.utils;
|
|
|
|
-
|
|
|
|
|
|
|
|
export default class MUCBottomPanel extends BottomPanel {
|
|
export default class MUCBottomPanel extends BottomPanel {
|
|
|
|
|
|
@@ -117,194 +97,8 @@ export default class MUCBottomPanel extends BottomPanel {
|
|
super.onKeyUp(ev);
|
|
super.onKeyUp(ev);
|
|
}
|
|
}
|
|
|
|
|
|
- setRole (command, args, required_affiliations = [], required_roles = []) {
|
|
|
|
- /* Check that a command to change a groupchat user's role or
|
|
|
|
- * affiliation has anough arguments.
|
|
|
|
- */
|
|
|
|
- const role = COMMAND_TO_ROLE[command];
|
|
|
|
- if (!role) {
|
|
|
|
- throw Error(`ChatRoomView#setRole called with invalid command: ${command}`);
|
|
|
|
- }
|
|
|
|
- if (!this.model.verifyAffiliations(required_affiliations) || !this.model.verifyRoles(required_roles)) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- if (!this.model.validateRoleOrAffiliationChangeArgs(command, args)) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- const nick_or_jid = this.model.getNickOrJIDFromCommandArgs(args);
|
|
|
|
- if (!nick_or_jid) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- const reason = args.split(nick_or_jid, 2)[1].trim();
|
|
|
|
- // We're guaranteed to have an occupant due to getNickOrJIDFromCommandArgs
|
|
|
|
- const occupant = this.model.getOccupant(nick_or_jid);
|
|
|
|
- this.model.setRole(occupant, role, reason, undefined, this.model.onCommandError.bind(this));
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- setAffiliation (command, args, required_affiliations) {
|
|
|
|
- const affiliation = COMMAND_TO_AFFILIATION[command];
|
|
|
|
- if (!affiliation) {
|
|
|
|
- throw Error(`ChatRoomView#setAffiliation called with invalid command: ${command}`);
|
|
|
|
- }
|
|
|
|
- if (!this.model.verifyAffiliations(required_affiliations)) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- if (!this.model.validateRoleOrAffiliationChangeArgs(command, args)) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- const nick_or_jid = this.model.getNickOrJIDFromCommandArgs(args);
|
|
|
|
- if (!nick_or_jid) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- let jid;
|
|
|
|
- const reason = args.split(nick_or_jid, 2)[1].trim();
|
|
|
|
- const occupant = this.model.getOccupant(nick_or_jid);
|
|
|
|
- if (occupant) {
|
|
|
|
- jid = occupant.get('jid');
|
|
|
|
- } else {
|
|
|
|
- if (u.isValidJID(nick_or_jid)) {
|
|
|
|
- jid = nick_or_jid;
|
|
|
|
- } else {
|
|
|
|
- const message = __(
|
|
|
|
- "Couldn't find a participant with that nickname. " + 'They might have left the groupchat.'
|
|
|
|
- );
|
|
|
|
- this.model.createMessage({ message, 'type': 'error' });
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- const attrs = { jid, reason };
|
|
|
|
- if (occupant && api.settings.get('auto_register_muc_nickname')) {
|
|
|
|
- attrs['nick'] = occupant.get('nick');
|
|
|
|
- }
|
|
|
|
- this.model
|
|
|
|
- .setAffiliation(affiliation, [attrs])
|
|
|
|
- .then(() => this.model.occupants.fetchMembers())
|
|
|
|
- .catch(err => this.model.onCommandError(err));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
parseMessageForCommands (text) {
|
|
parseMessageForCommands (text) {
|
|
- if (
|
|
|
|
- api.settings.get('muc_disable_slash_commands') &&
|
|
|
|
- !Array.isArray(api.settings.get('muc_disable_slash_commands'))
|
|
|
|
- ) {
|
|
|
|
- return super.parseMessageForCommands(text);
|
|
|
|
- }
|
|
|
|
- text = text.replace(/^\s*/, '');
|
|
|
|
- const command = (text.match(/^\/([a-zA-Z]*) ?/) || ['']).pop().toLowerCase();
|
|
|
|
- if (!command) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- const args = text.slice(('/' + command).length + 1).trim();
|
|
|
|
- if (!this.model.getAllowedCommands().includes(command)) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- switch (command) {
|
|
|
|
- case 'admin': {
|
|
|
|
- this.setAffiliation(command, args, ['owner']);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 'ban': {
|
|
|
|
- this.setAffiliation(command, args, ['admin', 'owner']);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 'modtools': {
|
|
|
|
- const chatview = _converse.chatboxviews.get(this.getAttribute('jid'));
|
|
|
|
- chatview.showModeratorToolsModal(args);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 'deop': {
|
|
|
|
- // FIXME: /deop only applies to setting a moderators
|
|
|
|
- // role to "participant" (which only admin/owner can
|
|
|
|
- // do). Moderators can however set non-moderator's role
|
|
|
|
- // to participant (e.g. visitor => participant).
|
|
|
|
- // Currently we don't distinguish between these two
|
|
|
|
- // cases.
|
|
|
|
- this.setRole(command, args, ['admin', 'owner']);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 'destroy': {
|
|
|
|
- if (!this.model.verifyAffiliations(['owner'])) {
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- const chatview = _converse.chatboxviews.get(this.getAttribute('jid'));
|
|
|
|
- chatview.destroy().catch(e => this.model.onCommandError(e));
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 'help': {
|
|
|
|
- this.model.set({ 'show_help_messages': true });
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 'kick': {
|
|
|
|
- this.setRole(command, args, [], ['moderator']);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 'mute': {
|
|
|
|
- this.setRole(command, args, [], ['moderator']);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 'member': {
|
|
|
|
- this.setAffiliation(command, args, ['admin', 'owner']);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 'nick': {
|
|
|
|
- if (!this.model.verifyRoles(['visitor', 'participant', 'moderator'])) {
|
|
|
|
- break;
|
|
|
|
- } else if (args.length === 0) {
|
|
|
|
- // e.g. Your nickname is "coolguy69"
|
|
|
|
- const message = __('Your nickname is "%1$s"', this.model.get('nick'));
|
|
|
|
- this.model.createMessage({ message, 'type': 'error' });
|
|
|
|
- } else {
|
|
|
|
- const jid = Strophe.getBareJidFromJid(this.model.get('jid'));
|
|
|
|
- api.send(
|
|
|
|
- $pres({
|
|
|
|
- from: _converse.connection.jid,
|
|
|
|
- to: `${jid}/${args}`,
|
|
|
|
- id: u.getUniqueId()
|
|
|
|
- }).tree()
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 'owner':
|
|
|
|
- this.setAffiliation(command, args, ['owner']);
|
|
|
|
- break;
|
|
|
|
- case 'op': {
|
|
|
|
- this.setRole(command, args, ['admin', 'owner']);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 'register': {
|
|
|
|
- if (args.length > 1) {
|
|
|
|
- this.model.createMessage({
|
|
|
|
- 'message': __('Error: invalid number of arguments'),
|
|
|
|
- 'type': 'error'
|
|
|
|
- });
|
|
|
|
- } else {
|
|
|
|
- this.model.registerNickname().then(err_msg => {
|
|
|
|
- err_msg && this.model.createMessage({ 'message': err_msg, 'type': 'error' });
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 'revoke': {
|
|
|
|
- this.setAffiliation(command, args, ['admin', 'owner']);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 'topic':
|
|
|
|
- case 'subject':
|
|
|
|
- this.model.setSubject(args);
|
|
|
|
- break;
|
|
|
|
- case 'voice': {
|
|
|
|
- this.setRole(command, args, [], ['moderator']);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- default:
|
|
|
|
- return super.parseMessageForCommands(text);
|
|
|
|
- }
|
|
|
|
- return true;
|
|
|
|
|
|
+ return parseMessageForMUCCommands(this.model, text);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|