PluginProbe
Automatic YouTube Gallery – Embed Auto-Updating YouTube Video Galleries, Feeds, Playlists & Channels / trunk
Automatic YouTube Gallery – Embed Auto-Updating YouTube Video Galleries, Feeds, Playlists & Channels vtrunk
2.9.1 2.9.0 trunk 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 2.0.0 2.1.0 2.2.0 2.3.2 2.3.3 2.3.5 2.3.6 2.3.8 2.3.9 2.4.3 All 37 releases
automatic-youtube-gallery / block / src / edit.js

edit.js in Automatic YouTube Gallery – Embed Auto-Updating YouTube Video Galleries, Feeds, Playlists & Channels trunk, at block/src/edit.js

289 lines 6.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Import block dependencies
3 */
4 import ServerSideRender from '@wordpress/server-side-render';
5
6 import classnames from 'classnames';
7
8 import { debounce } from '@wordpress/compose';
9
10 import {
11 InspectorControls,
12 PanelColorSettings,
13 useBlockProps
14 } from '@wordpress/block-editor';
15
16 import {
17 Disabled,
18 PanelBody,
19 PanelRow,
20 RangeControl,
21 SelectControl,
22 TextControl,
23 TextareaControl,
24 ToggleControl
25 } from '@wordpress/components';
26
27 import {
28 useCallback,
29 useEffect,
30 useRef,
31 useState
32 } from '@wordpress/element';
33
34 import { applyFilters } from '@wordpress/hooks';
35
36 /**
37 * Describes the structure of the block in the context of the editor.
38 * This represents what the editor will render when the block is used.
39 *
40 * @return {WPElement} Element to render.
41 */
42 export default function Edit( { attributes, setAttributes, className, clientId } ) {
43
44 attributes.uid = clientId;
45
46 const [ isLoading, setIsLoading ] = useState( false );
47 const [ proxyAttributes, setProxyAttributes ] = useState( attributes );
48
49 const AYGServerSideRender = () => (
50 <ServerSideRender
51 block="automatic-youtube-gallery/block"
52 attributes={ Object.assign( {}, proxyAttributes, { is_admin: true } ) }
53 />
54 );
55
56 const MemoizedServerSideRender = useCallback( AYGServerSideRender, [ proxyAttributes ] );
57
58 const debounceProxyAttributes = () => {
59 setIsLoading( false );
60 setProxyAttributes( { ...attributes } );
61 }
62
63 const debouncedProxyAttributes = debounce( debounceProxyAttributes, 1000 );
64
65 const getControl = ( field, index ) => {
66 if ( ! canShowControl( field.name ) ) {
67 return '';
68 }
69
70 const placeholder = field.placeholder ? field.placeholder : '';
71 const description = field.description ? field.description : '';
72
73 switch ( field.type ) {
74 case 'number':
75 return <PanelRow key={ index }>
76 <RangeControl
77 label={ field.label }
78 help={ description }
79 placeholder={ placeholder }
80 value={ attributes[ field.name ] }
81 min={ field.min }
82 max={ field.max }
83 onChange={ onChange( field.name ) }
84 __nextHasNoMarginBottom={ true }
85 __next40pxDefaultSize={ true }
86 />
87 </PanelRow>
88 case 'textarea':
89 return <PanelRow key={ index }>
90 <TextareaControl
91 label={ field.label }
92 help={ description }
93 placeholder={ placeholder }
94 value={ attributes[ field.name ] }
95 onChange={ onChange( field.name ) }
96 __nextHasNoMarginBottom={ true }
97 />
98 </PanelRow>
99 case 'select':
100 case 'radio':
101 let options = [];
102
103 for ( let key in field.options ) {
104 options.push({
105 label: field.options[ key ],
106 value: key
107 });
108 };
109
110 return <PanelRow key={ index }>
111 <SelectControl
112 label={ field.label }
113 help={ description }
114 options={ options }
115 value={ attributes[ field.name ] }
116 onChange={ onChange( field.name ) }
117 __nextHasNoMarginBottom={ true }
118 __next40pxDefaultSize={ true }
119 />
120 </PanelRow>
121 case 'checkbox':
122 return <PanelRow key={ index }>
123 <ToggleControl
124 label={ field.label }
125 help={ description }
126 checked={ attributes[ field.name ] }
127 onChange={ toggleAttribute( field.name ) }
128 __nextHasNoMarginBottom={ true }
129 />
130 </PanelRow>
131 case 'color':
132 return <PanelRow key={ index }>
133 <PanelColorSettings
134 title={ field.label }
135 colorSettings={ [
136 {
137 label: ayg_block.i18n.selected_color,
138 value: attributes[ field.name ],
139 onChange: onChange( field.name ),
140 }
141 ] }
142 >
143 </PanelColorSettings>
144 </PanelRow>
145 default:
146 return <PanelRow key={ index }>
147 <TextControl
148 label={ field.label }
149 help={ description }
150 placeholder={ placeholder }
151 value={ attributes[ field.name ] }
152 onChange={ onChange( field.name ) }
153 __nextHasNoMarginBottom={ true }
154 __next40pxDefaultSize={ true }
155 />
156 </PanelRow>
157 }
158 }
159
160 const canShowPanel = ( panel ) => {
161 let value = true;
162
163 switch ( panel ) {
164 case 'gallery':
165 if ( 'video' == attributes.type || 'livestream' == attributes.type ) {
166 value = false;
167 }
168 break;
169 case 'search':
170 if ( 'video' == attributes.type || 'livestream' == attributes.type ) {
171 value = false;
172 }
173
174 if ( 'slider' == attributes.theme || 'slider-popup' == attributes.theme || 'slider-inline' == attributes.theme || 'playlister' == attributes.theme ) {
175 value = false;
176 }
177 break;
178 }
179
180 return applyFilters( 'ayg_block_toggle_panels', value, panel, attributes );
181 }
182
183 const canShowControl = ( control ) => {
184 let value = true;
185
186 switch ( control ) {
187 case 'playlist':
188 case 'username':
189 case 'search':
190 case 'video':
191 case 'videos':
192 if ( control != attributes.type ) {
193 value = false;
194 }
195 break;
196 case 'channel':
197 if ( 'channel' != attributes.type && 'livestream' != attributes.type ) {
198 value = false;
199 }
200 break;
201 case 'order':
202 case 'limit':
203 if ( 'search' != attributes.type ) {
204 value = false;
205 }
206 break;
207 case 'cache':
208 case 'player_title':
209 case 'player_description':
210 case 'loop':
211 if ( 'livestream' == attributes.type ) {
212 value = false;
213 }
214 break;
215 case 'autoadvance':
216 if ( 'video' == attributes.type || 'livestream' == attributes.type ) {
217 value = false;
218 }
219 break;
220 }
221
222 return applyFilters( 'ayg_block_toggle_controls', value, control, attributes );
223 }
224
225 const onChange = ( attribute ) => {
226 return ( newValue ) => {
227 setAttributes( { [ attribute ]: newValue } );
228 };
229 }
230
231 const toggleAttribute = ( attribute ) => {
232 return ( newValue ) => {
233 setAttributes( { [ attribute ]: newValue } );
234 };
235 }
236
237 useEffect(() => {
238 setIsLoading( true );
239 debouncedProxyAttributes();
240 }, [ attributes ] );
241
242 const mounted = useRef();
243 useEffect( () => {
244 if ( ! mounted.current ) {
245 // Do componentDidMount logic
246 mounted.current = true;
247 } else {
248 // Do componentDidUpdate logic
249 applyFilters( 'ayg_block_init', attributes );
250 }
251 } );
252
253 const classes = classnames( className, {
254 'is-loading': isLoading,
255 } );
256
257 const blockProps = useBlockProps( {
258 className: classes,
259 } );
260
261 return (
262 <>
263 <InspectorControls>
264 {Object.keys( ayg_block.options ).map(( key, index ) => {
265 return (
266 canShowPanel( key ) && <PanelBody
267 key={ 'automatic-youtube-gallery-block-panel-' + index }
268 title={ ayg_block.options[ key ].label }
269 initialOpen={ 0 == index ? true : false }
270 className="automatic-youtube-gallery-block-panel">
271
272 {Object.keys( ayg_block.options[ key ].fields ).map(( _key, _index ) => {
273 return getControl( ayg_block.options[ key ].fields[ _key ], 'automatic-youtube-gallery-block-control-' + _index );
274 })}
275
276 </PanelBody>
277 )
278 })}
279 </InspectorControls>
280
281 <div { ...blockProps }>
282 <Disabled>
283 <MemoizedServerSideRender />
284 </Disabled>
285 </div>
286 </>
287 );
288 }
289