mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2024-12-15 09:40:34 +08:00
80 lines
1.9 KiB
TypeScript
80 lines
1.9 KiB
TypeScript
import { useEffect } from "react";
|
||
import { useSearchParams } from "react-router-dom";
|
||
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();
|
||
|
||
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;
|
||
}
|
||
});
|
||
|
||
if (shouldUpdate) {
|
||
setSearchParams(searchParams);
|
||
}
|
||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||
}, [searchParams, commands]);
|
||
}
|
||
|
||
interface ChatCommands {
|
||
new?: Command;
|
||
newm?: Command;
|
||
next?: Command;
|
||
prev?: Command;
|
||
clear?: Command;
|
||
fork?: Command;
|
||
del?: Command;
|
||
}
|
||
|
||
// Compatible with Chinese colon character ":"
|
||
export const ChatCommandPrefix = /^[::]/;
|
||
|
||
export function useChatCommand(commands: ChatCommands = {}) {
|
||
function extract(userInput: string) {
|
||
const match = userInput.match(ChatCommandPrefix);
|
||
if (match) {
|
||
return userInput.slice(1) as keyof ChatCommands;
|
||
}
|
||
return 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: ":" + 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 };
|
||
}
|