2023-07-05 15:19:54 +00:00
|
|
|
import { useEffect } from "react";
|
2023-05-08 16:39:00 +00:00
|
|
|
import { useSearchParams } from "react-router-dom";
|
2023-06-24 15:38:11 +00:00
|
|
|
import Locale from "./locales";
|
2023-05-08 16:39:00 +00:00
|
|
|
|
|
|
|
type Command = (param: string) => void;
|
|
|
|
interface Commands {
|
|
|
|
fill?: Command;
|
|
|
|
submit?: Command;
|
|
|
|
mask?: 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-05-08 16:39:00 +00:00
|
|
|
|
2023-07-05 15:19:54 +00:00
|
|
|
if (shouldUpdate) {
|
|
|
|
setSearchParams(searchParams);
|
2023-05-08 16:39:00 +00:00
|
|
|
}
|
2023-07-05 15:19:54 +00:00
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
}, [searchParams, commands]);
|
2023-05-08 16:39:00 +00:00
|
|
|
}
|
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 };
|
|
|
|
}
|