improve plugin hotkey support (#426)

This commit is contained in:
Dornfeld Capital 2023-04-10 22:41:29 -05:00 committed by GitHub
parent da7463e901
commit 60288ad20a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 6 deletions

View File

@ -284,9 +284,16 @@ export const ChatInput = ({
</button>
{showPluginSelect && (
<div className="absolute left-0 bottom-14 bg-white dark:bg-[#343541]">
<div className="absolute left-0 bottom-14 rounded bg-white dark:bg-[#343541]">
<PluginSelect
plugin={plugin}
onKeyDown={(e: any) => {
if (e.key === 'Escape') {
e.preventDefault();
setShowPluginSelect(false);
textareaRef.current?.focus();
}
}}
onPluginChange={(plugin: Plugin) => {
setPlugin(plugin);
setShowPluginSelect(false);

View File

@ -7,13 +7,53 @@ import { Plugin, PluginList } from '@/types/plugin';
interface Props {
plugin: Plugin | null;
onPluginChange: (plugin: Plugin) => void;
onKeyDown: (e: React.KeyboardEvent<HTMLSelectElement>) => void;
}
export const PluginSelect: FC<Props> = ({ plugin, onPluginChange }) => {
export const PluginSelect: FC<Props> = ({
plugin,
onPluginChange,
onKeyDown,
}) => {
const { t } = useTranslation('chat');
const selectRef = useRef<HTMLSelectElement>(null);
const handleKeyDown = (e: React.KeyboardEvent<HTMLSelectElement>) => {
const selectElement = selectRef.current;
const optionCount = selectElement?.options.length || 0;
if (e.key === '/' && e.metaKey) {
e.preventDefault();
if (selectElement) {
selectElement.selectedIndex =
(selectElement.selectedIndex + 1) % optionCount;
selectElement.dispatchEvent(new Event('change'));
}
} else if (e.key === '/' && e.shiftKey && e.metaKey) {
e.preventDefault();
if (selectElement) {
selectElement.selectedIndex =
(selectElement.selectedIndex - 1 + optionCount) % optionCount;
selectElement.dispatchEvent(new Event('change'));
}
} else if (e.key === 'Enter') {
e.preventDefault();
if (selectElement) {
selectElement.dispatchEvent(new Event('change'));
}
onPluginChange(
PluginList.find(
(plugin) =>
plugin.name === selectElement?.selectedOptions[0].innerText,
) as Plugin,
);
} else {
onKeyDown(e);
}
};
useEffect(() => {
if (selectRef.current) {
selectRef.current.focus();
@ -22,7 +62,7 @@ export const PluginSelect: FC<Props> = ({ plugin, onPluginChange }) => {
return (
<div className="flex flex-col">
<div className="w-full rounded-lg border border-neutral-200 bg-transparent pr-2 text-neutral-900 dark:border-neutral-600 dark:text-white">
<div className="mb-1 w-full rounded border border-neutral-200 bg-transparent pr-2 text-neutral-900 dark:border-neutral-600 dark:text-white">
<select
ref={selectRef}
className="w-full cursor-pointer bg-transparent p-2"
@ -35,13 +75,16 @@ export const PluginSelect: FC<Props> = ({ plugin, onPluginChange }) => {
) as Plugin,
);
}}
onKeyDown={(e) => {
handleKeyDown(e);
}}
>
<option
key="none"
value=""
key="chatgpt"
value="chatgpt"
className="dark:bg-[#343541] dark:text-white"
>
Select Plugin
ChatGPT
</option>
{PluginList.map((plugin) => (