UNPKG

@blocklet/ui-react

Version:

Some useful front-end web components that can be used in Blocklets.

89 lines (77 loc) 2.73 kB
import { BLOCKLET_SERVICE_PATH_PREFIX } from '@arcblock/did-connect/lib/constant'; import { useEffect, useMemo, useRef, useState } from 'react'; import { joinURL } from 'ufo'; const parseDidToSet = (did) => { if (typeof did === 'string') { return new Set(did.split(';;')); } return new Set(did); }; function useComponentInstalled({ did, onInstalled, onError }) { const didKeys = Array.isArray(did) ? did.join(';;') : did; const [installStatus, setInstallStatus] = useState({}); const onInstalledRef = useRef({ onInstalled, onError }); onInstalledRef.current = { onInstalled, onError }; const { optionalComponents, componentMountPoints } = window.blocklet; const optComponents = useMemo(() => { if (!optionalComponents || !optionalComponents.length) { return []; } const didSet = parseDidToSet(didKeys); const components = optionalComponents.filter((c) => didSet.has(c.meta.did)); (components ? onInstalledRef.current.onError : onInstalledRef.current.onInstalled)?.(components); return components; }, [didKeys, optionalComponents]); const definedInBlockletYML = useMemo(() => { if (optComponents.length) { return true; } const didSet = parseDidToSet(didKeys); return (componentMountPoints || []).find((item) => didSet.has(item.did)); }, [optComponents, componentMountPoints, didKeys]); optComponents.forEach((item) => { item.storeUrl = joinURL(item.meta.homepage, 'blocklets', item.meta.did); item.installUrl = joinURL( window.blocklet.appUrl, BLOCKLET_SERVICE_PATH_PREFIX, `/admin/components?install-component=${item.meta.did}` ); }); useEffect(() => { const handle = (event) => { if (event.origin !== window.blocklet.appUrl) { return; } if (event.data?.kind === 'component-installer' && event.data?.blocklet?.children) { let hasChild = false; const didSet = parseDidToSet(didKeys); event.data?.blocklet?.children.forEach((item) => { if (didSet.has(item.meta?.did)) { hasChild = true; setInstallStatus((value) => { return { ...value, [item.meta?.did]: item.status || 'waiting', }; }); } }); if (!hasChild) { setInstallStatus({}); } } }; window.addEventListener('message', handle); return () => { window.removeEventListener('message', handle); }; }, [didKeys]); return { optComponents, installed: !optComponents.length && definedInBlockletYML, installStatus, setInstallStatus, definedInBlockletYML, }; } export default useComponentInstalled;