index.js (5881B)
1 const {compose} = wp.compose; 2 const {withDispatch, withSelect} = wp.data; 3 const {useState, useEffect, useReducer} = wp.element 4 const {Spinner} = wp.components; 5 import SitePreviewSidebar from './SitePreviewSidebar'; 6 import {ModalManager} from '../modal-manager' 7 import ImportWizard from '../modal-import-wizard'; 8 import {Fragment} from 'react'; 9 import SafeImageLoad from '~redux-templates/components/safe-image-load'; 10 import {processImportHelper} from '~redux-templates/stores/actionHelper'; 11 import './style.scss'; 12 13 const initialState = { 14 currentPageData: null, 15 currentIndex: 0, 16 itemData: null, 17 imageURL: '' 18 }; 19 20 const LOADING_RESET = 0; 21 const IN_PROGRESS = 1; 22 const FULLY_LOADED = 2; 23 24 const previewReducer = (state, action) => { 25 let currentPageData; 26 let imageURL; 27 switch(action.type) { 28 case 'INDEX': 29 currentPageData = state.currentPageData; 30 break; 31 case 'DATA': 32 currentPageData = action.currentPageData; 33 break; 34 } 35 const itemData = currentPageData[action.currentIndex]; 36 if (itemData.image_full) 37 imageURL = itemData.image_full; 38 else 39 imageURL = itemData.image 40 41 return { 42 currentPageData, 43 currentIndex: action.currentIndex, 44 imageURL, 45 itemData 46 }; 47 } 48 49 function PreviewModal(props) { 50 51 const {startIndex, currentPageData} = props; 52 const {setImportingTemplate, importingTemplate} = props; 53 54 const [state, dispatch] = useReducer(previewReducer, initialState); 55 56 const [previewClass, setPreviewClass] = useState('preview-desktop') 57 const [expandedClass, toggleExpanded] = useState('expanded') 58 const [pressedKey, setPressedKey] = useState(null); 59 const [loading, setLoading] = useState(IN_PROGRESS); 60 const [wrapperClassName, setWrapperClassName] = useState('wp-full-overlay sites-preview theme-install-overlay '); 61 62 // Key event handling : event listener set up 63 useEffect(() => { 64 const handleKeyDown = ({keyCode}) => { 65 setPressedKey(keyCode); 66 } 67 68 window.addEventListener('keydown', handleKeyDown); 69 return () => { 70 window.removeEventListener('keydown', handleKeyDown); 71 } 72 }, []); 73 74 // Key Event handling 75 useEffect(() => { 76 if (pressedKey !== null) { 77 if (pressedKey === 37) onPrevBlock(); 78 if (pressedKey === 39) onNextBlock(); 79 setPressedKey(null); 80 } 81 }, [pressedKey]) 82 83 useEffect(() => { 84 if (isNaN(startIndex) === false && currentPageData) 85 dispatch({ type: 'DATA', currentIndex: startIndex, currentPageData }); 86 }, [startIndex, currentPageData]); 87 88 // mobile/desktop preview status and sidebar collapse/expand 89 useEffect(() => { 90 setWrapperClassName(['wp-full-overlay sites-preview theme-install-overlay ', previewClass, expandedClass].join(' ')); 91 }, [previewClass, expandedClass]) 92 93 const onCloseCustomizer = () => { 94 ModalManager.closeCustomizer(); 95 } 96 97 const onNextBlock = () => { 98 if (state.currentIndex < currentPageData.length - 1) { 99 startLoading(); 100 dispatch({ type: 'INDEX', currentIndex: state.currentIndex + 1 }); 101 } 102 } 103 104 const onPrevBlock = () => { 105 if (state.currentIndex > 0) { 106 setLoading(); 107 dispatch({ type: 'INDEX', currentIndex: state.currentIndex - 1 }); 108 } 109 } 110 111 const startLoading = () => { 112 setLoading(LOADING_RESET); 113 setTimeout(() => { 114 setLoading(IN_PROGRESS); 115 }, 100) 116 } 117 118 119 const importStarterBlock = () => { 120 setImportingTemplate(state.itemData); 121 ModalManager.closeCustomizer(); 122 } 123 124 const processImport = () => { 125 if (importingTemplate) processImportHelper(); 126 } 127 128 // Called from iframe upon successful loading 129 const hideSpinner = () => { 130 setLoading(FULLY_LOADED); 131 } 132 133 if (!state || !state.itemData) return null; 134 135 return ( 136 <Fragment> 137 <div className={wrapperClassName} style={{display: 'block'}}> 138 <SitePreviewSidebar itemData={state.itemData} previewClass={previewClass} expandedClass={expandedClass} 139 onNextBlock={onNextBlock} onPrevBlock={onPrevBlock} 140 onCloseCustomizer={onCloseCustomizer} onToggleExpanded={e => toggleExpanded(e)} 141 onImport={importStarterBlock} 142 onChangePreviewClass={e => setPreviewClass(e)}/> 143 <div className="wp-full-overlay-main loaded"> 144 { 145 (loading < FULLY_LOADED) && <Spinner /> 146 } 147 {state.itemData.url && 148 <iframe src={(loading === LOADING_RESET) ? '' : state.itemData.url + '?preview=1'} target='Preview' onLoad={hideSpinner}></iframe> 149 } 150 {!state.itemData.url && 151 <div className='redux-templates-modal-preview-box'> 152 <SafeImageLoad url={state.imageURL} /> 153 </div> 154 } 155 156 </div> 157 </div> 158 { importingTemplate && <ImportWizard startImportTemplate={processImport} /> } 159 </Fragment> 160 ); 161 } 162 163 export default compose([ 164 withDispatch((dispatch) => { 165 const { 166 setImportingTemplate, 167 setCustomizerOpened 168 } = dispatch('redux-templates/sectionslist'); 169 170 return { 171 setImportingTemplate, 172 setCustomizerOpened 173 }; 174 }), 175 176 withSelect((select, props) => { 177 const {getImportingTemplate} = select('redux-templates/sectionslist'); 178 return { 179 importingTemplate: getImportingTemplate() 180 }; 181 }) 182 ])(PreviewModal);