add-library.js
2 years ago
category-list.js
1 year ago
insert-pattern.js
2 years ago
library-cache.js
2 years ago
library-layout.js
1 year ago
library-provider.js
2 years ago
library-selector.js
1 year ago
manage-libraries.js
2 years ago
pattern-details-header.js
1 year ago
pattern-details.js
1 year ago
pattern-list.js
1 year ago
pattern-search.js
2 years ago
pattern.js
1 year ago
selected-patterns.js
1 year ago
library-provider.js
204 lines
| 1 | |
| 2 | import { createContext, useContext, useEffect, useState, useReducer } from '@wordpress/element'; |
| 3 | import { __ } from '@wordpress/i18n'; |
| 4 | import apiFetch from '@wordpress/api-fetch'; |
| 5 | import { addQueryArgs } from '@wordpress/url'; |
| 6 | |
| 7 | const LibraryContext = createContext( undefined ); |
| 8 | |
| 9 | export async function fetchLibraries( isEnabled = true ) { |
| 10 | return await apiFetch( { |
| 11 | path: addQueryArgs( '/generateblocks/v1/pattern-library/libraries', { |
| 12 | is_enabled: isEnabled, |
| 13 | } ), |
| 14 | method: 'GET', |
| 15 | } ); |
| 16 | } |
| 17 | |
| 18 | async function fetchLibraryCategories( libraryId, isLocal, publicKey ) { |
| 19 | const pro = isLocal ? '-pro' : ''; |
| 20 | try { |
| 21 | const response = await apiFetch( { |
| 22 | path: addQueryArgs( `/generateblocks${ pro }/v1/pattern-library/categories`, { |
| 23 | libraryId, |
| 24 | isLocal, |
| 25 | } ), |
| 26 | method: 'GET', |
| 27 | headers: { |
| 28 | 'X-GB-Public-Key': publicKey, |
| 29 | }, |
| 30 | } ); |
| 31 | |
| 32 | return response?.response ?? []; |
| 33 | } catch ( error ) { |
| 34 | return []; |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | async function fetchLibraryPatterns( libraryId, categoryId, search, isLocal, publicKey ) { |
| 39 | const pro = isLocal ? '-pro' : ''; |
| 40 | try { |
| 41 | const response = await apiFetch( { |
| 42 | path: addQueryArgs( `/generateblocks${ pro }/v1/pattern-library/patterns`, { |
| 43 | libraryId, |
| 44 | categoryId, |
| 45 | search, |
| 46 | isLocal, |
| 47 | } ), |
| 48 | method: 'GET', |
| 49 | headers: { |
| 50 | 'X-GB-Public-Key': publicKey, |
| 51 | }, |
| 52 | } ); |
| 53 | |
| 54 | return response?.response ?? []; |
| 55 | } catch ( error ) { |
| 56 | return []; |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | export function LibraryProvider( { children } ) { |
| 61 | const [ libraries, setLibraryData ] = useState( [] ); |
| 62 | const [ categories, setCategories ] = useState( [] ); |
| 63 | const [ patterns, setPatterns ] = useState( [] ); |
| 64 | const [ search, setSearch ] = useState( '' ); |
| 65 | const [ activeLibrary, setActiveLibrary ] = useState( '' ); |
| 66 | const [ publicKey, setPublicKey ] = useState( '' ); |
| 67 | const [ isLocal, setIsLocal ] = useState( false ); |
| 68 | const [ activeCategory, setActiveCategory ] = useState( '' ); |
| 69 | const [ activePatternId, setActivePatternId ] = useState( '' ); |
| 70 | const [ hoverPattern, setHoverPattern ] = useState( '' ); |
| 71 | const [ loading, setLoading ] = useState( false ); |
| 72 | const [ previewIframeWidth, setPreviewIframeWidth ] = useState( '100%' ); |
| 73 | const itemsPerPage = 15; |
| 74 | const [ itemCount, setItemCount ] = useState( itemsPerPage ); |
| 75 | const [ scrollPosition, setScrollPosition ] = useState( 0 ); |
| 76 | |
| 77 | function selectedPatternsReducer( state, action ) { |
| 78 | switch ( action.type ) { |
| 79 | case 'ADD': |
| 80 | return [ ...state, action.pattern ]; |
| 81 | case 'REMOVE': |
| 82 | return state.filter( ( selectedPattern ) => selectedPattern.id !== action.pattern.id ); |
| 83 | case 'SET': |
| 84 | return action.patterns; |
| 85 | default: |
| 86 | return state; |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | const [ selectedPatterns, selectedPatternsDispatch ] = useReducer( selectedPatternsReducer, [] ); |
| 91 | const defaultContext = { |
| 92 | libraries, |
| 93 | search, |
| 94 | setSearch, |
| 95 | activeLibrary, |
| 96 | setActiveLibrary, |
| 97 | activeCategory, |
| 98 | setActiveCategory, |
| 99 | activePatternId, |
| 100 | setActivePatternId, |
| 101 | selectedPatterns, |
| 102 | selectedPatternsDispatch, |
| 103 | categories, |
| 104 | hoverPattern, |
| 105 | setHoverPattern, |
| 106 | patterns, |
| 107 | isLocal, |
| 108 | setIsLocal, |
| 109 | setPublicKey, |
| 110 | loading, |
| 111 | setLoading, |
| 112 | previewIframeWidth, |
| 113 | setPreviewIframeWidth, |
| 114 | setLibraryCategories, |
| 115 | setLibraryPatterns, |
| 116 | setLibraries, |
| 117 | itemsPerPage, |
| 118 | itemCount, |
| 119 | setItemCount, |
| 120 | scrollPosition, |
| 121 | setScrollPosition, |
| 122 | }; |
| 123 | |
| 124 | async function setLibraryCategories() { |
| 125 | const { data } = await fetchLibraryCategories( activeLibrary?.id, isLocal, publicKey ); |
| 126 | |
| 127 | // We only want to show categories that have patterns in this current library of collections. |
| 128 | const categoriesInPatterns = new Set( patterns.flatMap( ( obj ) => obj.categories ) ); |
| 129 | const categoriesWithPatterns = data.filter( ( category ) => categoriesInPatterns.has( category.id ) ); |
| 130 | |
| 131 | setCategories( categoriesWithPatterns ?? [] ); |
| 132 | |
| 133 | const intialCategory = categoriesWithPatterns.find( ( category ) => ( |
| 134 | generateBlocksPatternLibrary.defaultOpenCategory === category.name |
| 135 | ) ) ?? ''; |
| 136 | |
| 137 | setActiveCategory( intialCategory?.id ?? '' ); |
| 138 | } |
| 139 | |
| 140 | async function setLibraryPatterns() { |
| 141 | setLoading( true ); |
| 142 | setPatterns( [] ); |
| 143 | |
| 144 | // Fetch all patterns for the active library. |
| 145 | const { data: fetchedPatterns } = await fetchLibraryPatterns( activeLibrary?.id, '', '', isLocal, publicKey ); |
| 146 | setPatterns( fetchedPatterns ?? [] ); |
| 147 | |
| 148 | // Reset. |
| 149 | setItemCount( itemsPerPage ); |
| 150 | setScrollPosition( 0 ); |
| 151 | setLoading( false ); |
| 152 | } |
| 153 | |
| 154 | async function setLibraries() { |
| 155 | const { data } = await fetchLibraries(); |
| 156 | setLibraryData( data ?? [] ); |
| 157 | |
| 158 | const initialLibrary = data.find( ( library ) => ( |
| 159 | generateBlocksPatternLibrary.defaultOpenLibrary === library.id |
| 160 | ) ) ?? data[ 0 ] ?? {}; |
| 161 | setActiveLibrary( initialLibrary ?? false ); |
| 162 | setPublicKey( initialLibrary?.publicKey ?? '' ); |
| 163 | setIsLocal( initialLibrary?.isLocal ?? false ); |
| 164 | } |
| 165 | |
| 166 | useEffect( () => { |
| 167 | ( async function() { |
| 168 | setLibraries(); |
| 169 | }() ); |
| 170 | }, [] ); |
| 171 | |
| 172 | useEffect( () => { |
| 173 | if ( activeLibrary.id ) { |
| 174 | setLibraryCategories(); |
| 175 | } else { |
| 176 | setCategories( [] ); |
| 177 | } |
| 178 | }, [ activeLibrary?.id, patterns ] ); |
| 179 | |
| 180 | useEffect( () => { |
| 181 | if ( activeLibrary.id ) { |
| 182 | setLibraryPatterns(); |
| 183 | } else { |
| 184 | setPatterns( [] ); |
| 185 | } |
| 186 | }, [ activeLibrary?.id, publicKey ] ); |
| 187 | |
| 188 | return ( |
| 189 | <LibraryContext.Provider value={ defaultContext }> |
| 190 | { children } |
| 191 | </LibraryContext.Provider> |
| 192 | ); |
| 193 | } |
| 194 | |
| 195 | export function useLibrary() { |
| 196 | const context = useContext( LibraryContext ); |
| 197 | |
| 198 | if ( ! context ) { |
| 199 | throw new Error( __( 'useLibrary hook must be wrapped by a LibraryProvider.', 'generateblocks' ) ); |
| 200 | } |
| 201 | |
| 202 | return context; |
| 203 | } |
| 204 |