Fix slash commands not being enabled in certain cases (#11090)
* Fix slash commands not being enabled in certain cases * Fix import cycle
This commit is contained in:
parent
9c48487d85
commit
6486255f54
4 changed files with 16 additions and 10 deletions
|
@ -69,6 +69,7 @@ import { htmlSerializeFromMdIfNeeded } from "./editor/serialize";
|
|||
import { leaveRoomBehaviour } from "./utils/leave-behaviour";
|
||||
import { isLocalRoom } from "./utils/localRoom/isLocalRoom";
|
||||
import { SdkContextClass } from "./contexts/SDKContext";
|
||||
import { MatrixClientPeg } from "./MatrixClientPeg";
|
||||
|
||||
// XXX: workaround for https://github.com/microsoft/TypeScript/issues/31816
|
||||
interface HTMLInputEvent extends Event {
|
||||
|
@ -122,7 +123,7 @@ interface ICommandOpts {
|
|||
runFn?: RunFn;
|
||||
category: string;
|
||||
hideCompletionAfterSpace?: boolean;
|
||||
isEnabled?(matrixClient?: MatrixClient): boolean;
|
||||
isEnabled?(matrixClient: MatrixClient | null): boolean;
|
||||
renderingTypes?: TimelineRenderingType[];
|
||||
}
|
||||
|
||||
|
@ -136,7 +137,7 @@ export class Command {
|
|||
public readonly hideCompletionAfterSpace: boolean;
|
||||
public readonly renderingTypes?: TimelineRenderingType[];
|
||||
public readonly analyticsName?: SlashCommandEvent["command"];
|
||||
private readonly _isEnabled?: (matrixClient?: MatrixClient) => boolean;
|
||||
private readonly _isEnabled?: (matrixClient: MatrixClient | null) => boolean;
|
||||
|
||||
public constructor(opts: ICommandOpts) {
|
||||
this.command = opts.command;
|
||||
|
@ -189,7 +190,7 @@ export class Command {
|
|||
return _t("Usage") + ": " + this.getCommandWithArgs();
|
||||
}
|
||||
|
||||
public isEnabled(cli?: MatrixClient): boolean {
|
||||
public isEnabled(cli: MatrixClient | null): boolean {
|
||||
return this._isEnabled?.(cli) ?? true;
|
||||
}
|
||||
}
|
||||
|
@ -206,7 +207,7 @@ function successSync(value: any): RunResult {
|
|||
return success(Promise.resolve(value));
|
||||
}
|
||||
|
||||
const isCurrentLocalRoom = (cli?: MatrixClient): boolean => {
|
||||
const isCurrentLocalRoom = (cli: MatrixClient | null): boolean => {
|
||||
const roomId = SdkContextClass.instance.roomViewStore.getRoomId();
|
||||
if (!roomId) return false;
|
||||
const room = cli?.getRoom(roomId);
|
||||
|
@ -214,7 +215,7 @@ const isCurrentLocalRoom = (cli?: MatrixClient): boolean => {
|
|||
return isLocalRoom(room);
|
||||
};
|
||||
|
||||
const canAffectPowerlevels = (cli?: MatrixClient): boolean => {
|
||||
const canAffectPowerlevels = (cli: MatrixClient | null): boolean => {
|
||||
const roomId = SdkContextClass.instance.roomViewStore.getRoomId();
|
||||
if (!cli || !roomId) return false;
|
||||
const room = cli?.getRoom(roomId);
|
||||
|
@ -1425,7 +1426,7 @@ interface ICmd {
|
|||
export function getCommand(input: string): ICmd {
|
||||
const { cmd, args } = parseCommandString(input);
|
||||
|
||||
if (cmd && CommandMap.has(cmd) && CommandMap.get(cmd)!.isEnabled()) {
|
||||
if (cmd && CommandMap.has(cmd) && CommandMap.get(cmd)!.isEnabled(MatrixClientPeg.get())) {
|
||||
return {
|
||||
cmd: CommandMap.get(cmd),
|
||||
args,
|
||||
|
|
|
@ -27,6 +27,7 @@ import { TextualCompletion } from "./Components";
|
|||
import { ICompletion, ISelectionRange } from "./Autocompleter";
|
||||
import { Command, Commands, CommandMap } from "../SlashCommands";
|
||||
import { TimelineRenderingType } from "../contexts/RoomContext";
|
||||
import { MatrixClientPeg } from "../MatrixClientPeg";
|
||||
|
||||
const COMMAND_RE = /(^\/\w*)(?: .*)?/g;
|
||||
|
||||
|
@ -51,12 +52,14 @@ export default class CommandProvider extends AutocompleteProvider {
|
|||
const { command, range } = this.getCurrentCommand(query, selection);
|
||||
if (!command) return [];
|
||||
|
||||
const cli = MatrixClientPeg.get();
|
||||
|
||||
let matches: Command[] = [];
|
||||
// check if the full match differs from the first word (i.e. returns false if the command has args)
|
||||
if (command[0] !== command[1]) {
|
||||
// The input looks like a command with arguments, perform exact match
|
||||
const name = command[1].slice(1); // strip leading `/`
|
||||
if (CommandMap.has(name) && CommandMap.get(name)!.isEnabled()) {
|
||||
if (CommandMap.has(name) && CommandMap.get(name)!.isEnabled(cli)) {
|
||||
// some commands, namely `me` don't suit having the usage shown whilst typing their arguments
|
||||
if (CommandMap.get(name)!.hideCompletionAfterSpace) return [];
|
||||
matches = [CommandMap.get(name)!];
|
||||
|
@ -75,7 +78,7 @@ export default class CommandProvider extends AutocompleteProvider {
|
|||
return matches
|
||||
.filter((cmd) => {
|
||||
const display = !cmd.renderingTypes || cmd.renderingTypes.includes(this.renderingType);
|
||||
return cmd.isEnabled() && display;
|
||||
return cmd.isEnabled(cli) && display;
|
||||
})
|
||||
.map((result) => {
|
||||
let completion = result.getCommand() + " ";
|
||||
|
|
|
@ -19,6 +19,7 @@ import React from "react";
|
|||
import { _t } from "../../../languageHandler";
|
||||
import { Command, CommandCategories, Commands } from "../../../SlashCommands";
|
||||
import InfoDialog from "./InfoDialog";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
|
||||
interface IProps {
|
||||
onFinished(): void;
|
||||
|
@ -27,7 +28,7 @@ interface IProps {
|
|||
const SlashCommandHelpDialog: React.FC<IProps> = ({ onFinished }) => {
|
||||
const categories: Record<string, Command[]> = {};
|
||||
Commands.forEach((cmd) => {
|
||||
if (!cmd.isEnabled()) return;
|
||||
if (!cmd.isEnabled(MatrixClientPeg.get())) return;
|
||||
if (!categories[cmd.category]) {
|
||||
categories[cmd.category] = [];
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ import { ALTERNATE_KEY_NAME, KeyBindingAction } from "../../../accessibility/Key
|
|||
import { _t } from "../../../languageHandler";
|
||||
import { linkify } from "../../../linkify-matrix";
|
||||
import { SdkContextClass } from "../../../contexts/SDKContext";
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
|
||||
// matches emoticons which follow the start of a line or whitespace
|
||||
const REGEX_EMOTICON_WHITESPACE = new RegExp("(?:^|\\s)(" + EMOTICON_REGEX.source + ")\\s|:^$");
|
||||
|
@ -268,7 +269,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
|
|||
if (isTyping && this.props.model.parts[0].type === "command") {
|
||||
const { cmd } = parseCommandString(this.props.model.parts[0].text);
|
||||
const command = CommandMap.get(cmd!);
|
||||
if (!command?.isEnabled() || command.category !== CommandCategories.messages) {
|
||||
if (!command?.isEnabled(MatrixClientPeg.get()) || command.category !== CommandCategories.messages) {
|
||||
isTyping = false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue