@multisynq/react
Version:
React bindings for Multisynq
56 lines (55 loc) • 1.89 kB
JavaScript
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;
}