import { useEffect, useState } from "react"; import type * as Y from "yjs"; export interface PublishStatus { active: boolean; userName: string | null; startedAt: number | null; jobId: string | null; } const INACTIVE: PublishStatus = { active: false, userName: null, startedAt: null, jobId: null, }; /** * Observe the `publish-status` Y.Map on a document. The backend populates * this map at the start and end of a publish so that all connected editors * can disable their Publish button while a publish is running. * * `doc` may be `null` while the provider is still connecting; the hook simply * returns an inactive status in that case and re-subscribes when `doc` is set. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export function usePublishStatus(doc: Y.Doc | null): PublishStatus { const [status, setStatus] = useState(INACTIVE); useEffect(() => { if (!doc) { setStatus(INACTIVE); return; } const map = doc.getMap("publish-status"); const read = (): PublishStatus => ({ active: (map.get("active") as boolean) === true, userName: (map.get("userName") as string | null | undefined) ?? null, startedAt: (map.get("startedAt") as number | null | undefined) ?? null, jobId: (map.get("jobId") as string | null | undefined) ?? null, }); setStatus(read()); const observer = () => setStatus(read()); map.observe(observer); return () => map.unobserve(observer); }, [doc]); return status; }