PluginProbe
Block Animations, Motion & Scroll Effects – Ghost Kit / 3.3.3
Block Animations, Motion & Scroll Effects – Ghost Kit v3.3.3
3.7.2 3.7.1 3.7.0 3.6.1 trunk 1.6.3 2.25.0 3.3.0 3.3.1 3.3.2 3.3.3 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.5.0 3.5.1 3.6.0
ghostkit / gutenberg / blocks / twitter / edit.js

edit.js in Block Animations, Motion & Scroll Effects – Ghost Kit 3.3.3, at gutenberg/blocks/twitter/edit.js

663 lines 23.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import classnames from 'classnames/dedupe';
2
3 import { InspectorControls } from '@wordpress/block-editor';
4 import {
5 ExternalLink,
6 PanelBody,
7 Placeholder,
8 SelectControl,
9 Spinner,
10 TextControl,
11 ToggleControl,
12 } from '@wordpress/components';
13 import { useSelect } from '@wordpress/data';
14 import { applyFilters } from '@wordpress/hooks';
15 import { __ } from '@wordpress/i18n';
16
17 import RangeControl from '../../components/range-control';
18 import getIcon from '../../utils/get-icon';
19
20 /**
21 * Block Edit Class.
22 *
23 * @param props
24 */
25 export default function BlockEdit(props) {
26 const { setAttributes, attributes } = props;
27
28 let { className } = props;
29
30 const {
31 consumerKey,
32 consumerSecret,
33 accessToken,
34 accessTokenSecret,
35
36 userName,
37 count,
38
39 showReplies,
40 showRetweets,
41 showFeedAvatar,
42 feedAvatarSize,
43 showFeedName,
44 showFeedDate,
45 feedTextMode,
46 feedTextConvertLinks,
47 showFeedActions,
48
49 showProfile,
50 showProfileAvatar,
51 profileAvatarSize,
52 showProfileName,
53 showProfileStats,
54 showProfileDescription,
55 showProfileWebsite,
56 showProfileLocation,
57 } = attributes;
58
59 const { twitterFeed, twitterProfile } = useSelect((select) => {
60 const APIDataReady =
61 consumerKey &&
62 consumerSecret &&
63 accessToken &&
64 accessTokenSecret &&
65 userName;
66
67 if (!APIDataReady) {
68 return false;
69 }
70
71 const apiKeys = {
72 consumer_key: consumerKey,
73 consumer_secret: consumerSecret,
74 access_token: accessToken,
75 access_token_secret: accessTokenSecret,
76 screen_name: userName,
77 };
78
79 return {
80 twitterFeed: select('ghostkit/blocks/twitter').getTwitterFeed({
81 count,
82 exclude_replies: showReplies ? 'false' : 'true',
83 include_rts: showRetweets ? 'true' : 'false',
84 tweet_mode_extended: feedTextMode === 'full' ? 'true' : 'false',
85 ...apiKeys,
86 }),
87 twitterProfile: select('ghostkit/blocks/twitter').getTwitterProfile(
88 apiKeys
89 ),
90 };
91 })(BlockEdit);
92
93 className = classnames('ghostkit-twitter', className);
94
95 className = applyFilters('ghostkit.editor.className', className, props);
96
97 const APIDataReady =
98 consumerKey &&
99 consumerSecret &&
100 accessToken &&
101 accessTokenSecret &&
102 userName;
103
104 return (
105 <>
106 <InspectorControls>
107 {APIDataReady ? (
108 <>
109 <PanelBody>
110 <TextControl
111 placeholder={__('Username', 'ghostkit')}
112 value={userName}
113 onChange={(value) =>
114 setAttributes({ userName: value })
115 }
116 />
117 </PanelBody>
118 <PanelBody title={__('Feed', 'ghostkit')}>
119 <RangeControl
120 label={__('Tweets Number', 'ghostkit')}
121 value={count}
122 onChange={(value) =>
123 setAttributes({ count: value })
124 }
125 min={1}
126 max={20}
127 />
128 <ToggleControl
129 label={__('Show Replies', 'ghostkit')}
130 checked={!!showReplies}
131 onChange={(value) =>
132 setAttributes({ showReplies: value })
133 }
134 />
135 <ToggleControl
136 label={__('Show Retweets', 'ghostkit')}
137 checked={!!showRetweets}
138 onChange={(value) =>
139 setAttributes({ showRetweets: value })
140 }
141 />
142 <ToggleControl
143 label={__('Show Avatar', 'ghostkit')}
144 checked={!!showFeedAvatar}
145 onChange={(value) =>
146 setAttributes({ showFeedAvatar: value })
147 }
148 />
149 {showFeedAvatar ? (
150 <RangeControl
151 label={__('Avatar Size', 'ghostkit')}
152 value={feedAvatarSize}
153 onChange={(value) =>
154 setAttributes({ feedAvatarSize: value })
155 }
156 min={10}
157 max={100}
158 allowCustomMin
159 allowCustomMax
160 />
161 ) : null}
162 <ToggleControl
163 label={__('Show Name', 'ghostkit')}
164 checked={!!showFeedName}
165 onChange={(value) =>
166 setAttributes({ showFeedName: value })
167 }
168 />
169 <ToggleControl
170 label={__('Show Date', 'ghostkit')}
171 checked={!!showFeedDate}
172 onChange={(value) =>
173 setAttributes({ showFeedDate: value })
174 }
175 />
176 <ToggleControl
177 label={__('Show Actions', 'ghostkit')}
178 checked={!!showFeedActions}
179 onChange={(value) =>
180 setAttributes({ showFeedActions: value })
181 }
182 />
183 <SelectControl
184 label={__('Text Mode', 'ghostkit')}
185 value={feedTextMode}
186 options={[
187 {
188 value: '',
189 label: __('Short', 'ghostkit'),
190 },
191 {
192 value: 'full',
193 label: __('Full', 'ghostkit'),
194 },
195 ]}
196 onChange={(value) =>
197 setAttributes({ feedTextMode: value })
198 }
199 />
200 <SelectControl
201 label={__('Convert Text Links', 'ghostkit')}
202 value={feedTextConvertLinks}
203 options={[
204 {
205 value: 'links_media',
206 label: __('Links + Media', 'ghostkit'),
207 },
208 {
209 value: 'links',
210 label: __('Links', 'ghostkit'),
211 },
212 {
213 value: 'no',
214 label: __('No Convert', 'ghostkit'),
215 },
216 ]}
217 onChange={(value) =>
218 setAttributes({
219 feedTextConvertLinks: value,
220 })
221 }
222 />
223 </PanelBody>
224 <PanelBody title={__('Profile', 'ghostkit')}>
225 <ToggleControl
226 label={__('Show Profile', 'ghostkit')}
227 checked={!!showProfile}
228 onChange={(value) =>
229 setAttributes({ showProfile: value })
230 }
231 />
232 {showProfile ? (
233 <>
234 <ToggleControl
235 label={__('Show Avatar', 'ghostkit')}
236 checked={!!showProfileAvatar}
237 onChange={(value) =>
238 setAttributes({
239 showProfileAvatar: value,
240 })
241 }
242 />
243 {showProfileAvatar ? (
244 <RangeControl
245 label={__(
246 'Avatar Size',
247 'ghostkit'
248 )}
249 value={profileAvatarSize}
250 onChange={(value) =>
251 setAttributes({
252 profileAvatarSize: value,
253 })
254 }
255 min={30}
256 max={150}
257 allowCustomMin
258 allowCustomMax
259 />
260 ) : null}
261 <ToggleControl
262 label={__('Show Name', 'ghostkit')}
263 checked={!!showProfileName}
264 onChange={(value) =>
265 setAttributes({
266 showProfileName: value,
267 })
268 }
269 />
270 <ToggleControl
271 label={__('Show Stats', 'ghostkit')}
272 checked={!!showProfileStats}
273 onChange={(value) =>
274 setAttributes({
275 showProfileStats: value,
276 })
277 }
278 />
279 <ToggleControl
280 label={__(
281 'Show Description',
282 'ghostkit'
283 )}
284 checked={!!showProfileDescription}
285 onChange={(value) =>
286 setAttributes({
287 showProfileDescription: value,
288 })
289 }
290 />
291 <ToggleControl
292 label={__('Show Website', 'ghostkit')}
293 checked={!!showProfileWebsite}
294 onChange={(value) =>
295 setAttributes({
296 showProfileWebsite: value,
297 })
298 }
299 />
300 <ToggleControl
301 label={__('Show Location', 'ghostkit')}
302 checked={!!showProfileLocation}
303 onChange={(value) =>
304 setAttributes({
305 showProfileLocation: value,
306 })
307 }
308 />
309 </>
310 ) : null}
311 </PanelBody>
312 </>
313 ) : null}
314
315 <PanelBody
316 title={__('API Data', 'ghostkit')}
317 initialOpen={!APIDataReady}
318 >
319 <TextControl
320 placeholder={__('Consumer Key', 'ghostkit')}
321 value={consumerKey}
322 onChange={(value) =>
323 setAttributes({ consumerKey: value })
324 }
325 />
326 <TextControl
327 placeholder={__('Consumer Secret', 'ghostkit')}
328 value={consumerSecret}
329 onChange={(value) =>
330 setAttributes({ consumerSecret: value })
331 }
332 />
333 <TextControl
334 placeholder={__('Access Token', 'ghostkit')}
335 value={accessToken}
336 onChange={(value) =>
337 setAttributes({ accessToken: value })
338 }
339 />
340 <TextControl
341 placeholder={__('Access Token Secret', 'ghostkit')}
342 value={accessTokenSecret}
343 onChange={(value) =>
344 setAttributes({ accessTokenSecret: value })
345 }
346 />
347 <p>
348 <em>
349 {__(
350 'A valid API data is required to use Twitter feed. How to get it',
351 'ghostkit'
352 )}{' '}
353 <ExternalLink href="http://www.gabfirethemes.com/create-twitter-api-key/">
354 http://www.gabfirethemes.com/create-twitter-api-key/
355 </ExternalLink>
356 </em>
357 </p>
358 </PanelBody>
359 </InspectorControls>
360 <div className={className}>
361 {APIDataReady && showProfile && twitterProfile ? (
362 <div className="ghostkit-twitter-profile">
363 {showProfileAvatar &&
364 twitterProfile.profile_images_https ? (
365 <div className="ghostkit-twitter-profile-avatar">
366 <ExternalLink
367 href={`https://twitter.com/${twitterProfile.screen_name}/`}
368 >
369 <img
370 src={
371 twitterProfile.profile_images_https
372 .original
373 }
374 alt={twitterProfile.fullName}
375 width={profileAvatarSize}
376 height={profileAvatarSize}
377 />
378 </ExternalLink>
379 </div>
380 ) : null}
381 <div className="ghostkit-twitter-profile-side">
382 {showProfileName && twitterProfile.name ? (
383 <div className="ghostkit-twitter-profile-name">
384 <h2 className="ghostkit-twitter-profile-fullname">
385 <ExternalLink
386 href={`https://twitter.com/${twitterProfile.screen_name}/`}
387 >
388 {twitterProfile.name}
389 </ExternalLink>
390 {twitterProfile.verified ? (
391 <span className="ghostkit-twitter-profile-verified">
392 {__(
393 'Verified account',
394 'ghostkit'
395 )}
396 </span>
397 ) : null}
398 </h2>
399 <h3 className="ghostkit-twitter-profile-username">
400 <ExternalLink
401 href={`https://twitter.com/${twitterProfile.screen_name}/`}
402 >
403 @{twitterProfile.screen_name}
404 </ExternalLink>
405 </h3>
406 </div>
407 ) : null}
408 {showProfileStats ? (
409 <div className="ghostkit-twitter-profile-stats">
410 <div>
411 <strong>
412 {
413 twitterProfile.statuses_count_short
414 }
415 </strong>{' '}
416 <span>{__('Tweets', 'ghostkit')}</span>
417 </div>
418 <div>
419 <strong>
420 {twitterProfile.friends_count_short}
421 </strong>{' '}
422 <span>
423 {__('Following', 'ghostkit')}
424 </span>
425 </div>
426 <div>
427 <strong>
428 {
429 twitterProfile.followers_count_short
430 }
431 </strong>{' '}
432 <span>
433 {__('Followers', 'ghostkit')}
434 </span>
435 </div>
436 </div>
437 ) : null}
438 {showProfileDescription &&
439 twitterProfile.description_entitled ? (
440 <div
441 className="ghostkit-twitter-profile-description"
442 dangerouslySetInnerHTML={{
443 __html: twitterProfile.description_entitled,
444 }}
445 />
446 ) : null}
447 {showProfileWebsite &&
448 twitterProfile.url_entitled ? (
449 <div
450 className="ghostkit-twitter-profile-website"
451 dangerouslySetInnerHTML={{
452 __html: `<svg class="ghostkit-svg-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.348 7.40994L14.378 5.37894C14.9421 4.82384 15.7027 4.51411 16.4941 4.51724C17.2855 4.52037 18.0436 4.8361 18.6033 5.39565C19.163 5.9552 19.4789 6.71324 19.4822 7.50465C19.4855 8.29606 19.176 9.05672 18.621 9.62094L15.621 12.6209C15.3171 12.9248 14.9514 13.1598 14.5488 13.3101C14.1462 13.4604 13.7159 13.5224 13.2873 13.492C12.8586 13.4616 12.4414 13.3394 12.064 13.1337C11.6867 12.928 11.3579 12.6437 11.1 12.2999C10.9804 12.1408 10.8025 12.0357 10.6054 12.0077C10.4083 11.9798 10.2081 12.0313 10.049 12.1509C9.8899 12.2705 9.7848 12.4484 9.75686 12.6455C9.72892 12.8426 9.78041 13.0428 9.90003 13.2019C10.2869 13.7176 10.7801 14.1442 11.3462 14.4527C11.9123 14.7612 12.5381 14.9445 13.1812 14.9901C13.8243 15.0357 14.4697 14.9426 15.0737 14.7171C15.6777 14.4915 16.2262 14.1388 16.682 13.6829L19.682 10.6829C20.1082 10.2669 20.4475 9.77059 20.6804 9.22251C20.9133 8.67443 21.0351 8.08558 21.0387 7.49008C21.0423 6.89459 20.9277 6.30429 20.7016 5.75342C20.4754 5.20254 20.1421 4.70204 19.721 4.28092C19.3 3.8598 18.7995 3.52644 18.2487 3.30016C17.6978 3.07388 17.1076 2.95919 16.5121 2.96273C15.9166 2.96626 15.3277 3.08796 14.7796 3.32077C14.2315 3.55357 13.735 3.89285 13.319 4.31894L11.289 6.34894C11.1523 6.49033 11.0766 6.67975 11.0782 6.8764C11.0799 7.07305 11.1586 7.26119 11.2976 7.40032C11.4366 7.53944 11.6247 7.6184 11.8213 7.6202C12.018 7.62201 12.2075 7.5465 12.349 7.40994H12.348ZM5.37803 14.3789L8.37803 11.3789C8.68201 11.0747 9.04784 10.8395 9.45072 10.689C9.8536 10.5386 10.2841 10.4766 10.713 10.5071C11.142 10.5377 11.5593 10.6601 11.9369 10.866C12.3144 11.072 12.6432 11.3567 12.901 11.7009C13.0206 11.86 13.1985 11.9651 13.3956 11.9931C13.5927 12.021 13.7929 11.9695 13.952 11.8499C14.1111 11.7303 14.2162 11.5524 14.2442 11.3553C14.2721 11.1582 14.2206 10.958 14.101 10.7989C13.7141 10.2832 13.2209 9.85667 12.6548 9.54816C12.0887 9.23965 11.4629 9.05638 10.8198 9.01077C10.1767 8.96516 9.5313 9.05827 8.92731 9.28379C8.32332 9.50932 7.77485 9.862 7.31903 10.3179L4.31803 13.3179C3.47411 14.1618 3 15.3064 3 16.4999C3 17.6934 3.47411 18.838 4.31803 19.6819C5.16195 20.5258 6.30655 20.9999 7.50003 20.9999C8.69351 20.9999 9.83811 20.5258 10.682 19.6819L12.712 17.6519C12.8487 17.5105 12.9244 17.3211 12.9228 17.1245C12.9211 16.9278 12.8424 16.7397 12.7034 16.6005C12.5644 16.4614 12.3763 16.3824 12.1796 16.3806C11.983 16.3788 11.7935 16.4543 11.652 16.5909L9.62203 18.6209C9.34432 18.9032 9.01346 19.1278 8.64854 19.2816C8.28361 19.4354 7.89184 19.5155 7.49582 19.5172C7.09981 19.5188 6.70738 19.442 6.34118 19.2913C5.97498 19.1405 5.64225 18.9187 5.36219 18.6387C5.08212 18.3588 4.86027 18.0261 4.70942 17.6599C4.55857 17.2937 4.48171 16.9013 4.48328 16.5053C4.48484 16.1093 4.5648 15.7175 4.71854 15.3525C4.87228 14.9876 5.09676 14.6567 5.37903 14.3789H5.37803Z" fill="currentColor"/></svg> ${twitterProfile.url_entitled}`,
453 }}
454 />
455 ) : null}
456 {showProfileLocation && twitterProfile.location ? (
457 <div
458 className="ghostkit-twitter-profile-location"
459 dangerouslySetInnerHTML={{
460 __html: `<svg class="ghostkit-svg-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M11.2806 20.6368C5.98328 13.2316 5 12.4715 5 9.75C5 6.02207 8.13399 3 12 3C15.866 3 19 6.02207 19 9.75C19 12.4715 18.0167 13.2316 12.7194 20.6368C12.3718 21.1211 11.6282 21.121 11.2806 20.6368ZM12 12.5625C13.6108 12.5625 14.9167 11.3033 14.9167 9.75C14.9167 8.19669 13.6108 6.9375 12 6.9375C10.3892 6.9375 9.08333 8.19669 9.08333 9.75C9.08333 11.3033 10.3892 12.5625 12 12.5625Z" fill="currentColor"/></svg> ${twitterProfile.location}`,
461 }}
462 />
463 ) : null}
464 </div>
465 </div>
466 ) : null}
467 {APIDataReady && twitterFeed ? (
468 <div className="ghostkit-twitter-items">
469 {twitterFeed.map((item, i) => {
470 const oldItem = item;
471 let isRetweet = false;
472
473 if (item.retweeted_status) {
474 item = item.retweeted_status;
475 isRetweet = true;
476 }
477
478 const itemName = `twitter-item-${i}`;
479
480 return (
481 <div
482 className="ghostkit-twitter-item"
483 key={itemName}
484 >
485 {showFeedAvatar ? (
486 <div className="ghostkit-twitter-item-avatar">
487 {isRetweet && <br />}
488 <ExternalLink
489 href={`https://twitter.com/${item.user.screen_name}/`}
490 >
491 <img
492 src={
493 item.user
494 .profile_images_https
495 .bigger
496 }
497 alt={item.user.screen_name}
498 width={feedAvatarSize}
499 height={feedAvatarSize}
500 />
501 </ExternalLink>
502 </div>
503 ) : null}
504 <div className="ghostkit-twitter-item-content">
505 {isRetweet ? (
506 <div className="ghostkit-twitter-item-retweeted">
507 <span
508 className="ghostkit-twitter-item-retweeted-icon"
509 dangerouslySetInnerHTML={{
510 __html: '<svg class="ghostkit-svg-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M22 16L19 19L16 16" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M14 6L15.6667 6C16.5507 6 17.3986 6.30436 18.0237 6.84614C18.6488 7.38791 19 8.12271 19 8.88889L19 19" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M2 9L5 6L8 9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 19L8.33333 19C7.44928 19 6.60143 18.6956 5.97631 18.1539C5.35119 17.6121 5 16.8773 5 16.1111L5 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',
511 }}
512 />
513 <ExternalLink
514 href={`https://twitter.com/${oldItem.user.screen_name}/`}
515 >
516 <strong>
517 {oldItem.user.name}
518 </strong>
519 </ExternalLink>
520 {__('Retweeted', 'ghostkit')}
521 </div>
522 ) : null}
523 {showFeedName || showFeedDate ? (
524 <div className="ghostkit-twitter-item-meta">
525 {showFeedName ? (
526 <div className="ghostkit-twitter-item-meta-name">
527 <ExternalLink
528 href={`https://twitter.com/${item.user.screen_name}/`}
529 >
530 <strong>
531 {item.user.name}
532 </strong>{' '}
533 {item.user
534 .verified ? (
535 <span className="ghostkit-twitter-item-meta-name-verified">
536 {__(
537 'Verified account',
538 'ghostkit'
539 )}
540 </span>
541 ) : null}{' '}
542 <span>
543 @
544 {
545 item.user
546 .screen_name
547 }
548 </span>
549 </ExternalLink>
550 </div>
551 ) : null}
552 {showFeedDate ? (
553 <div className="ghostkit-twitter-item-meta-date">
554 <ExternalLink
555 href={`https://twitter.com/${item.user.screen_name}/status/${item.id_str}`}
556 >
557 {
558 item.date_formatted
559 }
560 </ExternalLink>
561 </div>
562 ) : null}
563 </div>
564 ) : null}
565 {feedTextConvertLinks ===
566 'links_media' ? (
567 <div
568 className="ghostkit-twitter-item-text"
569 dangerouslySetInnerHTML={{
570 __html: item.text_entitled,
571 }}
572 />
573 ) : null}
574 {feedTextConvertLinks === 'links' ? (
575 <div
576 className="ghostkit-twitter-item-text"
577 dangerouslySetInnerHTML={{
578 __html: item.text_entitled_no_media,
579 }}
580 />
581 ) : null}
582 {feedTextConvertLinks !==
583 'links_media' &&
584 feedTextConvertLinks !== 'links' ? (
585 <div
586 className="ghostkit-twitter-item-text"
587 dangerouslySetInnerHTML={{
588 __html: item.text,
589 }}
590 />
591 ) : null}
592 {showFeedActions ? (
593 <div className="ghostkit-twitter-item-actions">
594 <div className="ghostkit-twitter-item-actions-retweet">
595 {/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}
596 <a
597 href={`https://twitter.com/${item.user.screen_name}/status/${item.id_str}`}
598 target="_blank"
599 rel="noopener noreferrer"
600 dangerouslySetInnerHTML={{
601 __html: `<svg class="ghostkit-svg-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M22 16L19 19L16 16" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M14 6L15.6667 6C16.5507 6 17.3986 6.30436 18.0237 6.84614C18.6488 7.38791 19 8.12271 19 8.88889L19 19" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M2 9L5 6L8 9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 19L8.33333 19C7.44928 19 6.60143 18.6956 5.97631 18.1539C5.35119 17.6121 5 16.8773 5 16.1111L5 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>${
602 item.retweet_count_short
603 ? `<span>${item.retweet_count_short}</span>`
604 : ''
605 }`,
606 }}
607 />
608 </div>
609 <div className="ghostkit-twitter-item-actions-like">
610 <ExternalLink
611 href={`https://twitter.com/${item.user.screen_name}/status/${item.id_str}`}
612 >
613 <svg
614 className="ghostkit-svg-icon"
615 width="24"
616 height="24"
617 viewBox="0 0 24 24"
618 fill="none"
619 xmlns="http://www.w3.org/2000/svg"
620 >
621 <path
622 d="M7.25 5C5.41421 5 3.5 6.66421 3.5 9C3.5 11.7695 5.57359 14.3251 7.86118 16.2727C8.98201 17.2269 10.1066 17.9947 10.9527 18.5245C11.375 18.7889 11.726 18.9928 11.9699 19.1298C11.9801 19.1356 11.9901 19.1412 12 19.1467C12.0098 19.1412 12.0199 19.1356 12.0301 19.1298C12.274 18.9928 12.625 18.7889 13.0473 18.5245C13.8934 17.9947 15.018 17.2269 16.1388 16.2727C18.4264 14.3251 20.5 11.7695 20.5 9C20.5 6.66421 18.5858 5 16.75 5C14.8879 5 13.3816 6.22683 12.7115 8.23717C12.6094 8.54343 12.3228 8.75 12 8.75C11.6772 8.75 11.3906 8.54343 11.2885 8.23717C10.6184 6.22683 9.11212 5 7.25 5ZM12 20C11.6574 20.6672 11.6572 20.6671 11.6569 20.6669L11.6479 20.6623L11.6251 20.6504C11.6057 20.6402 11.5777 20.6254 11.5418 20.6062C11.4699 20.5676 11.3662 20.5112 11.2352 20.4376C10.9732 20.2904 10.6016 20.0744 10.1567 19.7958C9.26844 19.2397 8.08049 18.4294 6.88882 17.4148C4.5514 15.4249 2 12.4805 2 9C2 5.83579 4.58579 3.5 7.25 3.5C9.30732 3.5 10.9728 4.57857 12 6.23441C13.0272 4.57857 14.6927 3.5 16.75 3.5C19.4142 3.5 22 5.83579 22 9C22 12.4805 19.4486 15.4249 17.1112 17.4148C15.9195 18.4294 14.7316 19.2397 13.8433 19.7958C13.3984 20.0744 13.0268 20.2904 12.7648 20.4376C12.6338 20.5112 12.5301 20.5676 12.4582 20.6062C12.4223 20.6254 12.3943 20.6402 12.3749 20.6504L12.3521 20.6623L12.3431 20.6669C12.3428 20.6671 12.3426 20.6672 12 20ZM12 20L12.3426 20.6672C12.1276 20.7776 11.8724 20.7776 11.6574 20.6672L12 20Z"
623 fill="currentColor"
624 />
625 </svg>
626 {item.favorite_count_short ? (
627 <span>
628 {
629 item.favorite_count_short
630 }
631 </span>
632 ) : null}
633 </ExternalLink>
634 </div>
635 </div>
636 ) : null}
637 </div>
638 </div>
639 );
640 })}
641 </div>
642 ) : null}
643 {APIDataReady && !twitterFeed ? (
644 <div className="ghostkit-twitter-spinner">
645 <Spinner />
646 </div>
647 ) : null}
648 {!APIDataReady ? (
649 <Placeholder
650 icon={getIcon('block-twitter')}
651 label={__('Twitter', 'ghostkit')}
652 instructions={__(
653 'A valid API data is required to use Twitter feed. You can fill it in the block settings in Inspector.',
654 'ghostkit'
655 )}
656 className={className}
657 />
658 ) : null}
659 </div>
660 </>
661 );
662 }
663