diff --git a/projects/plugins/jetpack/changelog/update-bump-block-api-version-2 b/projects/plugins/jetpack/changelog/update-bump-block-api-version-2 new file mode 100644 index 0000000000000..1e161d08a2531 --- /dev/null +++ b/projects/plugins/jetpack/changelog/update-bump-block-api-version-2 @@ -0,0 +1,4 @@ +Significance: patch +Type: other + +Eventbrite Block: refactor Edit component to function diff --git a/projects/plugins/jetpack/extensions/blocks/eventbrite/controls.js b/projects/plugins/jetpack/extensions/blocks/eventbrite/controls.js index 2ebca800b35ab..73a0f43fcd943 100644 --- a/projects/plugins/jetpack/extensions/blocks/eventbrite/controls.js +++ b/projects/plugins/jetpack/extensions/blocks/eventbrite/controls.js @@ -1,5 +1,26 @@ import { ToolbarButton, ToolbarGroup } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; +import { __, _x } from '@wordpress/i18n'; +import BlockStylesSelector from '../../shared/components/block-styles-selector'; +import EventbriteInPageExample from './eventbrite-in-page-example.png'; + +const embedTypes = [ + { + value: 'inline', + label: __( 'In-page Embed', 'jetpack' ), + preview: ( +
+ { +
+ ), + }, + { + value: 'modal', + label: __( 'Button & Modal', 'jetpack' ), + }, +]; export const ToolbarControls = ( { setEditingUrl } ) => ( @@ -11,3 +32,19 @@ export const ToolbarControls = ( { setEditingUrl } ) => ( /> ); + +export const InspectorControls = ( { attributes, clientId, setAttributes } ) => ( + +); diff --git a/projects/plugins/jetpack/extensions/blocks/eventbrite/edit.js b/projects/plugins/jetpack/extensions/blocks/eventbrite/edit.js index 40e50958bae47..775a44114909f 100644 --- a/projects/plugins/jetpack/extensions/blocks/eventbrite/edit.js +++ b/projects/plugins/jetpack/extensions/blocks/eventbrite/edit.js @@ -1,31 +1,19 @@ -import { - isAtomicSite, - isSimpleSite, - getBlockIconComponent, -} from '@automattic/jetpack-shared-extension-utils'; import { BlockControls, InnerBlocks } from '@wordpress/block-editor'; -import { - Placeholder, - SandBox, - Button, - Spinner, - ExternalLink, - withNotices, -} from '@wordpress/components'; -import { Component } from '@wordpress/element'; +import { Button, withNotices } from '@wordpress/components'; import { __, _x } from '@wordpress/i18n'; -import BlockStylesSelector from '../../shared/components/block-styles-selector'; +import { useCallback, useEffect, useState } from 'react'; import { getValidatedAttributes } from '../../shared/get-validated-attributes'; import testEmbedUrl from '../../shared/test-embed-url'; import metadata from './block.json'; import { EVENTBRITE_EXAMPLE_URL, URL_REGEX } from './constants'; -import { ToolbarControls } from './controls'; -import EventbriteInPageExample from './eventbrite-in-page-example.png'; +import { ToolbarControls, InspectorControls } from './controls'; +import EmbedForm from './form'; +import Loader from './loader'; +import InlinePreview from './preview'; import { convertToLink, eventIdFromUrl, normalizeUrlInput } from './utils'; import './editor.scss'; -const icon = getBlockIconComponent( metadata ); const innerButtonBlock = { name: 'jetpack/button', attributes: { @@ -34,61 +22,18 @@ const innerButtonBlock = { uniqueId: 'eventbrite-widget-id', }, }; -export class EventbriteEdit extends Component { - state = { - editedUrl: this.props.attributes.url || '', - editingUrl: false, - isResolvingUrl: false, - }; - componentDidMount() { - const { url } = this.props.attributes; +export const EventbriteEdit = props => { + const { attributes, noticeOperations, onReplace, setAttributes } = props; + const { url, style } = attributes; - this.setUrl( url ); - } - - setUrl = url => { - const { attributes, noticeOperations, setAttributes } = this.props; - const { style } = attributes; - - if ( ! url || EVENTBRITE_EXAMPLE_URL === url || 'modal' === style ) { - return; - } - - const eventId = eventIdFromUrl( url ); - - if ( ! eventId ) { - this.setErrorNotice(); - } else { - const newAttributes = { - eventId, - url, - }; + const [ editingUrl, setEditingUrl ] = useState( false ); + const [ editedUrl, setEditedUrl ] = useState( attributes.url || '' ); + const [ isResolvingUrl, setIsResolvingUrl ] = useState( false ); - testEmbedUrl( newAttributes.url, this.setIsResolvingUrl ) - .then( resolvedUrl => { - const newValidatedAttributes = getValidatedAttributes( metadata.attributes, { - ...newAttributes, - url: resolvedUrl, - } ); - setAttributes( newValidatedAttributes ); - this.setState( { editedUrl: resolvedUrl } ); - noticeOperations.removeAllNotices(); - } ) - .catch( () => { - setAttributes( { eventId: undefined, url: undefined } ); - this.setErrorNotice(); - } ); - } - }; - - setIsResolvingUrl = isResolvingUrl => this.setState( { isResolvingUrl } ); - setEditingUrl = editingUrl => this.setState( { editingUrl } ); - - setErrorNotice = () => { - const { noticeOperations, onReplace } = this.props; - const { editedUrl } = this.state; + const cannotEmbed = ! isResolvingUrl && url && ! URL_REGEX.test( url ); + const setErrorNotice = useCallback( () => { noticeOperations.removeAllNotices(); noticeOperations.createErrorNotice( <> @@ -98,181 +43,73 @@ export class EventbriteEdit extends Component { ); - }; - - submitForm = event => { - if ( event ) { - event.preventDefault(); - } - - this.setUrl( normalizeUrlInput( this.state.editedUrl ) ); - - this.setState( { editingUrl: false } ); - }; - - cannotEmbed = () => { - const { url } = this.props.attributes; - const { isResolvingUrl } = this.state; - - return ! isResolvingUrl && url && ! URL_REGEX.test( url ); - }; - - renderLoading() { - return ( -
- -

{ __( 'Embedding…', 'jetpack' ) }

-
- ); - } - - renderInspectorControls() { - const { style } = this.props.attributes; - const { attributes, clientId, setAttributes } = this.props; - - const embedTypes = [ - { - value: 'inline', - label: __( 'In-page Embed', 'jetpack' ), - preview: ( -
- { -
- ), - }, - { - value: 'modal', - label: __( 'Button & Modal', 'jetpack' ), - }, - ]; - - return ( - { + if ( ! str || EVENTBRITE_EXAMPLE_URL === str || 'modal' === style ) { + return; + } + + const eventId = eventIdFromUrl( str ); + + if ( ! eventId ) { + setErrorNotice(); + } else { + const newAttributes = { + eventId, + url: str, + }; + + testEmbedUrl( newAttributes.url, setIsResolvingUrl ) + .then( resolvedUrl => { + const newValidatedAttributes = getValidatedAttributes( metadata.attributes, { + ...newAttributes, + url: resolvedUrl, + } ); + setAttributes( newValidatedAttributes ); + setEditedUrl( resolvedUrl ); + noticeOperations.removeAllNotices(); + } ) + .catch( () => { + setAttributes( { eventId: undefined, url: undefined } ); + setErrorNotice(); + } ); + } + }, + [ style, noticeOperations, setErrorNotice, setAttributes, setEditedUrl, setIsResolvingUrl ] + ); + + useEffect( () => { + setUrl( url ); + }, [ url, setUrl ] ); + + let content; + + if ( isResolvingUrl ) { + content = ; + } else if ( editingUrl || ! url || cannotEmbed ) { + content = ( + setEditedUrl( e.target.value ) } + onSubmit={ e => { + if ( e ) { + e.preventDefault(); + } + + setUrl( normalizeUrlInput( editedUrl ) ); + setEditingUrl( false ); + } } /> ); - } - - renderEditEmbed() { - const { className, noticeUI } = this.props; - const { editedUrl } = this.state; - const supportLink = - isSimpleSite() || isAtomicSite() - ? 'http://support.wordpress.com/wordpress-editor/blocks/eventbrite-block/' - : 'https://jetpack.com/support/jetpack-blocks/eventbrite-block/'; - - return ( -
- -
- this.setState( { editedUrl: event.target.value } ) } - /> - -
- -
- - { __( 'Learn more about Eventbrite embeds', 'jetpack' ) } - -
-
-
- ); - } - - renderInlinePreview() { - const { className } = this.props; - const { eventId } = this.props.attributes; - - if ( ! eventId ) { - return; - } - - const widgetId = `eventbrite-widget-${ eventId }`; - const html = ` - - - -
- `; - - return ( -
- - { /* Use an overlay to prevent interactivity with the preview, since the preview does not always resize correctly. */ } -
-
- ); - } - - /** - * Render a preview of the Eventbrite embed. - * - * @returns {object} The UI displayed when user edits this block. - */ - render() { - const { attributes } = this.props; - const { url, style } = attributes; - const { editingUrl, isResolvingUrl } = this.state; - - if ( isResolvingUrl ) { - return this.renderLoading(); - } - - if ( editingUrl || ! url || this.cannotEmbed() ) { - return this.renderEditEmbed(); - } - - return ( + } else { + content = ( <> - { this.renderInspectorControls() } + - + { style === 'modal' ? ( ) : ( - this.renderInlinePreview() + ) } ); } -} + + return
{ content }
; +}; export default withNotices( EventbriteEdit ); diff --git a/projects/plugins/jetpack/extensions/blocks/eventbrite/form.js b/projects/plugins/jetpack/extensions/blocks/eventbrite/form.js new file mode 100644 index 0000000000000..1cac0e6751c64 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/eventbrite/form.js @@ -0,0 +1,54 @@ +import { + isAtomicSite, + isSimpleSite, + getBlockIconComponent, +} from '@automattic/jetpack-shared-extension-utils'; +import { Placeholder, Button, ExternalLink } from '@wordpress/components'; +import { __, _x } from '@wordpress/i18n'; +import metadata from './block.json'; +import {} from './utils'; + +const icon = getBlockIconComponent( metadata ); + +const EmbedForm = ( { className, noticeUI, editedUrl, onChange, onSubmit } ) => { + const supportLink = + isSimpleSite() || isAtomicSite() + ? 'http://support.wordpress.com/wordpress-editor/blocks/eventbrite-block/' + : 'https://jetpack.com/support/jetpack-blocks/eventbrite-block/'; + + return ( +
+ +
+ + +
+ +
+ + { __( 'Learn more about Eventbrite embeds', 'jetpack' ) } + +
+
+
+ ); +}; + +export default EmbedForm; diff --git a/projects/plugins/jetpack/extensions/blocks/eventbrite/loader.js b/projects/plugins/jetpack/extensions/blocks/eventbrite/loader.js new file mode 100644 index 0000000000000..a1b8bcef69b2d --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/eventbrite/loader.js @@ -0,0 +1,13 @@ +import { Spinner } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; + +const Loader = () => { + return ( +
+ +

{ __( 'Embedding…', 'jetpack' ) }

+
+ ); +}; + +export default Loader; diff --git a/projects/plugins/jetpack/extensions/blocks/eventbrite/preview.js b/projects/plugins/jetpack/extensions/blocks/eventbrite/preview.js new file mode 100644 index 0000000000000..81abe3ce642b2 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/eventbrite/preview.js @@ -0,0 +1,43 @@ +import { SandBox } from '@wordpress/components'; + +const InlinePreview = ( { className, attributes } ) => { + const { eventId } = attributes; + + if ( ! eventId ) { + return; + } + + const widgetId = `eventbrite-widget-${ eventId }`; + const html = ` + + + +
+ `; + + return ( +
+ + { /* Use an overlay to prevent interactivity with the preview, since the preview does not always resize correctly. */ } +
+
+ ); +}; + +export default InlinePreview; diff --git a/projects/plugins/jetpack/extensions/blocks/eventbrite/save.js b/projects/plugins/jetpack/extensions/blocks/eventbrite/save.js index 3a68ff6fd8312..6f64e3a9ec352 100644 --- a/projects/plugins/jetpack/extensions/blocks/eventbrite/save.js +++ b/projects/plugins/jetpack/extensions/blocks/eventbrite/save.js @@ -1,4 +1,3 @@ -/* eslint-disable jsdoc/require-jsdoc */ import { InnerBlocks } from '@wordpress/block-editor'; export default function save( { attributes } ) {