re-arrange to split the async task into two and only wait on the user-blocking one

pull/21833/head
Michael Telatynski 2020-01-21 16:57:07 +00:00
parent b34fe45518
commit 9f7df33bc3
2 changed files with 52 additions and 58 deletions

View File

@ -907,14 +907,14 @@ const aliases = {
/** /**
* Process the given text for /commands and perform them. * Process the given text for /commands and return a bound method to perform them.
* @param {string} roomId The room in which the command was performed. * @param {string} roomId The room in which the command was performed.
* @param {string} input The raw text input by the user. * @param {string} input The raw text input by the user.
* @return {Object|null} An object with the property 'error' if there was an error * @return {null|function(): Object} Function returning an object with the property 'error' if there was an error
* processing the command, or 'promise' if a request was sent out. * processing the command, or 'promise' if a request was sent out.
* Returns null if the input didn't match a command. * Returns null if the input didn't match a command.
*/ */
export function processCommandInput(roomId, input) { export function getCommand(roomId, input) {
// trim any trailing whitespace, as it can confuse the parser for // trim any trailing whitespace, as it can confuse the parser for
// IRC-style commands // IRC-style commands
input = input.replace(/\s+$/, ''); input = input.replace(/\s+$/, '');
@ -934,8 +934,6 @@ export function processCommandInput(roomId, input) {
cmd = aliases[cmd]; cmd = aliases[cmd];
} }
if (CommandMap[cmd]) { if (CommandMap[cmd]) {
return CommandMap[cmd].run(roomId, args); return () => CommandMap[cmd].run(roomId, args);
} }
return null;
// return reject(_t('Unrecognised command:') + ' ' + input);
} }

View File

@ -35,7 +35,7 @@ import ReplyThread from "../elements/ReplyThread";
import {parseEvent} from '../../../editor/deserialize'; import {parseEvent} from '../../../editor/deserialize';
import {findEditableEvent} from '../../../utils/EventUtils'; import {findEditableEvent} from '../../../utils/EventUtils';
import SendHistoryManager from "../../../SendHistoryManager"; import SendHistoryManager from "../../../SendHistoryManager";
import {processCommandInput} from '../../../SlashCommands'; import {getCommand} from '../../../SlashCommands';
import * as sdk from '../../../index'; import * as sdk from '../../../index';
import Modal from '../../../Modal'; import Modal from '../../../Modal';
import {_t, _td} from '../../../languageHandler'; import {_t, _td} from '../../../languageHandler';
@ -197,12 +197,7 @@ export default class SendMessageComposer extends React.Component {
return false; return false;
} }
/** _getSlashCommand() {
* 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") {
@ -210,9 +205,11 @@ export default class SendMessageComposer extends React.Component {
} }
return text + part.text; return text + part.text;
}, ""); }, "");
const cmd = processCommandInput(this.props.room.roomId, commandText); return [getCommand(this.props.room.roomId, commandText), commandText];
}
if (cmd) { async _runSlashCommand(fn) {
const cmd = fn();
let error = cmd.error; let error = cmd.error;
if (cmd.promise) { if (cmd.promise) {
try { try {
@ -244,18 +241,6 @@ 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;
}
} }
async _sendMessage() { async _sendMessage() {
@ -266,13 +251,24 @@ export default class SendMessageComposer extends React.Component {
let shouldSend = true; let shouldSend = true;
if (!containsEmote(this.model) && this._isSlashCommand()) { if (!containsEmote(this.model) && this._isSlashCommand()) {
const resp = await this._tryRunSlashCommand(); const [cmd, commandText] = this._getSlashCommand();
if (resp === UNKNOWN_CMD) { if (cmd) {
// unknown command, bail to let the user modify it shouldSend = false;
return; this._runSlashCommand(cmd);
} else {
// ask the user if their unknown command should be sent as a message instead
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;
// if !sendAnyway bail to let the user edit the composer and try again
if (!sendAnyway) return;
} }
shouldSend = resp === SEND_ANYWAY;
} }
if (shouldSend) { if (shouldSend) {