import { createContext, FC, PropsWithChildren, useCallback, useContext, useEffect, useMemo } from 'react'; import { InteractionsRegistry } from '../interactions/InteractionsRegistry'; import { Article } from '@cntrl-site/sdk'; import { useCurrentLayout } from '../common/useCurrentLayout'; import { ArticleRectContext } from './ArticleRectContext'; import { ItemGeometryContext } from '../ItemGeometry/ItemGeometryContext'; export const InteractionsContext = createContext(undefined); interface Props { article: Article; } export const InteractionsProvider: FC> = ({ article, children }) => { const { layoutId } = useCurrentLayout(); const articleRectObserver = useContext(ArticleRectContext); const itemGeometryService = useContext(ItemGeometryContext); const registry = useMemo(() => { if (!layoutId) return; return new InteractionsRegistry(article, layoutId, itemGeometryService); }, [layoutId, itemGeometryService]); useEffect(() => { if (!registry || !articleRectObserver) return; const handleScroll = () => { const scrollY = window.scrollY; registry.notifyScroll(scrollY); }; return articleRectObserver.on('scroll', handleScroll); }, [registry, articleRectObserver]); const notifyLoad = useCallback(() => { if (!registry) return; requestAnimationFrame(() => { setTimeout(() => { registry.notifyLoad(); }, 0); }); }, [registry]); useEffect(() => { const handlePageOverlay = (e: CustomEvent) => { const itemId = e.detail.itemId; if (!registry || !itemId) return; registry.notifyPageOverlay(itemId); }; window.addEventListener('page-overlay', handlePageOverlay as EventListener); return () => { window.removeEventListener('page-overlay', handlePageOverlay as EventListener); }; }, [registry]); useEffect(() => { if (document.readyState === 'complete') { notifyLoad(); } else { window.addEventListener('load', notifyLoad); } return () => window.removeEventListener('load', notifyLoad); }, [notifyLoad]); return ( {children} ); }; export function useInteractionsRegistry(): InteractionsRegistry | undefined { const registry = useContext(InteractionsContext); return registry; }