repo_description: ✨ Light and Fast AI Assistant. Support: Web | iOS | MacOS | Android |  Linux | Windows
repo_topics: calclaude chatgpt claude cross-platform desktop fe gemini gemini-pro gemini-server gemini-ultra gpt-4o groq nextjs ollama react tauri tauri-app vercel webui
code: 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 };
  }
  