import React, { useState, useEffect } from 'react';
import { MediaTransport } from './transport';
import { MemberId } from '@joystream/types/members';
import { useMyMembership } from '@polkadot/joy-utils/MyMembershipContext';
import { useTransportContext } from './TransportContext';
import { withMembershipRequired } from '@polkadot/joy-utils/MyAccount';
type InitialPropsWithMembership = A & {
myAddress?: string;
myMemberId?: MemberId;
}
type ResolverProps = InitialPropsWithMembership & {
transport: MediaTransport;
}
type BaseProps = {
component: React.ComponentType;
unresolvedView?: React.ReactElement;
resolveProps?: (props: ResolverProps) => Promise;
/**
* Array of property names that can trigger re-render of the view,
* if values of such properties changed.
*/
triggers?: (keyof A)[];
/** Set `true` if only members should have access to this component. `false` by default. */
membersOnly?: boolean;
}
function serializeTrigger (val: any): any {
if (['number', 'boolean', 'string'].includes(typeof val)) {
return val;
} else if (typeof val === 'object' && typeof val.toString === 'function') {
return val.toString();
} else {
return undefined;
}
}
export function MediaView (baseProps: BaseProps) {
function InnerView (initialProps: A & B) {
const { component: Component, resolveProps, triggers = [], unresolvedView = null } = baseProps;
const transport = useTransportContext();
const { myAddress, myMemberId } = useMyMembership();
const resolverProps = { ...initialProps, transport, myAddress, myMemberId };
const [resolvedProps, setResolvedProps] = useState({} as B);
const [propsResolved, setPropsResolved] = useState(false);
const initialDeps = triggers.map(propName => serializeTrigger(initialProps[propName]));
const rerenderDeps = [...initialDeps, myAddress];
useEffect(() => {
async function doResolveProps () {
if (typeof resolveProps !== 'function') return;
console.log('Resolving props of media view');
// Transport session allows us to cache loaded channels, entites and classes
// during the render of this view:
transport.openSession();
setResolvedProps(await resolveProps(resolverProps));
transport.closeSession();
setPropsResolved(true);
}
if (!transport) {
console.error('Transport is not defined');
} else {
doResolveProps();
}
}, rerenderDeps);
console.log('Rerender deps of Media View:', rerenderDeps);
const renderResolving = () => {
return unresolvedView || ;
};
return propsResolved
?
: renderResolving();
}
const { membersOnly = false } = baseProps;
return membersOnly
? withMembershipRequired(InnerView)
: InnerView;
}