First attempt. Has a lag issue due to the async-clear :(

pull/21833/head
Michael Telatynski 2020-01-21 16:50:04 +00:00
parent 060938379a
commit b34fe45518
3 changed files with 44 additions and 12 deletions

View File

@ -81,6 +81,8 @@ class Command {
} }
run(roomId, args) { run(roomId, args) {
// if it has no runFn then its an ignored/nop command (autocomplete only) e.g `/me`
if (!this.runFn) return;
return this.runFn.bind(this)(roomId, args); return this.runFn.bind(this)(roomId, args);
} }
@ -918,12 +920,12 @@ export function processCommandInput(roomId, input) {
input = input.replace(/\s+$/, ''); input = input.replace(/\s+$/, '');
if (input[0] !== '/') return null; // not a command if (input[0] !== '/') return null; // not a command
const bits = input.match(/^(\S+?)( +((.|\n)*))?$/); const bits = input.match(/^(\S+?)(?: +((.|\n)*))?$/);
let cmd; let cmd;
let args; let args;
if (bits) { if (bits) {
cmd = bits[1].substring(1).toLowerCase(); cmd = bits[1].substring(1).toLowerCase();
args = bits[3]; args = bits[2];
} else { } else {
cmd = input; cmd = input;
} }
@ -932,11 +934,8 @@ export function processCommandInput(roomId, input) {
cmd = aliases[cmd]; cmd = aliases[cmd];
} }
if (CommandMap[cmd]) { if (CommandMap[cmd]) {
// if it has no runFn then its an ignored/nop command (autocomplete only) e.g `/me`
if (!CommandMap[cmd].runFn) return null;
return CommandMap[cmd].run(roomId, args); return CommandMap[cmd].run(roomId, args);
} else {
return reject(_t('Unrecognised command:') + ' ' + input);
} }
return null;
// return reject(_t('Unrecognised command:') + ' ' + input);
} }

View File

@ -43,6 +43,9 @@ import ContentMessages from '../../../ContentMessages';
import {Key} from "../../../Keyboard"; import {Key} from "../../../Keyboard";
import MatrixClientContext from "../../../contexts/MatrixClientContext"; import MatrixClientContext from "../../../contexts/MatrixClientContext";
const SEND_ANYWAY = Symbol("send-anyway");
const UNKNOWN_CMD = Symbol("unknown-cmd");
function addReplyToMessageContent(content, repliedToEvent, permalinkCreator) { function addReplyToMessageContent(content, repliedToEvent, permalinkCreator) {
const replyContent = ReplyThread.makeReplyMixIn(repliedToEvent); const replyContent = ReplyThread.makeReplyMixIn(repliedToEvent);
Object.assign(content, replyContent); Object.assign(content, replyContent);
@ -194,7 +197,12 @@ export default class SendMessageComposer extends React.Component {
return false; return false;
} }
async _runSlashCommand() { /**
* Parses and executes current input as a Slash Command
* @returns {Promise<Symbol|void>} UNKNOWN_CMD if the command is not known,
* SEND_ANYWAY if the input should be sent as message instead
*/
async _tryRunSlashCommand() {
const commandText = this.model.parts.reduce((text, part) => { const commandText = this.model.parts.reduce((text, part) => {
// use mxid to textify user pills in a command // use mxid to textify user pills in a command
if (part.type === "user-pill") { if (part.type === "user-pill") {
@ -236,16 +244,38 @@ export default class SendMessageComposer extends React.Component {
} else { } else {
console.log("Command success."); console.log("Command success.");
} }
} else {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
// unknown command, ask the user if they meant to send it as a message
const {finished} = Modal.createTrackedDialog("Unknown command", "", QuestionDialog, {
title: _t("Unknown Command"),
description: _t("Unrecognised command: ") + commandText,
button: _t('Send as message'),
danger: true,
});
const [sendAnyway] = await finished;
return sendAnyway ? SEND_ANYWAY : UNKNOWN_CMD;
} }
} }
_sendMessage() { async _sendMessage() {
if (this.model.isEmpty) { if (this.model.isEmpty) {
return; return;
} }
let shouldSend = true;
if (!containsEmote(this.model) && this._isSlashCommand()) { if (!containsEmote(this.model) && this._isSlashCommand()) {
this._runSlashCommand(); const resp = await this._tryRunSlashCommand();
} else { if (resp === UNKNOWN_CMD) {
// unknown command, bail to let the user modify it
return;
}
shouldSend = resp === SEND_ANYWAY;
}
if (shouldSend) {
const isReply = !!RoomViewStore.getQuotingEvent(); const isReply = !!RoomViewStore.getQuotingEvent();
const {roomId} = this.props.room; const {roomId} = this.props.room;
const content = createMessageContent(this.model, this.props.permalinkCreator); const content = createMessageContent(this.model, this.props.permalinkCreator);
@ -259,6 +289,7 @@ export default class SendMessageComposer extends React.Component {
}); });
} }
} }
this.sendHistoryManager.save(this.model); this.sendHistoryManager.save(this.model);
// clear composer // clear composer
this.model.reset([]); this.model.reset([]);

View File

@ -200,7 +200,6 @@
"Sends the given message coloured as a rainbow": "Sends the given message coloured as a rainbow", "Sends the given message coloured as a rainbow": "Sends the given message coloured as a rainbow",
"Sends the given emote coloured as a rainbow": "Sends the given emote coloured as a rainbow", "Sends the given emote coloured as a rainbow": "Sends the given emote coloured as a rainbow",
"Displays list of commands with usages and descriptions": "Displays list of commands with usages and descriptions", "Displays list of commands with usages and descriptions": "Displays list of commands with usages and descriptions",
"Unrecognised command:": "Unrecognised command:",
"Reason": "Reason", "Reason": "Reason",
"%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s accepted the invitation for %(displayName)s.", "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s accepted the invitation for %(displayName)s.",
"%(targetName)s accepted an invitation.": "%(targetName)s accepted an invitation.", "%(targetName)s accepted an invitation.": "%(targetName)s accepted an invitation.",
@ -1077,6 +1076,9 @@
"Server error": "Server error", "Server error": "Server error",
"Command error": "Command error", "Command error": "Command error",
"Server unavailable, overloaded, or something else went wrong.": "Server unavailable, overloaded, or something else went wrong.", "Server unavailable, overloaded, or something else went wrong.": "Server unavailable, overloaded, or something else went wrong.",
"Unknown Command": "Unknown Command",
"Unrecognised command: ": "Unrecognised command: ",
"Send as message": "Send as message",
"Failed to connect to integration manager": "Failed to connect to integration manager", "Failed to connect to integration manager": "Failed to connect to integration manager",
"You don't currently have any stickerpacks enabled": "You don't currently have any stickerpacks enabled", "You don't currently have any stickerpacks enabled": "You don't currently have any stickerpacks enabled",
"Add some now": "Add some now", "Add some now": "Add some now",