Файловый менеджер - Редактировать - /home/digitalm/tendepavia/wp-content/plugins/redux-framework/extendify-sdk/src/Library/pages/GridView.js
Назад
import { Spinner, Button } from '@wordpress/components' import { useEffect, useState, useCallback, useRef, memo, } from '@wordpress/element' import { __, sprintf } from '@wordpress/i18n' import { cloneDeep } from 'lodash' import { useInView } from 'react-intersection-observer' import Masonry from 'react-masonry-css' import { Templates as TemplatesApi } from '@library/api/Templates' import { ImportTemplateBlock } from '@library/components/ImportTemplateBlock' import { useIsMounted } from '@library/hooks/helpers' import { useGlobalStore } from '@library/state/GlobalState' import { useTaxonomyStore } from '@library/state/Taxonomies' import { useTemplatesStore } from '@library/state/Templates' export const GridView = memo(function GridView() { const isMounted = useIsMounted() const templates = useTemplatesStore((state) => state.templates) const [templatesCount, setTemplatesCount] = useState(0) const appendTemplates = useTemplatesStore((state) => state.appendTemplates) const [serverError, setServerError] = useState('') const retryOnce = useRef(false) const [nothingFound, setNothingFound] = useState(false) const [loading, setLoading] = useState(false) const [loadMoreRef, inView] = useInView() const searchParamsRaw = useTemplatesStore((state) => state.searchParams) const currentType = useGlobalStore((state) => state.currentType) const resetTemplates = useTemplatesStore((state) => state.resetTemplates) const open = useGlobalStore((state) => state.open) const taxonomies = useTaxonomyStore((state) => state.taxonomies) const updateType = useTemplatesStore((state) => state.updateType) const updateTaxonomies = useTemplatesStore( (state) => state.updateTaxonomies, ) // Store the next page in case we have pagination const nextPage = useRef(useTemplatesStore.getState().nextPage) const searchParams = useRef(useTemplatesStore.getState().searchParams) const taxonomyType = searchParams.current.type === 'pattern' ? 'patternType' : 'layoutType' const currentTax = searchParams.current.taxonomies[taxonomyType] // Subscribing to the store will keep these values updates synchronously useEffect(() => { return useTemplatesStore.subscribe( (state) => state.nextPage, (n) => (nextPage.current = n), ) }, []) useEffect(() => { return useTemplatesStore.subscribe( (state) => state.searchParams, (s) => (searchParams.current = s), ) }, []) // Fetch the templates then add them to the current state const fetchTemplates = useCallback(() => { setServerError('') setNothingFound(false) const defaultError = __( 'Unknown error occurred. Check browser console or contact support.', 'extendify', ) const args = { offset: nextPage.current } const siteType = searchParams.current.taxonomies?.siteType?.slug?.length ? searchParams.current.taxonomies.siteType : { slug: 'default' } const params = cloneDeep(searchParams.current) params.taxonomies.siteType = siteType TemplatesApi.get(params, args) .then((response) => { if (!isMounted.current) return if (response?.error?.length) { setServerError(response?.error) return } if (response?.records?.length <= 0) { setNothingFound(true) return } if ( searchParamsRaw === searchParams.current && response?.records?.length ) { useTemplatesStore.setState({ nextPage: response?.offset ?? '', }) // Essentially used to trigger the inview observer appendTemplates(response.records) setTemplatesCount((c) => response.records.length + c) setLoading(false) } }) .catch((error) => { if (!isMounted.current) return console.error(error) setServerError(defaultError) }) }, [appendTemplates, isMounted, searchParamsRaw]) useEffect(() => { if (templates?.length === 0) { setLoading(true) return } }, [templates?.length, searchParamsRaw]) useEffect(() => { // If there's a server error, retry the request // This is temporary until we upgrade the backend and add // a tool like react query to handle this automatically if (!retryOnce.current && serverError.length) { retryOnce.current = true fetchTemplates() } }, [serverError, fetchTemplates]) useEffect(() => { // This will check the URL for a pattern type and set that and remove it // TODO: possibly refactor this if we expand it to support layouts if (!open || !taxonomies?.patternType?.length) return const search = new URLSearchParams(window.location.search) if (!search.has('ext-patternType')) return const term = search.get('ext-patternType') // Delete it right away search.delete('ext-patternType') window.history.replaceState( null, null, window.location.pathname + '?' + search.toString(), ) // Search the slug in patternTypes const tax = taxonomies.patternType.find((t) => t.slug === term) if (!tax) return updateTaxonomies({ patternType: tax }) updateType('pattern') }, [open, taxonomies, updateType, updateTaxonomies]) // This is the main driver for loading templates // This loads the initial batch of templates. But if we don't yet have taxonomies. // There's also an option to skip loading on first mount useEffect(() => { if (!Object.keys(searchParams.current?.taxonomies)?.length) { return } if (useTemplatesStore.getState().skipNextFetch) { // This is useful if the templates are fetched already and // the library moves to/from another state that re-renders // The point is to keep the logic close to the list. That may change someday useTemplatesStore.setState({ skipNextFetch: false, }) return } fetchTemplates() return () => resetTemplates() }, [fetchTemplates, searchParams, resetTemplates]) // Fetches when the load more is in view useEffect(() => { nextPage.current && inView && fetchTemplates() }, [inView, fetchTemplates, templatesCount]) if (serverError.length && retryOnce.current) { return ( <div className="text-left"> <h2 className="text-left">{__('Server error', 'extendify')}</h2> <code className="mb-4 block max-w-xl p-4" style={{ minHeight: '10rem' }}> {serverError} </code> <Button isTertiary onClick={() => { retryOnce.current = false fetchTemplates() }}> {__('Press here to reload', 'extendify')} </Button> </div> ) } if (nothingFound) { return ( <div className="-mt-2 flex h-full w-full items-center justify-center sm:mt-0"> <h2 className="text-sm font-normal text-extendify-gray"> {sprintf( searchParams.current.type === 'template' ? // translators: %s is the layout category name __( 'We couldn\'t find any layouts in the "%s" category.', 'extendify', ) : // translators: %s is the pattern category name __( 'We couldn\'t find any patterns in the "%s" category.', 'extendify', ), currentTax?.title ?? currentTax.slug, )} </h2> </div> ) } return ( <> {loading && ( <div className="-mt-2 flex h-full w-full items-center justify-center sm:mt-0"> <Spinner /> </div> )} <Grid type={currentType} templates={templates}> {templates.map((template) => { return ( <ImportTemplateBlock maxHeight={ currentType === 'template' ? 520 : 'none' } key={template.id} template={template} /> ) })} </Grid> {nextPage.current && ( <> <div className="mt-8"> <Spinner /> </div> <div className="relative flex flex-col items-end justify-end -top-1/4 h-4" ref={loadMoreRef} style={{ zIndex: -1 }} /> </> )} </> ) }) const Grid = ({ type, children }) => { const sharedClasses = 'relative min-h-screen z-10 pb-40 pt-0.5' switch (type) { case 'template': return ( <div className={`grid gap-6 md:gap-8 lg:grid-cols-2 ${sharedClasses}`}> {children} </div> ) } const breakpointColumnsObj = { default: 3, 1600: 2, 860: 1, 599: 2, 400: 1, } return ( <Masonry breakpointCols={breakpointColumnsObj} className={`-ml-6 flex w-auto px-0.5 md:-ml-8 ${sharedClasses}`} columnClassName="pl-6 md:pl-8 bg-clip-padding space-y-6 md:space-y-8"> {children} </Masonry> ) }
| ver. 1.4 |
Github
|
.
| PHP 8.3.23 | Генерация страницы: 0.06 |
proxy
|
phpinfo
|
Настройка