Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RNMobile] Add 'Insert from URL' option to Image block #40334

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e686dde
Add 'Insert from URL' option to Video and Image blocks
Apr 7, 2022
3b9afa3
Merge branch 'WordPress:trunk' into rnmobile/add-url-option-to-video-…
derekblank Apr 7, 2022
cec7316
Update code style from linting
derekblank Apr 11, 2022
0b48a73
Merge branch 'rnmobile/add-url-option-to-video-and-image-blocks' of h…
derekblank Apr 11, 2022
d56ab56
Improve test cases for Media Upload capture options
derekblank Apr 14, 2022
504eabf
Fix whitespace issue
derekblank Apr 14, 2022
d5394d0
Merge branch 'WordPress:trunk' into rnmobile/add-url-option-to-video-…
derekblank Apr 14, 2022
8b79cf1
Update Media Upload option tests to be asynchronous
derekblank Apr 21, 2022
c660f75
Merge branch 'rnmobile/add-url-option-to-video-and-image-blocks' of h…
derekblank Apr 21, 2022
760b9cf
Update native image block to use correct image URL
derekblank Apr 26, 2022
b3312b9
Add error handling for invalid URLs to native Image block
derekblank Apr 28, 2022
badb6e1
Clear invalid URL error on Image URL success
derekblank Apr 29, 2022
ee5456b
Fix synchronicity of Media Upload option tests
derekblank Apr 29, 2022
0e647c1
Add check for URL handler to native Image block picker options
derekblank May 5, 2022
4d33bb1
Update code style
derekblank May 5, 2022
aede9d3
Remove Video block from urlSource options
derekblank May 5, 2022
dbc6e23
Remove URL option from Video block for Media Upload test
derekblank May 5, 2022
07ee97d
Use Notice snackbar for native Image block error handling
derekblank May 6, 2022
7e8b6cb
Update Image/Media Upload code style and helpers
derekblank May 9, 2022
7995ef9
Use getImage to determine if URL is a valid image within Image block
derekblank May 13, 2022
344c340
Add loading indicator and isURL check to native Image block URL behavior
derekblank May 16, 2022
ee61ccb
Add loading indicator to native Image block media placeholder
derekblank May 18, 2022
a43fce1
Fix whitespace issue in native Image block code style
derekblank May 19, 2022
7b721c0
Reuse native Image block loading indicator
derekblank May 20, 2022
ae02763
Use undefined dimension attributes for the native Image block URL beh…
derekblank May 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const OPTION_TAKE_VIDEO = __( 'Take a Video' );
export const OPTION_TAKE_PHOTO = __( 'Take a Photo' );
export const OPTION_TAKE_PHOTO_OR_VIDEO = __( 'Take a Photo or Video' );
export const OPTION_INSERT_FROM_URL = __( 'Insert from URL' );
export const OPTION_WORDPRESS_MEDIA_LIBRARY = __( 'WordPress Media Library' );

const URL_MEDIA_SOURCE = 'URL';

Expand Down Expand Up @@ -78,6 +79,8 @@ export class MediaUpload extends Component {
}

