import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"; import { authSessionId, credentials } from "../services/authStorage"; import { onViewerChange, viewerEpoch } from "../utils/writeThroughHold"; /** Who one opening of a worklist belongs to: the viewer, acted-as subject and practice, the session and the transport. */ export interface ListOwner { viewer: number; session: string | null; transport: unknown; } /** * The owner of the list now shown, and whether an owner is still it. Liveness is read at the moment of asking, not from * the last render, so an operation begun for one viewer or session is refused for the next before the screen redraws, * including when the same account signs in again. */ export const useListOwner = (transport: unknown) => { const [viewer, setViewer] = useState(viewerEpoch); const [session, setSession] = useState(authSessionId); useEffect(() => { const changed = () => { setViewer(viewerEpoch()); setSession(authSessionId()); }; const stop = onViewerChange(changed); const stopRecord = credentials().onChange(changed); return () => { stop(); stopRecord(); }; }, []); const owner = useMemo(() => ({ viewer, session, transport }), [viewer, session, transport]); const current = useRef(owner); useLayoutEffect(() => { current.current = owner; return () => { if (current.current === owner) current.current = null; }; }, [owner]); const live = useCallback((of: ListOwner) => current.current === of && of.viewer === viewerEpoch() && of.session === authSessionId(), []); return { owner, live }; };