PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 1.5.2
GenerateBlocks v1.5.2
trunk 1.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 2.0.0 2.0.1 2.0.2 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.3.0
generateblocks / src / blocks / image / edit.js
generateblocks / src / blocks / image Last commit date
components 4 years ago css 4 years ago block.json 4 years ago edit.js 4 years ago editor.scss 4 years ago index.js 4 years ago save.js 4 years ago transforms.js 4 years ago
edit.js
191 lines
1 import './editor.scss';
2 import ImageContentRenderer from './components/ImageContentRenderer';
3 import { compose } from '@wordpress/compose';
4 import withDynamicContent from '../../extend/dynamic-content/hoc/withDynamicContent';
5 import { withUniqueId } from '../../hoc';
6 import { useDeviceType } from '../../hooks';
7 import ComponentCSS from './components/ComponentCSS';
8 import { useDispatch, useSelect } from '@wordpress/data';
9 import { useEffect, useState } from '@wordpress/element';
10 import { store as noticesStore } from '@wordpress/notices';
11 import InspectorControls from './components/InspectorControls';
12 import { InspectorAdvancedControls, store as blockEditorStore } from '@wordpress/block-editor';
13 import { useEntityProp } from '@wordpress/core-data';
14 import { getBlobByURL, isBlobURL, revokeBlobURL } from '@wordpress/blob';
15 import HTMLAnchor from '../../components/html-anchor';
16 import { pick } from 'lodash';
17
18 function ImageEdit( props ) {
19 const {
20 attributes,
21 setAttributes,
22 context,
23 ContentRenderer = ImageContentRenderer,
24 } = props;
25
26 const {
27 useDynamicData,
28 dynamicContentType,
29 sizeSlug,
30 mediaId,
31 mediaUrl,
32 anchor,
33 } = attributes;
34
35 const [ deviceType ] = useDeviceType( 'Desktop' );
36 const { createErrorNotice } = useDispatch( noticesStore );
37 const [ temporaryURL, setTemporaryURL ] = useState();
38 const postType = 'post-type' === attributes.dynamicSource ? attributes.postType : context.postType;
39 const postId = 'post-type' === attributes.dynamicSource ? attributes.postId : context.postId;
40 const [ featuredImage ] = useEntityProp( 'postType', postType, 'featured_media', postId );
41 const isTemporaryImage = ( id, url ) => ! id && isBlobURL( url );
42
43 const { mediaUpload } = useSelect( ( select ) => {
44 const { getSettings } = select( blockEditorStore );
45 return pick( getSettings(), [ 'imageDefaultSize', 'mediaUpload' ] );
46 }, [] );
47
48 const onSelectImage = ( image ) => {
49 if ( ! image || ! image.url ) {
50 setAttributes( {
51 mediaUrl: undefined,
52 mediaId: undefined,
53 title: undefined,
54 alt: undefined,
55 } );
56
57 return;
58 }
59
60 if ( isBlobURL( image.url ) ) {
61 setTemporaryURL( image.url );
62 return;
63 }
64
65 setTemporaryURL();
66
67 if (
68 !! image &&
69 (
70 ! useDynamicData ||
71 (
72 !! useDynamicData &&
73 ! dynamicContentType
74 )
75 )
76 ) {
77 const imageUrl = ( image?.sizes && image?.sizes[ sizeSlug ]?.url ) || image?.url;
78
79 setAttributes( {
80 mediaId: image?.id,
81 mediaUrl: imageUrl,
82 alt: image?.alt,
83 title: image?.title,
84 } );
85 }
86 };
87
88 const onSelectURL = ( newURL ) => {
89 if ( newURL !== mediaUrl ) {
90 setAttributes( {
91 mediaUrl: newURL,
92 mediaId: undefined,
93 title: '',
94 alt: '',
95 } );
96 }
97 };
98
99 const onUploadError = ( message ) => {
100 createErrorNotice( message[ 2 ], { type: 'snackbar' } );
101 };
102
103 const onResetImage = () => {
104 setAttributes( {
105 mediaId: undefined,
106 mediaUrl: '',
107 alt: '',
108 title: '',
109 width: '',
110 widthTablet: '',
111 widthMobile: '',
112 height: '',
113 heightTablet: '',
114 heightMobile: '',
115 } );
116 };
117
118 useEffect( () => {
119 if ( ! sizeSlug ) {
120 setAttributes( { sizeSlug: 'full' } );
121 }
122 }, [] );
123
124 let isTemp = isTemporaryImage( mediaId, mediaUrl );
125
126 // Upload a temporary image on mount.
127 useEffect( () => {
128 if ( ! isTemp ) {
129 return;
130 }
131
132 const file = getBlobByURL( mediaUrl );
133
134 if ( file ) {
135 mediaUpload( {
136 filesList: [ file ],
137 onFileChange: ( [ img ] ) => {
138 onSelectImage( img );
139 },
140 allowedTypes: [ 'image' ],
141 onError: ( message ) => {
142 isTemp = false;
143 onUploadError( message );
144 },
145 } );
146 }
147 }, [] );
148
149 // If an image is temporary, revoke the Blob url when it is uploaded (and is
150 // no longer temporary).
151 useEffect( () => {
152 if ( isTemp ) {
153 setTemporaryURL( mediaUrl );
154 return;
155 }
156 revokeBlobURL( temporaryURL );
157 }, [ isTemp, mediaUrl ] );
158
159 return (
160 <>
161 <InspectorControls
162 attributes={ attributes }
163 setAttributes={ setAttributes }
164 deviceType={ deviceType }
165 />
166
167 <InspectorAdvancedControls>
168 <HTMLAnchor { ...props } anchor={ anchor } />
169 </InspectorAdvancedControls>
170
171 <ComponentCSS { ...props } deviceType={ deviceType } />
172
173 <ContentRenderer
174 { ...props }
175 temporaryURL={ temporaryURL }
176 featuredImage={ featuredImage }
177 onSelectImage={ onSelectImage }
178 onSelectURL={ onSelectURL }
179 onUploadError={ onUploadError }
180 onResetImage={ onResetImage }
181 deviceType={ deviceType }
182 />
183 </>
184 );
185 }
186
187 export default compose(
188 withDynamicContent,
189 withUniqueId,
190 )( ImageEdit );
191