getAllSources() {
const { onSelectURL } = this.props;

const cameraImageSource = {
id: mediaSources.deviceCamera, // ID is the value sent to native.
value: mediaSources.deviceCamera + '-IMAGE', // This is needed to diferenciate image-camera from video-camera sources.
Expand Down Expand Up @@ -124,16 +127,17 @@ export class MediaUpload extends Component {
id: URL_MEDIA_SOURCE,
value: URL_MEDIA_SOURCE,
label: __( 'Insert from URL' ),
types: [ MEDIA_TYPE_AUDIO ],
types: [ MEDIA_TYPE_AUDIO, MEDIA_TYPE_IMAGE ],
icon: globe,
};

// Only include `urlSource` option if `onSelectURL` prop is present, in order to match the web behavior.
const internalSources = [
deviceLibrarySource,
cameraImageSource,
cameraVideoSource,
siteLibrarySource,
urlSource,
...( onSelectURL ? [ urlSource ] : [] ),
];

return internalSources.concat( this.state.otherMediaOptions );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
OPTION_TAKE_VIDEO,
OPTION_TAKE_PHOTO,
OPTION_INSERT_FROM_URL,
OPTION_WORDPRESS_MEDIA_LIBRARY,
} from '../index';

const MEDIA_URL = 'http://host.media.type';
Expand All @@ -33,8 +34,11 @@ describe( 'MediaUpload component', () => {
expect( wrapper ).toBeTruthy();
} );

it( 'shows right media capture option for media type', () => {
const expectOptionForMediaType = ( mediaType, expectedOption ) => {
describe( 'Media capture options for different media block types', () => {
const expectOptionForMediaType = async (
mediaType,
expectedOptions
) => {
const wrapper = render(
<MediaUpload
allowedTypes={ [ mediaType ] }
Expand All @@ -52,11 +56,32 @@ describe( 'MediaUpload component', () => {
);
fireEvent.press( wrapper.getByText( 'Open Picker' ) );

wrapper.getByText( expectedOption );
expectedOptions.forEach( ( item ) => {
const option = wrapper.getByText( item );
expect( option ).toBeVisible();
} );
};
expectOptionForMediaType( MEDIA_TYPE_IMAGE, OPTION_TAKE_PHOTO );
expectOptionForMediaType( MEDIA_TYPE_VIDEO, OPTION_TAKE_VIDEO );
expectOptionForMediaType( MEDIA_TYPE_AUDIO, OPTION_INSERT_FROM_URL );

it( 'shows the correct media capture options for the Image block', () => {
expectOptionForMediaType( MEDIA_TYPE_IMAGE, [
OPTION_TAKE_PHOTO,
OPTION_WORDPRESS_MEDIA_LIBRARY,
OPTION_INSERT_FROM_URL,
] );
} );

it( 'shows the correct media capture options for the Video block', () => {
expectOptionForMediaType( MEDIA_TYPE_VIDEO, [
OPTION_TAKE_VIDEO,
OPTION_WORDPRESS_MEDIA_LIBRARY,
] );
} );

it( 'shows the correct media capture options for the Audio block', () => {
expectOptionForMediaType( MEDIA_TYPE_AUDIO, [
OPTION_INSERT_FROM_URL,
] );
} );
} );

const expectMediaPickerForOption = (
Expand Down
68 changes: 65 additions & 3 deletions packages/block-library/src/image/edit.native.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/**
* External dependencies
*/
import { View, TouchableWithoutFeedback } from 'react-native';
import {
ActivityIndicator,
Image as RNImage,
TouchableWithoutFeedback,
View,
} from 'react-native';
import { useRoute } from '@react-navigation/native';

/**
Expand Down Expand Up @@ -45,7 +50,7 @@ import {
blockSettingsScreens,
} from '@wordpress/block-editor';
import { __, _x, sprintf } from '@wordpress/i18n';
import { getProtocol, hasQueryArg } from '@wordpress/url';
import { getProtocol, hasQueryArg, isURL } from '@wordpress/url';
import { doAction, hasAction } from '@wordpress/hooks';
import { compose, withPreferredColorScheme } from '@wordpress/compose';
import { withSelect, withDispatch } from '@wordpress/data';
Expand All @@ -57,6 +62,7 @@ import {
} from '@wordpress/icons';
import { store as coreStore } from '@wordpress/core-data';
import { store as editPostStore } from '@wordpress/edit-post';
import { store as noticesStore } from '@wordpress/notices';

/**
* Internal dependencies
Expand Down Expand Up @@ -207,6 +213,7 @@ export class ImageEdit extends Component {
this.onImagePressed = this.onImagePressed.bind( this );
this.onSetFeatured = this.onSetFeatured.bind( this );
this.onFocusCaption = this.onFocusCaption.bind( this );
this.onSelectURL = this.onSelectURL.bind( this );
this.updateAlignment = this.updateAlignment.bind( this );
this.accessibilityLabelCreator = this.accessibilityLabelCreator.bind(
this
Expand Down Expand Up @@ -461,6 +468,45 @@ export class ImageEdit extends Component {
} );
}

onSelectURL( newURL ) {
const {
createErrorNotice,
imageDefaultSize,
setAttributes,
} = this.props;

if ( isURL( newURL ) ) {
this.setState( {
isFetchingImage: true,
} );

// Use RN's Image.getSize to determine if URL is a valid image
RNImage.getSize(
newURL,
() => {
setAttributes( {
url: newURL,
id: undefined,
width: undefined,
height: undefined,
sizeSlug: imageDefaultSize,
} );
this.setState( {
isFetchingImage: false,
} );
},
() => {
createErrorNotice( __( 'Image file not found.' ) );
this.setState( {
isFetchingImage: false,
} );
}
);
} else {
createErrorNotice( __( 'Invalid URL.' ) );
}
}

onFocusCaption() {
if ( this.props.onFocus ) {
this.props.onFocus();
Expand All @@ -484,6 +530,14 @@ export class ImageEdit extends Component {
);
}

showLoadingIndicator() {
return (
<View style={ styles.image__loading }>
<ActivityIndicator animating />
</View>
);
}

getWidth() {
const { attributes } = this.props;
const { align, width } = attributes;
Expand Down Expand Up @@ -611,7 +665,7 @@ export class ImageEdit extends Component {
}

render() {
const { isCaptionSelected } = this.state;
const { isCaptionSelected, isFetchingImage } = this.state;
const {
attributes,
isSelected,
Expand Down Expand Up @@ -713,9 +767,11 @@ export class ImageEdit extends Component {
if ( ! url ) {
return (
<View style={ styles.content }>
{ isFetchingImage && this.showLoadingIndicator() }
<MediaPlaceholder
allowedTypes={ [ MEDIA_TYPE_IMAGE ] }
onSelect={ this.onSelectMediaUploadOption }
onSelectURL={ this.onSelectURL }
icon={ this.getPlaceholderIcon() }
onFocus={ this.props.onFocus }
autoOpenMediaUpload={
Expand Down Expand Up @@ -785,6 +841,8 @@ export class ImageEdit extends Component {
} ) => {
return (
<View style={ imageContainerStyles }>
{ isFetchingImage &&
this.showLoadingIndicator() }
<Image
align={
align && alignToFlex[ align ]
Expand Down Expand Up @@ -837,6 +895,7 @@ export class ImageEdit extends Component {
allowedTypes={ [ MEDIA_TYPE_IMAGE ] }
isReplacingMedia={ true }
onSelect={ this.onSelectMediaUploadOption }
onSelectURL={ this.onSelectURL }
render={ ( { open, getMediaOptions } ) => {
return getImageComponent( open, getMediaOptions );
} }
Expand Down Expand Up @@ -882,7 +941,10 @@ export default compose( [
};
} ),
withDispatch( ( dispatch ) => {
const { createErrorNotice } = dispatch( noticesStore );

return {
createErrorNotice,
closeSettingsBottomSheet() {
dispatch( editPostStore ).closeGeneralSidebar();
},
Expand Down
11 changes: 11 additions & 0 deletions packages/block-library/src/image/styles.native.scss
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,14 @@
.removeFeaturedButton {
color: $alert-red;
}

.image__loading {
align-items: center;
background-color: rgba(10, 10, 10, 0.5);
flex: 1;
height: 100%;
justify-content: center;
position: absolute;
width: 100%;
z-index: 1;
}