UNPKG

@multisynq/react

Version:

React bindings for Multisynq

56 lines (55 loc) 1.89 kB
import { useEffect, useState } from 'react'; import { useMultisynqContext } from './useMultisynqContext'; // Make sure we only warn once let warned = false; function deprecatedViewsPropertyWarning() { if (warned) return; warned = true; console.warn('Accessing the `views` property of `useJoinedViews` is deprecated. Use `viewIds` instead.'); } const EMPTY_ARRAY = []; const EMPTY_OBJECT = {}; const NO_VIEWS = { viewIds: EMPTY_ARRAY, viewInfos: EMPTY_OBJECT, viewCount: 0, get views() { deprecatedViewsPropertyWarning(); return this.viewIds; } }; function viewsSelector(rootModel) { if (!(rootModel === null || rootModel === void 0 ? void 0 : rootModel.__views)) return NO_VIEWS; const views = rootModel.__views; return { viewIds: Array.from(views.keys()), viewInfos: Object.fromEntries(views.entries()), viewCount: views.size, get views() { deprecatedViewsPropertyWarning(); return this.viewIds; } }; } export function useJoinedViews() { const { session, view, model } = useMultisynqContext(); const [views, setViews] = useState(viewsSelector(model)); useEffect(() => { if (session && view && model) { const handler = () => setViews(viewsSelector(model)); view.subscribe(session.id, { event: 'views-updated', handling: 'oncePerFrame' }, handler); handler(); return () => view.unsubscribe(session.id, 'views-updated', handler); } else { setViews(NO_VIEWS); } }, [session, view, model]); if (model && !model.__views) { throw new Error('Your root model is not tracking the joined views.\n' + 'Pass `options: { trackViews: true }` to your <MultisynqRoot> component to start tracking them\n'); } return views; }