import { useEffect, useState, useRef, memo } from '@wordpress/element' import { __, sprintf } from '@wordpress/i18n' import { BlockPreview } from '@wordpress/block-editor' import { rawHandler } from '@wordpress/blocks' import { Icon } from '@wordpress/icons' import { Button } from '@wordpress/components' import { useInView } from 'react-intersection-observer' import { growthArrow, patterns, layouts, support, star, brandLogo, } from '../components/icons/' import { AuthorizationCheck, Middleware } from '../middleware' import { injectTemplateBlocks } from '../util/templateInjection' import { useUserStore } from '../state/User' import { useGlobalStore } from '../state/GlobalState' import { Templates as TemplatesApi } from '../api/Templates' import Primary from './buttons/Primary' import SplitModal from './modals/SplitModal' import SettingsModal from './modals/SettingsModal' import { useIsDevMode } from '../hooks/helpers' import { DevButtonOverlay } from './DevHelpers' const LiveBlocksMemoized = memo( ({ blocks }) => { return (
) }, (oldBlocks, newBlocks) => oldBlocks.clientId == newBlocks.clientId, ) const canImportMiddleware = Middleware([ 'NeedsRegistrationModal', 'hasRequiredPlugins', 'hasPluginsActivated', ]) // TODO: extract this modal const NoImportModal = ( useGlobalStore.setState({ currentModal: null })} left={ <>
{brandLogo}

{__("You're out of imports", 'extendify')}

{__( 'Sign up today and get unlimited access to our entire collection of patterns and page layouts.', 'extendify', )}

{__('Get Unlimited Imports', 'extendify')}

{__('Have an account?', 'extendify')}

} right={
{__("Access to 100's of Patterns", 'extendify')}
{__('Beautiful full page layouts', 'extendify')}
{__('Fast and friendly support', 'extendify')}
{__('14-Day guarantee', 'extendify')}
} /> ) export function ImportTemplateBlock({ template }) { const importButtonRef = useRef(null) const once = useRef(false) const canImport = useUserStore((state) => state.canImport) const setOpen = useGlobalStore((state) => state.setOpen) const setCurrentModal = useGlobalStore((state) => state.setCurrentModal) const blocks = rawHandler({ HTML: template.fields.code }) const [hasBeenSeen, setHasBeenSeen] = useState(false) const [loaded, setLoaded] = useState(false) const [onlyLoadInView, inView] = useInView() const devMode = useIsDevMode() const focusTrapInnerBlocks = () => { if (once.current) return once.current = true Array.from( importButtonRef.current.querySelectorAll( 'a, button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])', ), ).forEach((el) => el.setAttribute('tabIndex', '-1')) } const importTemplates = async () => { await canImportMiddleware.check(template) AuthorizationCheck(canImportMiddleware) .then(() => { setTimeout(() => { injectTemplateBlocks(blocks, template) .then(() => setCurrentModal(null)) .then(() => setOpen(false)) .then(() => canImportMiddleware.reset()) }, 100) }) .catch(() => {}) } const handleKeyDown = (event) => { if (['Enter', 'Space', ' '].includes(event.key)) { event.stopPropagation() event.preventDefault() importTemplate() } } const importTemplate = () => { if (!canImport()) { setCurrentModal(NoImportModal) return } TemplatesApi.maybeImport(template) importTemplates() } // Trigger resize event on the live previews to add // Grammerly/Loom/etc compatability // TODO: This can probably be removed after WP 5.9 useEffect(() => { const rafIds = [] let rafId1, rafId2, rafId3 rafId1 = window.requestAnimationFrame(() => { rafId2 = window.requestAnimationFrame(() => { importButtonRef.current .querySelectorAll('iframe') .forEach((frame) => { const rafId = window.requestAnimationFrame(() => { frame.contentWindow.dispatchEvent( new Event('resize'), ) }) rafIds.push(rafId) }) rafId3 = window.requestAnimationFrame(() => { window.dispatchEvent(new Event('resize')) setLoaded(true) }) }) }) return () => [...rafIds, rafId1, rafId2, rafId3].forEach((id) => window.cancelAnimationFrame(id), ) }, []) useEffect(() => { if (!hasBeenSeen && inView) { setHasBeenSeen(true) } }, [inView, hasBeenSeen, template]) return (
{hasBeenSeen && }
{/* Show dev info after the preview is loaded to trigger observer */} {devMode && loaded && }
) }