ChatGPT-Next-Web/app/command.ts

76 lines
1.8 KiB
TypeScript
Raw Normal View History

2023-07-05 15:19:54 +00:00
import { useEffect } from "react";
import { useSearchParams } from "react-router-dom";
2023-06-24 15:38:11 +00:00
import Locale from "./locales";
type Command = (param: string) => void;
interface Commands {
fill?: Command;
submit?: Command;
mask?: Command;
code?: Command;
settings?: Command;
}
export function useCommand(commands: Commands = {}) {
const [searchParams, setSearchParams] = useSearchParams();
2023-07-05 15:19:54 +00:00
useEffect(() => {
let shouldUpdate = false;
searchParams.forEach((param, name) => {
const commandName = name as keyof Commands;
if (typeof commands[commandName] === "function") {
commands[commandName]!(param);
searchParams.delete(name);
shouldUpdate = true;
}
});
2023-07-05 15:19:54 +00:00
if (shouldUpdate) {
setSearchParams(searchParams);
}
2023-07-05 15:19:54 +00:00
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [searchParams, commands]);
}
2023-06-24 15:38:11 +00:00
interface ChatCommands {
new?: Command;
newm?: Command;
next?: Command;
prev?: Command;
clear?: Command;
del?: Command;
}
export const ChatCommandPrefix = ":";
export function useChatCommand(commands: ChatCommands = {}) {
function extract(userInput: string) {
return (
userInput.startsWith(ChatCommandPrefix) ? userInput.slice(1) : userInput
) as keyof ChatCommands;
}
function search(userInput: string) {
const input = extract(userInput);
const desc = Locale.Chat.Commands;
return Object.keys(commands)
.filter((c) => c.startsWith(input))
.map((c) => ({
title: desc[c as keyof ChatCommands],
content: ChatCommandPrefix + c,
}));
}
function match(userInput: string) {
const command = extract(userInput);
const matched = typeof commands[command] === "function";
return {
matched,
invoke: () => matched && commands[command]!(userInput),
};
}
return { match, search };
}