%PDF- %PDF-
Direktori : /home/dopla/www/wp-content/plugins/ml-slider/extendify-sdk/src/pages/ |
Current File : /home/dopla/www/wp-content/plugins/ml-slider/extendify-sdk/src/pages/GridView.js |
/** * External dependencies */ import Masonry from 'react-masonry-css' /** * WordPress dependencies */ import { useEffect, useState, useCallback, useRef } from '@wordpress/element' import { Spinner, Button } from '@wordpress/components' import { __ } from '@wordpress/i18n' /** * Internal dependencies */ import { useTemplatesStore } from '../state/Templates' import { Templates as TemplatesApi } from '../api/Templates' import { useInView } from 'react-intersection-observer' import { useIsMounted } from '../hooks/helpers' import { ImportTemplateBlock } from '../components/ImportTemplateBlock' export default function GridView() { const isMounted = useIsMounted() const templates = useTemplatesStore((state) => state.templates) const appendTemplates = useTemplatesStore((state) => state.appendTemplates) const [serverError, setServerError] = useState('') const [nothingFound, setNothingFound] = useState(false) // const [imagesLoaded, setImagesLoaded] = useState([]) const [loadMoreRef, inView] = useInView() const updateSearchParams = useTemplatesStore( (state) => state.updateSearchParams, ) const searchParamsRaw = useTemplatesStore((state) => state.searchParams) // Store the next page in case we have pagination const nextPage = useRef(useTemplatesStore.getState().nextPage) const searchParams = useRef(useTemplatesStore.getState().searchParams) // Connect to the store on mount, disconnect on unmount, catch state-changes in a reference useEffect( () => useTemplatesStore.subscribe( (n) => (nextPage.current = n), (state) => state.nextPage, ), [], ) useEffect( () => useTemplatesStore.subscribe( (s) => (searchParams.current = s), (state) => state.searchParams, ), [], ) // Fetch the templates then add them to the current state // TODO: This works, but it's not really doing what it's intended to do // as it has a side effect in there, and isn't pure. // It could be extracted to a hook const fetchTemplates = useCallback(async () => { setServerError('') setNothingFound(false) const response = await TemplatesApi.get(searchParams.current, { offset: nextPage.current, }).catch((error) => { console.error(error) setServerError( error && error.message ? error.message : __( 'Unknown error occured. Check browser console or contact support.', 'extendify-sdk', ), ) }) if (!isMounted.current) { return } if (response?.error?.length) { setServerError(response?.error) } if (response?.records && searchParamsRaw === searchParams.current) { useTemplatesStore.setState({ nextPage: response.offset, }) appendTemplates(response.records) setNothingFound(response.records.length <= 0) } }, [searchParamsRaw, appendTemplates, isMounted]) // 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 } // setImagesLoaded([]) fetchTemplates() }, [fetchTemplates, searchParams]) // Fetches when the load more is in view useEffect(() => { inView && fetchTemplates() }, [inView, fetchTemplates]) if (serverError.length) { return ( <div className="text-left"> <h2 className="text-left"> {__('Server error', 'extendify-sdk')} </h2> <code className="block max-w-xl p-4 mb-4" style={{ minHeight: '10rem', }}> {serverError} </code> <Button isTertiary onClick={() => { // setImagesLoaded([]) updateSearchParams({ taxonomies: {}, search: '', }) fetchTemplates() }}> {__('Press here to reload experience')} </Button> </div> ) } if (nothingFound) { return ( <h2 className="text-left"> {__('No results found.', 'extendify-sdk')} </h2> ) } if (!templates.length) { return ( <div className="flex items-center justify-center w-full sm:mt-64"> <Spinner /> </div> ) } const breakpointColumnsObj = { default: 2, 1320: 2, 860: 1, 599: 2, 400: 1, } return ( <> <Masonry breakpointCols={breakpointColumnsObj} className="flex -ml-8 w-auto pb-40 pt-0.5 pl-0.5" columnClassName="pl-8 bg-clip-padding min-h-screen"> {templates.map((template) => { return ( <ImportTemplateBlock key={template.id} template={template} /> ) })} </Masonry> {useTemplatesStore.getState().nextPage && ( <> <div className="transform -translate-y-20"> <Spinner /> </div> <div className="-translate-y-full flex flex-col h-80 items-end justify-end my-2 relative transform z-0 text" ref={loadMoreRef} style={{ zIndex: -1 }}></div> </> )} </> ) }