import { useCallback, useEffect, useState } from "react"; import { type ToastItem } from "@nodedc/ui-react"; import { APIError, loginFromLaunch, request, type Status } from "./api"; export function useNode() { const [value, setValue] = useState(null); const [pending, setPending] = useState(true); const [locked, setLocked] = useState(false); const [toasts, setToasts] = useState([]); const failure = useCallback((error: unknown) => { if (error instanceof APIError && error.status === 401) { setValue(null); setLocked(true); } setToasts([{ id: "request", tone: "error", title: error instanceof Error ? error.message : "Нода недоступна", durationMs: null }]); }, []); const refresh = useCallback(async () => { setPending(true); try { const result = await request("/api/status"); setValue(result); setLocked(false); setToasts([]); } catch (error) { failure(error); } finally { setPending(false); } }, [failure]); useEffect(() => { const launch = () => { void loginFromLaunch().then(refresh).then(()=>window.dispatchEvent(new Event("mission-core-session-ready"))).catch(error => { failure(error); setPending(false); }); }; launch(); window.addEventListener("hashchange", launch); return () => window.removeEventListener("hashchange", launch); }, [refresh, failure]); const success = useCallback((title: string) => setToasts([{ id: "request", tone: "success", title }]), []); return { value, pending, locked, refresh, failure, success, toasts, dismiss: (id: string) => setToasts(items => items.filter(item => item.id !== id)) }; }