import { useState, useEffect, useCallback, useRef } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { checkDocker, listTuskContainers, cloneToDocker, startContainer, stopContainer, removeContainer, onCloneProgress, } from "@/lib/tauri"; import type { CloneToDockerParams, CloneProgress, CloneResult } from "@/types"; export function useDockerStatus() { return useQuery({ queryKey: ["docker-status"], queryFn: checkDocker, staleTime: 30_000, }); } export function useTuskContainers() { return useQuery({ queryKey: ["tusk-containers"], queryFn: listTuskContainers, refetchInterval: 10_000, }); } export function useCloneToDocker() { const [progress, setProgress] = useState(null); const cloneIdRef = useRef(""); const queryClient = useQueryClient(); const mutation = useMutation({ mutationFn: ({ params, cloneId, }: { params: CloneToDockerParams; cloneId: string; }) => { cloneIdRef.current = cloneId; setProgress(null); return cloneToDocker(params, cloneId); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["connections"] }); queryClient.invalidateQueries({ queryKey: ["tusk-containers"] }); }, }); useEffect(() => { let mounted = true; let unlisten: (() => void) | undefined; onCloneProgress((p) => { if (mounted && p.clone_id === cloneIdRef.current) { setProgress(p); } }).then((fn) => { if (mounted) { unlisten = fn; } else { fn(); } }); return () => { mounted = false; unlisten?.(); }; }, []); const mutationRef = useRef(mutation); useEffect(() => { mutationRef.current = mutation; }); const reset = useCallback(() => { mutationRef.current.reset(); setProgress(null); cloneIdRef.current = ""; }, []); return { clone: mutation.mutate, result: mutation.data as CloneResult | undefined, error: mutation.error ? String(mutation.error) : null, isCloning: mutation.isPending, progress, reset, }; } export function useStartContainer() { const queryClient = useQueryClient(); return useMutation({ mutationFn: (name: string) => startContainer(name), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["tusk-containers"] }); }, }); } export function useStopContainer() { const queryClient = useQueryClient(); return useMutation({ mutationFn: (name: string) => stopContainer(name), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["tusk-containers"] }); }, }); } export function useRemoveContainer() { const queryClient = useQueryClient(); return useMutation({ mutationFn: (name: string) => removeContainer(name), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["tusk-containers"] }); }, }); }