command.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import { useEffect } from "react";
  2. import { useSearchParams } from "react-router-dom";
  3. import Locale from "./locales";
  4. type Command = (param: string) => void;
  5. interface Commands {
  6. fill?: Command;
  7. submit?: Command;
  8. mask?: Command;
  9. }
  10. export function useCommand(commands: Commands = {}) {
  11. const [searchParams, setSearchParams] = useSearchParams();
  12. useEffect(() => {
  13. let shouldUpdate = false;
  14. searchParams.forEach((param, name) => {
  15. const commandName = name as keyof Commands;
  16. if (typeof commands[commandName] === "function") {
  17. commands[commandName]!(param);
  18. searchParams.delete(name);
  19. shouldUpdate = true;
  20. }
  21. });
  22. if (shouldUpdate) {
  23. setSearchParams(searchParams);
  24. }
  25. // eslint-disable-next-line react-hooks/exhaustive-deps
  26. }, [searchParams, commands]);
  27. }
  28. interface ChatCommands {
  29. new?: Command;
  30. newm?: Command;
  31. next?: Command;
  32. prev?: Command;
  33. clear?: Command;
  34. del?: Command;
  35. }
  36. export const ChatCommandPrefix = ":";
  37. export function useChatCommand(commands: ChatCommands = {}) {
  38. function extract(userInput: string) {
  39. return (
  40. userInput.startsWith(ChatCommandPrefix) ? userInput.slice(1) : userInput
  41. ) as keyof ChatCommands;
  42. }
  43. function search(userInput: string) {
  44. const input = extract(userInput);
  45. const desc = Locale.Chat.Commands;
  46. return Object.keys(commands)
  47. .filter((c) => c.startsWith(input))
  48. .map((c) => ({
  49. title: desc[c as keyof ChatCommands],
  50. content: ChatCommandPrefix + c,
  51. }));
  52. }
  53. function match(userInput: string) {
  54. const command = extract(userInput);
  55. const matched = typeof commands[command] === "function";
  56. return {
  57. matched,
  58. invoke: () => matched && commands[command]!(userInput),
  59. };
  60. }
  61. return { match, search };
  62. }