Skip to content

Commit

Permalink
[RNMobile] Embed block - Link in Block Settings (#36099)
Browse files Browse the repository at this point in the history
* Created a native version of embed-controls

* added withBottomSheet flag so embed link works in both modes.

* integrate EmbedBottomSheet with EmbedControls in Embed functionality

* Removed the edit button from the toolbar. Removed all related code.

* onClose calls onDismiss to perform necessary url validation & submission

* the responsive condition should encapsulate the media settings only.

* utilize the LinkPicker when the Embed URL is being edited.

* Removed unneeded className in the native embed-controls.

* Added entry to the CHANGELOG.

* Refactor EmbedBottomSheet component

The EmbedBottomSheet component has been also renamed to EmbedLinkSettings because the component is no longer strictly tied to the bottom sheet component.

* Added Edit Link functionality to Error Picker options.

* Update url when value changes

* Utilized the Block Settings Bottom Sheet for tests that are editing URL

* Removed unneeded whiteline

* Fix indentation and lint issues

* Use within to query edit link field

* Update responsive not supported test case

* Expect for link field instead block settings button

This change prevents potential act warnings after setting a URL in an empty embed block.

* Invalidate core-data store before each test

* Expect for link field instead block settings button in more tests

* Add comments to test actions

* Add set empty URL test case

* Add edit URL when request fails test case

* Created a ref to store if the onCloseSettingsSheet is consumed.

* Added "modal" to  "block-settings" TestId to make "block-settings-modal"

* onCloseSettingsSheetConsumed is set to false when isVisible is true.

* Added CHANGELOG entry to the unreleased section.

Co-authored-by: Carlos Garcia <[email protected]>
  • Loading branch information
jd-alexander and fluiddot authored Nov 12, 2021
1 parent 23412da commit 80db388
Show file tree
Hide file tree
Showing 10 changed files with 437 additions and 184 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ function BottomSheetSettings( {
hideHeader
contentStyle={ styles.content }
hasNavigation
testID="block-settings-modal"
{ ...props }
>
<BottomSheet.NavigationContainer animate main>
Expand Down
41 changes: 23 additions & 18 deletions packages/block-library/src/embed/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { embedContentIcon } from './icons';
import EmbedLoading from './embed-loading';
import EmbedPlaceholder from './embed-placeholder';
import EmbedPreview from './embed-preview';
import EmbedBottomSheet from './embed-bottom-sheet';
import EmbedLinkSettings from './embed-link-settings';

/**
* External dependencies
Expand All @@ -24,7 +24,7 @@ import classnames from 'classnames';
* WordPress dependencies
*/
import { _x } from '@wordpress/i18n';
import { useState, useEffect } from '@wordpress/element';
import { useCallback, useState, useEffect } from '@wordpress/element';
import { useDispatch, useSelect } from '@wordpress/data';
import {
useBlockProps,
Expand Down Expand Up @@ -196,6 +196,14 @@ const EmbedEdit = ( props ) => {
isEditingURL,
] );

const onEditURL = useCallback( ( value ) => {
// The order of the following calls is important, we need to update the URL attribute before changing `isEditingURL`,
// otherwise the side-effect that potentially replaces the block when updating the local state won't use the new URL
// for creating the new block.
setAttributes( { url: value } );
setIsEditingURL( false );
}, [] );

const blockProps = useBlockProps();

if ( fetching ) {
Expand Down Expand Up @@ -230,16 +238,12 @@ const EmbedEdit = ( props ) => {
( WP_EMBED_TYPE === type &&
! NOT_PREVIEWABLE_WP_EMBED_PROVIDERS.includes( providerNameSlug ) );

const bottomSheetLabel = WP_EMBED_TYPE === type ? 'WordPress' : title;
const linkLabel = WP_EMBED_TYPE === type ? 'WordPress' : title;

return (
<>
{ showEmbedPlaceholder ? (
<>
<EmbedControls
showEditButton={ cannotEmbed }
switchBackToURLInput={ () => setIsEditingURL( true ) }
/>
<View { ...blockProps }>
<EmbedPlaceholder
icon={ icon }
Expand All @@ -256,18 +260,22 @@ const EmbedEdit = ( props ) => {
url,
] );
} }
openEmbedLinkSettings={ () =>
setShowEmbedBottomSheet( true )
}
/>
</View>
</>
) : (
<>
<EmbedControls
showEditButton={ preview && ! cannotEmbed }
themeSupportsResponsive={ themeSupportsResponsive }
blockSupportsResponsive={ responsive }
allowResponsive={ allowResponsive }
toggleResponsive={ toggleResponsive }
switchBackToURLInput={ () => setIsEditingURL( true ) }
url={ url }
linkLabel={ linkLabel }
onEditURL={ onEditURL }
/>
<View { ...blockProps }>
<EmbedPreview
Expand All @@ -289,18 +297,15 @@ const EmbedEdit = ( props ) => {
</View>
</>
) }
<EmbedBottomSheet
<EmbedLinkSettings
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus
value={ url }
label={ bottomSheetLabel }
label={ linkLabel }
isVisible={ showEmbedBottomSheet }
onClose={ () => setShowEmbedBottomSheet( false ) }
onSubmit={ ( value ) => {
// The order of the following calls is important, we need to update the URL attribute before changing `isEditingURL`,
// otherwise the side-effect that potentially replaces the block when updating the local state won't use the new URL
// for creating the new block.
setAttributes( { url: value } );
setIsEditingURL( false );
} }
onSubmit={ onEditURL }
withBottomSheet
/>
</>
);
Expand Down
78 changes: 0 additions & 78 deletions packages/block-library/src/embed/embed-bottom-sheet.native.js

This file was deleted.

65 changes: 65 additions & 0 deletions packages/block-library/src/embed/embed-controls.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Internal dependencies
*/
import EmbedLinkSettings from './embed-link-settings';
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { PanelBody, ToggleControl } from '@wordpress/components';
import { InspectorControls } from '@wordpress/block-editor';
import { useDispatch } from '@wordpress/data';
import { store as editPostStore } from '@wordpress/edit-post';

function getResponsiveHelp( checked ) {
return checked
? __(
'This embed will preserve its aspect ratio when the browser is resized.'
)
: __(
'This embed may not preserve its aspect ratio when the browser is resized.'
);
}

const EmbedControls = ( {
blockSupportsResponsive,
themeSupportsResponsive,
allowResponsive,
toggleResponsive,
url,
linkLabel,
onEditURL,
} ) => {
const { closeGeneralSidebar: closeSettingsBottomSheet } = useDispatch(
editPostStore
);

return (
<>
<InspectorControls>
{ themeSupportsResponsive && blockSupportsResponsive && (
<PanelBody title={ __( 'Media settings' ) }>
<ToggleControl
label={ __( 'Resize for smaller devices' ) }
checked={ allowResponsive }
help={ getResponsiveHelp }
onChange={ toggleResponsive }
/>
</PanelBody>
) }
<PanelBody title={ __( 'Link settings' ) }>
<EmbedLinkSettings
value={ url }
label={ linkLabel }
onSubmit={ ( value ) => {
closeSettingsBottomSheet();
onEditURL( value );
} }
/>
</PanelBody>
</InspectorControls>
</>
);
};

export default EmbedControls;
100 changes: 100 additions & 0 deletions packages/block-library/src/embed/embed-link-settings.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* WordPress dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import {
LinkSettingsNavigation,
FooterMessageLink,
} from '@wordpress/components';
import { isURL } from '@wordpress/url';
import { useDispatch } from '@wordpress/data';
import { store as noticesStore } from '@wordpress/notices';
import { useCallback, useEffect, useRef, useState } from '@wordpress/element';

const EmbedLinkSettings = ( {
autoFocus,
value,
label,
isVisible,
onClose,
onSubmit,
withBottomSheet,
} ) => {
const url = useRef( value );
const [ inputURL, setInputURL ] = useState( value );
const { createErrorNotice } = useDispatch( noticesStore );

const linkSettingsOptions = {
url: {
label: sprintf(
// translators: %s: embed block variant's label e.g: "Twitter".
__( '%s link' ),
label
),
placeholder: __( 'Add link' ),
autoFocus,
autoFill: true,
},
footer: {
label: (
<FooterMessageLink
href={ __(
'https://wordpress.org/support/article/embeds/'
) }
value={ __( 'Learn more about embeds' ) }
/>
),
separatorType: 'topFullWidth',
},
};

const onDismiss = useCallback( () => {
if ( ! isURL( url.current ) && url.current !== '' ) {
createErrorNotice( __( 'Invalid URL. Please enter a valid URL.' ) );
// If the URL was already defined, we submit it to stop showing the embed placeholder.
onSubmit( value );
return;
}
onSubmit( url.current );
}, [ onSubmit, value ] );

useEffect( () => {
url.current = value;
setInputURL( value );
}, [ value ] );

/**
* If the Embed Bottom Sheet component does not utilize a bottom sheet then the onDismiss action is not
* called. Here we are wiring the onDismiss to the onClose callback that gets triggered when input is submitted.
*/
const performOnCloseOperations = useCallback( () => {
if ( onClose ) {
onClose();
}

if ( ! withBottomSheet ) {
onDismiss();
}
}, [ onClose ] );

const onSetAttributes = useCallback( ( attributes ) => {
url.current = attributes.url;
setInputURL( attributes.url );
}, [] );

return (
<LinkSettingsNavigation
isVisible={ isVisible }
url={ inputURL }
onClose={ performOnCloseOperations }
onDismiss={ onDismiss }
setAttributes={ onSetAttributes }
options={ linkSettingsOptions }
testID="embed-edit-url-modal"
withBottomSheet={ withBottomSheet }
showIcon
/>
);
};

export default EmbedLinkSettings;
8 changes: 8 additions & 0 deletions packages/block-library/src/embed/embed-placeholder.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const EmbedPlaceholder = ( {
cannotEmbed,
fallback,
tryAgain,
openEmbedLinkSettings,
} ) => {
const containerStyle = usePreferredColorSchemeStyle(
styles.embed__container,
Expand Down Expand Up @@ -59,11 +60,18 @@ const EmbedPlaceholder = ( {
value: 'convertToLinkOption',
onSelect: fallback,
},
editLink: {
id: 'editLinkOption',
label: __( 'Edit link' ),
value: 'editLinkOption',
onSelect: openEmbedLinkSettings,
},
};

const options = compact( [
cannotEmbed && errorPickerOptions.retry,
cannotEmbed && errorPickerOptions.convertToLink,
cannotEmbed && errorPickerOptions.editLink,
] );

function onPickerSelect( value ) {
Expand Down
Loading

0 comments on commit 80db388

Please sign in to comment.