From 87a696eac7ffc224d883350d0394ad29116a929b Mon Sep 17 00:00:00 2001 From: Enej Bajgoric Date: Tue, 6 Jul 2021 22:15:11 -0700 Subject: [PATCH] Mobile: update image size picker (#31963) * Update Bottom Sheet Select Control to accept a label icon * Update the Image block to use Bottom Sheet Select Control * Minor code fixes * Fix code style * Make sure that we always recalculate the possible sizeOptions. Before we calculating the sizeOptions in the constructor which didn't happen often enough. And caused an issue when you first inserted the image. * Remove lodash find, isEmpty, map and filter * Double check that we are dealing with arrays before proceeding. * Use the same icon - fullscreen --- .../block-library/src/image/edit.native.js | 58 ++++++++++++------- .../bottom-sheet-select-control/README.md | 7 +++ .../index.native.js | 2 + 3 files changed, 47 insertions(+), 20 deletions(-) diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index da026f95422769..5ea885333ad69a 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -2,7 +2,6 @@ * External dependencies */ import { View, TouchableWithoutFeedback, Platform } from 'react-native'; -import { isEmpty, get, find, map } from 'lodash'; /** * WordPress dependencies @@ -17,7 +16,6 @@ import { setFeaturedImage, } from '@wordpress/react-native-bridge'; import { - CycleSelectControl, Icon, PanelBody, ToolbarButton, @@ -27,6 +25,7 @@ import { LinkSettingsNavigation, BottomSheet, BottomSheetTextControl, + BottomSheetSelectControl, FooterMessageLink, Badge, } from '@wordpress/components'; @@ -67,8 +66,11 @@ import { MEDIA_ID_NO_FEATURED_IMAGE_SET, } from './constants'; -const getUrlForSlug = ( image, { sizeSlug } ) => { - return get( image, [ 'media_details', 'sizes', sizeSlug, 'source_url' ] ); +const getUrlForSlug = ( image, sizeSlug ) => { + if ( ! sizeSlug ) { + return undefined; + } + return image?.media_details?.sizes?.[ sizeSlug ]?.source_url; }; export class ImageEdit extends Component { @@ -119,11 +121,6 @@ export class ImageEdit extends Component { placeholder: __( 'None' ), }, }; - - this.sizeOptions = map( this.props.imageSizes, ( { name, slug } ) => ( { - value: slug, - name, - } ) ); } componentDidMount() { @@ -176,7 +173,9 @@ export class ImageEdit extends Component { componentDidUpdate( previousProps ) { if ( ! previousProps.image && this.props.image ) { const { image, attributes } = this.props; - const url = getUrlForSlug( image, attributes ) || image.source_url; + const url = + getUrlForSlug( image, attributes?.sizeSlug ) || + image.source_url; this.props.setAttributes( { url } ); } } @@ -190,7 +189,10 @@ export class ImageEdit extends Component { } accessibilityLabelCreator( caption ) { - return isEmpty( caption ) + // Checks if caption is empty. + return ( typeof caption === 'string' && caption.trim().length === 0 ) || + caption === undefined || + caption === null ? /* translators: accessibility text. Empty image caption. */ 'Image caption. Empty' : sprintf( @@ -292,7 +294,7 @@ export class ImageEdit extends Component { onSetSizeSlug( sizeSlug ) { const { image } = this.props; - const url = getUrlForSlug( image, { sizeSlug } ); + const url = getUrlForSlug( image, sizeSlug ); if ( ! url ) { return null; } @@ -494,10 +496,26 @@ export class ImageEdit extends Component { } = this.props; const { align, url, alt, id, sizeSlug, className } = attributes; - const sizeOptionsValid = find( this.sizeOptions, [ - 'value', - imageDefaultSize, - ] ); + const imageSizes = Array.isArray( this.props.imageSizes ) + ? this.props.imageSizes + : []; + // Only map available image sizes for the user to choose. + const sizeOptions = imageSizes + .filter( ( { slug } ) => getUrlForSlug( image, slug ) ) + .map( ( { name, slug } ) => ( { value: slug, label: name } ) ); + + let selectedSizeOption = sizeSlug || imageDefaultSize; + let sizeOptionsValid = sizeOptions.find( + ( option ) => option.value === selectedSizeOption + ); + + if ( ! sizeOptionsValid ) { + // Default to 'full' size if the default large size is not available. + sizeOptionsValid = sizeOptions.find( + ( option ) => option.value === 'full' + ); + selectedSizeOption = 'full'; + } // By default, it's only possible to set images that have been uploaded to a site's library as featured. // Images that haven't been uploaded to a site's library have an id of 'undefined', which the 'canImageBeFeatured' check filters out. @@ -533,12 +551,12 @@ export class ImageEdit extends Component { { image && sizeOptionsValid && ( - ) } { this.getAltTextSettings() } diff --git a/packages/components/src/mobile/bottom-sheet-select-control/README.md b/packages/components/src/mobile/bottom-sheet-select-control/README.md index 1eeb6b99bfcaab..ed940baa53409f 100644 --- a/packages/components/src/mobile/bottom-sheet-select-control/README.md +++ b/packages/components/src/mobile/bottom-sheet-select-control/README.md @@ -88,3 +88,10 @@ Can be used to externally control the value of the control, like in the `MyContr - Type: `Object` - Required: No + +#### icon + +The icon for the control. + +- Type: `Icon component` +- Required: No \ No newline at end of file diff --git a/packages/components/src/mobile/bottom-sheet-select-control/index.native.js b/packages/components/src/mobile/bottom-sheet-select-control/index.native.js index 3df7f185c77103..5f2ec0aee79979 100644 --- a/packages/components/src/mobile/bottom-sheet-select-control/index.native.js +++ b/packages/components/src/mobile/bottom-sheet-select-control/index.native.js @@ -18,6 +18,7 @@ import styles from './style.scss'; const BottomSheetSelectControl = ( { label, + icon, options: items, onChange, value: selectedValue, @@ -52,6 +53,7 @@ const BottomSheetSelectControl = ( {