import { useQuery } from "@tanstack/react-query"; import type { GetTemplateFunctionSummaryResponse, TemplateFunction, } from "@yaakapp-internal/plugins"; import { atom, useAtomValue, useSetAtom } from "jotai"; import { useMemo, useState } from "react"; import type { TwigCompletionOption } from "../components/core/Editor/twig/completion"; import { invokeCmd } from "../lib/tauri"; import { usePluginsKey } from "./usePlugins"; const templateFunctionsAtom = atom([]); export function useTemplateFunctionCompletionOptions( onClick: (fn: TemplateFunction, ragTag: string, pos: number) => void, enabled: boolean, ) { const templateFunctions = useAtomValue(templateFunctionsAtom); return useMemo(() => { if (!enabled) { return []; } return templateFunctions.map((fn) => { const argsLabel = fn.args.length > 0 ? "…" : ""; const fn2: TwigCompletionOption = { type: "function", onClick: (rawTag: string, startPos: number) => onClick(fn, rawTag, startPos), label: `${fn.name}(${argsLabel})`, invalid: false, value: null, ...fn, }; return fn2; }); }, [enabled, onClick, templateFunctions]); } export function useSubscribeTemplateFunctions() { const pluginsKey = usePluginsKey(); const [numFns, setNumFns] = useState(0); const setAtom = useSetAtom(templateFunctionsAtom); useQuery({ queryKey: ["template_functions", pluginsKey], // Fetch periodically until functions are returned // NOTE: visibilitychange (refetchOnWindowFocus) does not work on Windows, so we'll rely on this logic // to refetch things until that's working again // TODO: Update plugin system to wait for plugins to initialize before sending the first event to them refetchInterval: numFns > 0 ? Number.POSITIVE_INFINITY : 1000, refetchOnMount: true, queryFn: async () => { const result = await invokeCmd( "cmd_template_function_summaries", ); setNumFns(result.length); const functions = result.flatMap((r) => r.functions) ?? []; setAtom(functions); return functions; }, }); }