Bot Command Tooltip: Fix sending wrong command
This commit is contained in:
parent
6d5625ce0c
commit
a219f67624
@ -4,6 +4,7 @@ import React, {
|
|||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
import { getActions, withGlobal } from '../../../global';
|
import { getActions, withGlobal } from '../../../global';
|
||||||
|
|
||||||
|
import type { Signal } from '../../../util/signals';
|
||||||
import type { ApiBotCommand, ApiUser } from '../../../api/types';
|
import type { ApiBotCommand, ApiUser } from '../../../api/types';
|
||||||
|
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
@ -20,6 +21,7 @@ export type OwnProps = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
withUsername?: boolean;
|
withUsername?: boolean;
|
||||||
botCommands?: ApiBotCommand[];
|
botCommands?: ApiBotCommand[];
|
||||||
|
getHtml: Signal<string>;
|
||||||
onClick: NoneToVoidFunction;
|
onClick: NoneToVoidFunction;
|
||||||
onClose: NoneToVoidFunction;
|
onClose: NoneToVoidFunction;
|
||||||
};
|
};
|
||||||
@ -33,6 +35,7 @@ const BotCommandTooltip: FC<OwnProps & StateProps> = ({
|
|||||||
isOpen,
|
isOpen,
|
||||||
withUsername,
|
withUsername,
|
||||||
botCommands,
|
botCommands,
|
||||||
|
getHtml,
|
||||||
onClick,
|
onClick,
|
||||||
onClose,
|
onClose,
|
||||||
}) => {
|
}) => {
|
||||||
@ -50,10 +53,20 @@ const BotCommandTooltip: FC<OwnProps & StateProps> = ({
|
|||||||
onClick();
|
onClick();
|
||||||
}, [onClick, sendBotCommand, usersById, withUsername]);
|
}, [onClick, sendBotCommand, usersById, withUsername]);
|
||||||
|
|
||||||
|
const handleSelect = useCallback((botCommand: ApiBotCommand) => {
|
||||||
|
// We need an additional check because tooltip is updated with throttling
|
||||||
|
if (!botCommand.command.startsWith(getHtml())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSendCommand(botCommand);
|
||||||
|
return true;
|
||||||
|
}, [getHtml, handleSendCommand]);
|
||||||
|
|
||||||
const selectedCommandIndex = useKeyboardNavigation({
|
const selectedCommandIndex = useKeyboardNavigation({
|
||||||
isActive: isOpen,
|
isActive: isOpen,
|
||||||
items: botCommands,
|
items: botCommands,
|
||||||
onSelect: handleSendCommand,
|
onSelect: handleSelect,
|
||||||
onClose,
|
onClose,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1267,6 +1267,7 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
isOpen={isBotCommandTooltipOpen}
|
isOpen={isBotCommandTooltipOpen}
|
||||||
withUsername={Boolean(chatBotCommands)}
|
withUsername={Boolean(chatBotCommands)}
|
||||||
botCommands={botTooltipCommands}
|
botCommands={botTooltipCommands}
|
||||||
|
getHtml={getHtml}
|
||||||
onClick={handleBotCommandSelect}
|
onClick={handleBotCommandSelect}
|
||||||
onClose={closeBotCommandTooltip}
|
onClose={closeBotCommandTooltip}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import useFlag from '../../../../hooks/useFlag';
|
|||||||
import useDerivedSignal from '../../../../hooks/useDerivedSignal';
|
import useDerivedSignal from '../../../../hooks/useDerivedSignal';
|
||||||
import { useThrottledResolver } from '../../../../hooks/useAsyncResolvers';
|
import { useThrottledResolver } from '../../../../hooks/useAsyncResolvers';
|
||||||
|
|
||||||
const RE_COMMAND = /^\/([\w@]{1,32}\s?)?/i;
|
const RE_COMMAND = /^\/([\w@]{1,32})?$/i;
|
||||||
|
|
||||||
const THROTTLE = 300;
|
const THROTTLE = 300;
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,7 @@ export function useKeyboardNavigation({
|
|||||||
noArrowNavigation?: boolean;
|
noArrowNavigation?: boolean;
|
||||||
items?: any[];
|
items?: any[];
|
||||||
shouldSelectOnTab?: boolean;
|
shouldSelectOnTab?: boolean;
|
||||||
onSelect: AnyToVoidFunction;
|
onSelect: (item: any) => void | boolean;
|
||||||
onClose: NoneToVoidFunction;
|
onClose: NoneToVoidFunction;
|
||||||
}) {
|
}) {
|
||||||
const [selectedItemIndex, setSelectedItemIndex] = useState(-1);
|
const [selectedItemIndex, setSelectedItemIndex] = useState(-1);
|
||||||
@ -42,10 +42,15 @@ export function useKeyboardNavigation({
|
|||||||
if (items && items.length && selectedItemIndex > -1) {
|
if (items && items.length && selectedItemIndex > -1) {
|
||||||
const item = items[selectedItemIndex];
|
const item = items[selectedItemIndex];
|
||||||
if (item) {
|
if (item) {
|
||||||
|
if (onSelect(item) === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
onSelect(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}, [items, onSelect, selectedItemIndex]);
|
}, [items, onSelect, selectedItemIndex]);
|
||||||
|
|
||||||
const isSelectionOutOfRange = !items || selectedItemIndex > items.length - 1;
|
const isSelectionOutOfRange = !items || selectedItemIndex > items.length - 1;
|
||||||
|
|||||||
@ -1,6 +1,14 @@
|
|||||||
type HandlerName = 'onEnter' | 'onBackspace' | 'onDelete' | 'onEsc' | 'onUp' | 'onDown' | 'onLeft' | 'onRight'
|
type HandlerName =
|
||||||
| 'onTab';
|
'onEnter'
|
||||||
type Handler = (e: KeyboardEvent) => void;
|
| 'onBackspace'
|
||||||
|
| 'onDelete'
|
||||||
|
| 'onEsc'
|
||||||
|
| 'onUp'
|
||||||
|
| 'onDown'
|
||||||
|
| 'onLeft'
|
||||||
|
| 'onRight'
|
||||||
|
| 'onTab';
|
||||||
|
type Handler = (e: KeyboardEvent) => void | boolean;
|
||||||
type CaptureOptions = Partial<Record<HandlerName, Handler>>;
|
type CaptureOptions = Partial<Record<HandlerName, Handler>>;
|
||||||
|
|
||||||
const keyToHandlerName: Record<string, HandlerName> = {
|
const keyToHandlerName: Record<string, HandlerName> = {
|
||||||
@ -64,10 +72,14 @@ function handleKeyDown(e: KeyboardEvent) {
|
|||||||
if (!length) {
|
if (!length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
const handler = handlers[handlerName][length - 1];
|
for (let i = length - 1; i >= 0; i--) {
|
||||||
handler!(e);
|
const handler = handlers[handlerName][i]!;
|
||||||
|
if (handler(e) !== false) {
|
||||||
|
e.stopPropagation();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function releaseKeyboardListener(options: CaptureOptions) {
|
function releaseKeyboardListener(options: CaptureOptions) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user