Move methods to utils
So that they can also be used independently of the components
This commit is contained in:
parent
d335a11119
commit
d8cab006c8
|
@ -911,7 +911,7 @@ describe("Chatboxes", function () {
|
||||||
|
|
||||||
describe("Special Messages", function () {
|
describe("Special Messages", function () {
|
||||||
|
|
||||||
it("'/clear' can be used to clear messages in a conversation",
|
fit("'/clear' can be used to clear messages in a conversation",
|
||||||
mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
|
mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
|
||||||
|
|
||||||
await mock.waitForRoster(_converse, 'current');
|
await mock.waitForRoster(_converse, 'current');
|
||||||
|
@ -925,28 +925,21 @@ describe("Chatboxes", function () {
|
||||||
await mock.sendMessage(view, message);
|
await mock.sendMessage(view, message);
|
||||||
|
|
||||||
expect(view.model.messages.length === 1).toBeTruthy();
|
expect(view.model.messages.length === 1).toBeTruthy();
|
||||||
let stored_messages = await view.model.messages.browserStorage.findAll();
|
const stored_messages = await view.model.messages.browserStorage.findAll();
|
||||||
expect(stored_messages.length).toBe(1);
|
expect(stored_messages.length).toBe(1);
|
||||||
await u.waitUntil(() => view.querySelector('.chat-msg'));
|
await u.waitUntil(() => view.querySelector('.chat-msg'));
|
||||||
|
|
||||||
message = '/clear';
|
message = '/clear';
|
||||||
const bottom_panel = view.querySelector('converse-chat-bottom-panel');
|
const bottom_panel = view.querySelector('converse-chat-bottom-panel');
|
||||||
spyOn(bottom_panel, 'clearMessages').and.callThrough();
|
spyOn(window, 'confirm').and.callFake(() => true);
|
||||||
spyOn(window, 'confirm').and.callFake(function () {
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
view.querySelector('.chat-textarea').value = message;
|
view.querySelector('.chat-textarea').value = message;
|
||||||
bottom_panel.onKeyDown({
|
bottom_panel.onKeyDown({
|
||||||
target: view.querySelector('textarea.chat-textarea'),
|
target: view.querySelector('textarea.chat-textarea'),
|
||||||
preventDefault: function preventDefault () {},
|
preventDefault: function preventDefault () {},
|
||||||
keyCode: 13
|
keyCode: 13
|
||||||
});
|
});
|
||||||
expect(bottom_panel.clearMessages.calls.all().length).toBe(1);
|
expect(window.confirm).toHaveBeenCalledWith('Are you sure you want to clear the messages from this conversation?');
|
||||||
await bottom_panel.clearMessages.calls.all()[0].returnValue;
|
await u.waitUntil(() => view.model.messages.length === 0);
|
||||||
expect(window.confirm).toHaveBeenCalled();
|
|
||||||
expect(view.model.messages.length, 0); // The messages must be removed from the chatbox
|
|
||||||
stored_messages = await view.model.messages.browserStorage.findAll();
|
|
||||||
expect(stored_messages.length).toBe(0);
|
|
||||||
expect(_converse.api.trigger.calls.count(), 1);
|
expect(_converse.api.trigger.calls.count(), 1);
|
||||||
expect(_converse.api.trigger.calls.mostRecent().args, ['messageSend', message]);
|
expect(_converse.api.trigger.calls.mostRecent().args, ['messageSend', message]);
|
||||||
done();
|
done();
|
||||||
|
|
|
@ -3294,13 +3294,13 @@ describe("Groupchats", function () {
|
||||||
const textarea = await u.waitUntil(() => view.querySelector('.chat-textarea'));
|
const textarea = await u.waitUntil(() => view.querySelector('.chat-textarea'));
|
||||||
textarea.value = '/clear';
|
textarea.value = '/clear';
|
||||||
const bottom_panel = view.querySelector('converse-muc-bottom-panel');
|
const bottom_panel = view.querySelector('converse-muc-bottom-panel');
|
||||||
spyOn(bottom_panel, 'clearMessages');
|
spyOn(window, 'confirm').and.callFake(() => false);
|
||||||
bottom_panel.onKeyDown({
|
bottom_panel.onKeyDown({
|
||||||
target: textarea,
|
target: textarea,
|
||||||
preventDefault: function preventDefault () {},
|
preventDefault: function preventDefault () {},
|
||||||
keyCode: 13
|
keyCode: 13
|
||||||
});
|
});
|
||||||
expect(bottom_panel.clearMessages).toHaveBeenCalled();
|
expect(window.confirm).toHaveBeenCalledWith('Are you sure you want to clear the messages from this conversation?');
|
||||||
done();
|
done();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { ElementView } from '@converse/skeletor/src/element.js';
|
||||||
import { __ } from 'i18n';
|
import { __ } from 'i18n';
|
||||||
import { _converse, api, converse } from "@converse/headless/core";
|
import { _converse, api, converse } from "@converse/headless/core";
|
||||||
import { html, render } from 'lit-html';
|
import { html, render } from 'lit-html';
|
||||||
|
import { clearMessages, parseMessageForCommands } from './utils.js';
|
||||||
|
|
||||||
const { u } = converse.env;
|
const { u } = converse.env;
|
||||||
|
|
||||||
|
@ -109,29 +110,13 @@ export default class ChatBottomPanel extends ElementView {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
async clearMessages (ev) {
|
clearMessages (ev) {
|
||||||
ev?.preventDefault?.();
|
ev?.preventDefault?.();
|
||||||
const result = confirm(__('Are you sure you want to clear the messages from this conversation?'));
|
clearMessages(this.model);
|
||||||
if (result === true) {
|
|
||||||
await this.model.clearMessages();
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parseMessageForCommands (text) {
|
parseMessageForCommands (text) {
|
||||||
const match = text.replace(/^\s*/, '').match(/^\/(.*)\s*$/);
|
return parseMessageForCommands(this.model, text);
|
||||||
if (match) {
|
|
||||||
if (match[1] === 'clear') {
|
|
||||||
this.clearMessages();
|
|
||||||
return true;
|
|
||||||
} else if (match[1] === 'close') {
|
|
||||||
_converse.chatboxviews.get(this.getAttribute('jid'))?.close();
|
|
||||||
return true;
|
|
||||||
} else if (match[1] === 'help') {
|
|
||||||
this.model.set({ 'show_help_messages': true });
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async onFormSubmitted () {
|
async onFormSubmitted () {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { __ } from 'i18n';
|
||||||
|
import { _converse } from "@converse/headless/core";
|
||||||
import { html } from 'lit-html';
|
import { html } from 'lit-html';
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,3 +23,27 @@ export async function getHeadingStandaloneButton (promise_or_data) {
|
||||||
></a>
|
></a>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function clearMessages (chat) {
|
||||||
|
const result = confirm(__('Are you sure you want to clear the messages from this conversation?'));
|
||||||
|
if (result === true) {
|
||||||
|
await chat.clearMessages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function parseMessageForCommands (chat, text) {
|
||||||
|
const match = text.replace(/^\s*/, '').match(/^\/(.*)\s*$/);
|
||||||
|
if (match) {
|
||||||
|
if (match[1] === 'clear') {
|
||||||
|
clearMessages(chat);
|
||||||
|
return true;
|
||||||
|
} else if (match[1] === 'close') {
|
||||||
|
_converse.chatboxviews.get(chat.get('jid'))?.close();
|
||||||
|
return true;
|
||||||
|
} else if (match[1] === 'help') {
|
||||||
|
chat.set({ 'show_help_messages': true });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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 (
|
return parseMessageForMUCCommands(this.model, text);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,24 @@
|
||||||
import { _converse, api, converse } from "@converse/headless/core";
|
|
||||||
import log from "@converse/headless/log";
|
import log from "@converse/headless/log";
|
||||||
|
import { __ } from 'i18n';
|
||||||
|
import { _converse, api, converse } from "@converse/headless/core";
|
||||||
|
import { parseMessageForCommands } from 'plugins/chatview/utils.js';
|
||||||
|
|
||||||
const { Strophe, $iq, sizzle, u } = converse.env;
|
const { Strophe, $pres, $iq, sizzle, u } = 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'
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export function getAutoCompleteListItem (text, input) {
|
export function getAutoCompleteListItem (text, input) {
|
||||||
|
@ -75,3 +92,192 @@ export async function fetchCommandForm (command) {
|
||||||
command.fields = [];
|
command.fields = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function setRole (muc, command, args, required_affiliations = [], required_roles = []) {
|
||||||
|
const role = COMMAND_TO_ROLE[command];
|
||||||
|
if (!role) {
|
||||||
|
throw Error(`ChatRoomView#setRole called with invalid command: ${command}`);
|
||||||
|
}
|
||||||
|
if (!muc.verifyAffiliations(required_affiliations) || !muc.verifyRoles(required_roles)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!muc.validateRoleOrAffiliationChangeArgs(command, args)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const nick_or_jid = muc.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 = muc.getOccupant(nick_or_jid);
|
||||||
|
muc.setRole(occupant, role, reason, undefined, e => muc.onCommandError(e));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function setAffiliation (muc, command, args, required_affiliations) {
|
||||||
|
const affiliation = COMMAND_TO_AFFILIATION[command];
|
||||||
|
if (!affiliation) {
|
||||||
|
throw Error(`ChatRoomView#setAffiliation called with invalid command: ${command}`);
|
||||||
|
}
|
||||||
|
if (!muc.verifyAffiliations(required_affiliations)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!muc.validateRoleOrAffiliationChangeArgs(command, args)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const nick_or_jid = muc.getNickOrJIDFromCommandArgs(args);
|
||||||
|
if (!nick_or_jid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let jid;
|
||||||
|
const reason = args.split(nick_or_jid, 2)[1].trim();
|
||||||
|
const occupant = muc.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.'
|
||||||
|
);
|
||||||
|
muc.createMessage({ message, 'type': 'error' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const attrs = { jid, reason };
|
||||||
|
if (occupant && api.settings.get('auto_register_muc_nickname')) {
|
||||||
|
attrs['nick'] = occupant.get('nick');
|
||||||
|
}
|
||||||
|
muc
|
||||||
|
.setAffiliation(affiliation, [attrs])
|
||||||
|
.then(() => muc.occupants.fetchMembers())
|
||||||
|
.catch(err => muc.onCommandError(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function parseMessageForMUCCommands (muc, text) {
|
||||||
|
if (
|
||||||
|
api.settings.get('muc_disable_slash_commands') &&
|
||||||
|
!Array.isArray(api.settings.get('muc_disable_slash_commands'))
|
||||||
|
) {
|
||||||
|
return parseMessageForCommands(muc, 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 (!muc.getAllowedCommands().includes(command)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (command) {
|
||||||
|
case 'admin': {
|
||||||
|
setAffiliation(muc, command, args, ['owner']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'ban': {
|
||||||
|
setAffiliation(muc, command, args, ['admin', 'owner']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'modtools': {
|
||||||
|
const chatview = _converse.chatboxviews.get(muc.get('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.
|
||||||
|
setRole(muc, command, args, ['admin', 'owner']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'destroy': {
|
||||||
|
if (!muc.verifyAffiliations(['owner'])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const chatview = _converse.chatboxviews.get(muc.get('jid'));
|
||||||
|
chatview.destroy().catch(e => muc.onCommandError(e));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'help': {
|
||||||
|
muc.set({ 'show_help_messages': true });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'kick': {
|
||||||
|
setRole(muc, command, args, [], ['moderator']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'mute': {
|
||||||
|
setRole(muc, command, args, [], ['moderator']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'member': {
|
||||||
|
setAffiliation(muc, command, args, ['admin', 'owner']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'nick': {
|
||||||
|
if (!muc.verifyRoles(['visitor', 'participant', 'moderator'])) {
|
||||||
|
break;
|
||||||
|
} else if (args.length === 0) {
|
||||||
|
// e.g. Your nickname is "coolguy69"
|
||||||
|
const message = __('Your nickname is "%1$s"', muc.get('nick'));
|
||||||
|
muc.createMessage({ message, 'type': 'error' });
|
||||||
|
} else {
|
||||||
|
const jid = Strophe.getBareJidFromJid(muc.get('jid'));
|
||||||
|
api.send(
|
||||||
|
$pres({
|
||||||
|
from: _converse.connection.jid,
|
||||||
|
to: `${jid}/${args}`,
|
||||||
|
id: u.getUniqueId()
|
||||||
|
}).tree()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'owner':
|
||||||
|
setAffiliation(muc, command, args, ['owner']);
|
||||||
|
break;
|
||||||
|
case 'op': {
|
||||||
|
setRole(muc, command, args, ['admin', 'owner']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'register': {
|
||||||
|
if (args.length > 1) {
|
||||||
|
muc.createMessage({
|
||||||
|
'message': __('Error: invalid number of arguments'),
|
||||||
|
'type': 'error'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
muc.registerNickname().then(err_msg => {
|
||||||
|
err_msg && muc.createMessage({ 'message': err_msg, 'type': 'error' });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'revoke': {
|
||||||
|
setAffiliation(muc, command, args, ['admin', 'owner']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'topic':
|
||||||
|
case 'subject':
|
||||||
|
muc.setSubject(args);
|
||||||
|
break;
|
||||||
|
case 'voice': {
|
||||||
|
setRole(muc, command, args, [], ['moderator']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return parseMessageForCommands(muc, text);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user