import React, { useContext, useEffect, useState, useRef, useCallback, } from 'react'; import { TokenContext, TokenContextType } from '../contexts/tokenProvider'; import { ClientContext } from '../contexts/clientProvider'; import DefaultRenderer, { RenderProps } from '../renderers/DefaultRenderer'; import { Token } from '../core/token'; import Loading from './bootstrap/Loading'; export default function TokenRenderer({ customRenderer = null, tokenContext = null, customToken = null, rendererProps = {}, }: { customRenderer?: typeof DefaultRenderer | DefaultRenderer; tokenContext?: TokenContextType; customToken?: Token; rendererProps?: RenderProps; }) { const client = useContext(ClientContext); const [loading, setLoading] = useState(false); const [ready, setReady] = useState(false); const currentTokenContext = useRef(tokenContext); const currentTokenRenderer = useRef< typeof DefaultRenderer | DefaultRenderer >(null); const backupContext = useContext(TokenContext); currentTokenContext.current = currentTokenContext.current || backupContext; const load = useCallback(async () => { if (!client.loaded) return; if (!customToken && !currentTokenContext.current) return; setReady(false); setLoading(true); if (customRenderer) currentTokenRenderer.current = customRenderer; else currentTokenRenderer.current = client.controller.config.rendering.defaultRenderer || DefaultRenderer; if (client.project.hasCustomRenderer()) { currentTokenRenderer.current = await require(client.project.getCustomRenderer()); currentTokenRenderer.current = (currentTokenRenderer.current as any).default || currentTokenRenderer.current; } setLoading(false); setReady(true); }, [client, customToken, customRenderer]); useEffect(() => { load(); }, [load]); if (loading || !ready) return ; let Component = currentTokenRenderer.current as typeof DefaultRenderer; if (ready && Component) return ( ); return ; }