diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index 15798ae3b1..7ebdc4ee3b 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -118,7 +118,7 @@ export class Command { run(roomId: string, args: string, cmd: string) { // if it has no runFn then its an ignored/nop command (autocomplete only) e.g `/me` - if (!this.runFn) return; + if (!this.runFn) return reject(_t("Command error")); return this.runFn.bind(this)(roomId, args, cmd); } diff --git a/src/editor/serialize.ts b/src/editor/serialize.ts index 4d0b8cd03a..40038114d4 100644 --- a/src/editor/serialize.ts +++ b/src/editor/serialize.ts @@ -62,16 +62,20 @@ export function textSerialize(model: EditorModel) { } export function containsEmote(model: EditorModel) { - return startsWith(model, "/me "); + return startsWith(model, "/me ", true); } -export function startsWith(model: EditorModel, prefix: string) { +export function startsWith(model: EditorModel, prefix: string, caseInsensitive = false) { const firstPart = model.parts[0]; // part type will be "plain" while editing, // and "command" while composing a message. - return firstPart && - (firstPart.type === "plain" || firstPart.type === "command") && - firstPart.text.startsWith(prefix); + let text = firstPart && firstPart.text; + if (caseInsensitive) { + prefix = prefix.toLowerCase(); + text = text.toLowerCase(); + } + + return firstPart && (firstPart.type === "plain" || firstPart.type === "command") && text.startsWith(prefix); } export function stripEmoteCommand(model: EditorModel) {