diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index 7413978f2e0123..fe3fa7c54d2e15 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -2,27 +2,31 @@ * External dependencies */ import React from 'react'; -import { View, Image, TextInput } from 'react-native'; +import { View, ImageBackground, TextInput, Text, TouchableWithoutFeedback } from 'react-native'; import { subscribeMediaUpload, requestMediaPickFromMediaLibrary, requestMediaPickFromDeviceLibrary, requestMediaPickFromDeviceCamera, mediaUploadSync, + requestImageFailedRetryDialog, + requestImageUploadCancelDialog, } from 'react-native-gutenberg-bridge'; /** * Internal dependencies */ import { MediaPlaceholder, RichText, BlockControls, InspectorControls } from '@wordpress/editor'; -import { Toolbar, ToolbarButton, Spinner } from '@wordpress/components'; +import { Toolbar, ToolbarButton, Spinner, Dashicon } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import ImageSize from './image-size'; import { isURL } from '@wordpress/url'; +import styles from './styles.scss'; -const MEDIA_ULOAD_STATE_UPLOADING = 1; -const MEDIA_ULOAD_STATE_SUCCEEDED = 2; -const MEDIA_ULOAD_STATE_FAILED = 3; +const MEDIA_UPLOAD_STATE_UPLOADING = 1; +const MEDIA_UPLOAD_STATE_SUCCEEDED = 2; +const MEDIA_UPLOAD_STATE_FAILED = 3; +const MEDIA_UPLOAD_STATE_RESET = 4; export default class ImageEdit extends React.Component { constructor( props ) { @@ -31,6 +35,7 @@ export default class ImageEdit extends React.Component { this.state = { progress: 0, isUploadInProgress: false, + isUploadFailed: false, }; this.mediaUpload = this.mediaUpload.bind( this ); @@ -38,6 +43,7 @@ export default class ImageEdit extends React.Component { this.removeMediaUploadListener = this.removeMediaUploadListener.bind( this ); this.finishMediaUploadWithSuccess = this.finishMediaUploadWithSuccess.bind( this ); this.finishMediaUploadWithFailure = this.finishMediaUploadWithFailure.bind( this ); + this.onImagePressed = this.onImagePressed.bind( this ); } componentDidMount() { @@ -53,6 +59,16 @@ export default class ImageEdit extends React.Component { this.removeMediaUploadListener(); } + onImagePressed() { + const { attributes } = this.props; + + if ( this.state.isUploadInProgress ) { + requestImageUploadCancelDialog( attributes.id ); + } else if ( attributes.id && ! isURL( attributes.url ) ) { + requestImageFailedRetryDialog( attributes.id ); + } + } + mediaUpload( payload ) { const { attributes } = this.props; @@ -61,15 +77,18 @@ export default class ImageEdit extends React.Component { } switch ( payload.state ) { - case MEDIA_ULOAD_STATE_UPLOADING: - this.setState( { progress: payload.progress, isUploadInProgress: true } ); + case MEDIA_UPLOAD_STATE_UPLOADING: + this.setState( { progress: payload.progress, isUploadInProgress: true, isUploadFailed: false } ); break; - case MEDIA_ULOAD_STATE_SUCCEEDED: + case MEDIA_UPLOAD_STATE_SUCCEEDED: this.finishMediaUploadWithSuccess( payload ); break; - case MEDIA_ULOAD_STATE_FAILED: + case MEDIA_UPLOAD_STATE_FAILED: this.finishMediaUploadWithFailure( payload ); break; + case MEDIA_UPLOAD_STATE_RESET: + this.mediaUploadStateReset( payload ); + break; } } @@ -85,10 +104,15 @@ export default class ImageEdit extends React.Component { finishMediaUploadWithFailure( payload ) { const { setAttributes } = this.props; - setAttributes( { url: payload.mediaUrl, id: payload.mediaId } ); - this.setState( { isUploadInProgress: false } ); + setAttributes( { id: payload.mediaId } ); + this.setState( { isUploadInProgress: false, isUploadFailed: true } ); + } - this.removeMediaUploadListener(); + mediaUploadStateReset( payload ) { + const { setAttributes } = this.props; + + setAttributes( { id: payload.mediaId, url: null } ); + this.setState( { isUploadInProgress: false, isUploadFailed: false } ); } addMediaUploadListener() { @@ -170,55 +194,64 @@ export default class ImageEdit extends React.Component { const progress = this.state.progress * 100; return ( - - { showSpinner && } - - { toolbarEditButton } - - - { inlineToolbarButtons } - - - { ( sizes ) => { - const { - imageWidthWithinContainer, - imageHeightWithinContainer, - } = sizes; - - let finalHeight = imageHeightWithinContainer; - if ( height > 0 && height < imageHeightWithinContainer ) { - finalHeight = height; - } - - let finalWidth = imageWidthWithinContainer; - if ( width > 0 && width < imageWidthWithinContainer ) { - finalWidth = width; - } - - return ( - - - - ); - } } - - { ( ! RichText.isEmpty( caption ) > 0 || isSelected ) && ( - - setAttributes( { caption: newCaption } ) } - /> - - ) } - + + + { showSpinner && } + + { toolbarEditButton } + + + { inlineToolbarButtons } + + + { ( sizes ) => { + const { + imageWidthWithinContainer, + imageHeightWithinContainer, + } = sizes; + + let finalHeight = imageHeightWithinContainer; + if ( height > 0 && height < imageHeightWithinContainer ) { + finalHeight = height; + } + + let finalWidth = imageWidthWithinContainer; + if ( width > 0 && width < imageWidthWithinContainer ) { + finalWidth = width; + } + + return ( + + + { this.state.isUploadFailed && + + + { __( 'Failed to insert media.\nPlease tap for options.' ) } + + } + + + ); + } } + + { ( ! RichText.isEmpty( caption ) > 0 || isSelected ) && ( + + setAttributes( { caption: newCaption } ) } + /> + + ) } + + ); } } diff --git a/packages/block-library/src/image/styles.native.scss b/packages/block-library/src/image/styles.native.scss new file mode 100644 index 00000000000000..833b8126bfc1ad --- /dev/null +++ b/packages/block-library/src/image/styles.native.scss @@ -0,0 +1,17 @@ +.imageContainer { + flex: 1; + justify-content: center; + align-items: center; +} + +.uploadFailedText { + color: #fff; + font-size: 14; + margin-top: 5; +} + +.uploadFailedContainer { + position: absolute; + flex-direction: column; + align-items: center; +}