diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index d60434cf97..aac42b6740 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -914,7 +914,7 @@ export const Commands = [ // Command definitions for autocompletion ONLY: // /me is special because its not handled by SlashCommands.js and is instead done inside the Composer classes new Command({ - command: 'me', + command: "me", args: '', description: _td('Displays action'), category: CommandCategories.messages, @@ -931,16 +931,7 @@ Commands.forEach(cmd => { }); }); - -/** - * 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} input The raw text input by the user. - * @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. - * Returns null if the input didn't match a command. - */ -export function getCommand(roomId, input) { +export function parseCommandString(input) { // trim any trailing whitespace, as it can confuse the parser for // IRC-style commands input = input.replace(/\s+$/, ''); @@ -956,6 +947,20 @@ export function getCommand(roomId, input) { cmd = input; } + return {cmd, args}; +} + +/** + * 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} input The raw text input by the user. + * @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. + * Returns null if the input didn't match a command. + */ +export function getCommand(roomId, input) { + const {cmd, args} = parseCommandString(input); + if (CommandMap.has(cmd)) { return () => CommandMap.get(cmd).run(roomId, args, cmd); } diff --git a/src/components/views/rooms/BasicMessageComposer.js b/src/components/views/rooms/BasicMessageComposer.js index e3cffd59f8..bbfc2780e8 100644 --- a/src/components/views/rooms/BasicMessageComposer.js +++ b/src/components/views/rooms/BasicMessageComposer.js @@ -39,6 +39,7 @@ import EMOTICON_REGEX from 'emojibase-regex/emoticon'; import * as sdk from '../../../index'; import {Key} from "../../../Keyboard"; import {EMOTICON_TO_EMOJI} from "../../../emoji"; +import {CommandCategories, CommandMap, parseCommandString} from "../../../SlashCommands"; const REGEX_EMOTICON_WHITESPACE = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX.source + ')\\s$'); @@ -162,7 +163,16 @@ export default class BasicMessageEditor extends React.Component { } this.setState({autoComplete: this.props.model.autoComplete}); this.historyManager.tryPush(this.props.model, selection, inputType, diff); - TypingStore.sharedInstance().setSelfTyping(this.props.room.roomId, !this.props.model.isEmpty); + + let isTyping = !this.props.model.isEmpty; + // If the user is entering a command, only consider them typing if it is one which sends a message into the room + if (isTyping && this.props.model.parts[0].type === "command") { + const {cmd} = parseCommandString(this.props.model.parts[0].text); + if (CommandMap.get(cmd).category !== CommandCategories.messages) { + isTyping = false; + } + } + TypingStore.sharedInstance().setSelfTyping(this.props.room.roomId, isTyping); if (this.props.onChange) { this.props.onChange();