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/upload media failed state #13615

Merged
merged 23 commits into from
Jan 31, 2019
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5897905
Implement failed state UI
marecar3 Jan 29, 2019
1e77159
Merge branch 'master' into rnmobile/upload_media_failed_state
marecar3 Jan 30, 2019
7022790
Move styles to better place
marecar3 Jan 30, 2019
45ec452
Merge branch 'master' into rnmobile/upload_media_failed_state
marecar3 Jan 30, 2019
b577d29
Support for failed upload retry (#13601)
mzorz Jan 30, 2019
0e9940b
Fixed lint errors
marecar3 Jan 30, 2019
17aaf68
Fixed style
marecar3 Jan 30, 2019
58f9685
removed debugger statement
mzorz Jan 30, 2019
5e7328a
Merge branch 'master' into rnmobile/upload_media_failed_state
marecar3 Jan 30, 2019
10706e4
Merge branch 'rnmobile/upload_media_failed_state' of https://github.c…
mzorz Jan 30, 2019
8d752eb
Merge branch 'rnmobile/upload_media_failed_state' of https://github.c…
mzorz Jan 30, 2019
8e08897
Added onImageUploadCancel method
marecar3 Jan 30, 2019
b6bc888
Refactored names of imageFailed and imageCancel methods
marecar3 Jan 30, 2019
d102ca2
added new state MEDIA_UPLOAD_STATE_RESET to reset associated mediaUrl…
mzorz Jan 31, 2019
eb4f315
Merge branch 'master' into rnmobile/upload_media_failed_state
marecar3 Jan 31, 2019
5149b6f
Implement failed state overlay using ImageBackground.
SergioEstevao Jan 31, 2019
a75ad32
Fixed styles
marecar3 Jan 31, 2019
abbd83c
Merge branch 'master' into rnmobile/upload_media_failed_state
marecar3 Jan 31, 2019
b246604
Disable Touchable view if image isn't in focus
marecar3 Jan 31, 2019
090fc1c
Fixed lint error
marecar3 Jan 31, 2019
e5eaa20
Fixed lint error
marecar3 Jan 31, 2019
3270b10
Fix lint erros
marecar3 Jan 31, 2019
3fa8d38
Merge branch 'master' into rnmobile/upload_media_failed_state
marecar3 Jan 31, 2019
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
155 changes: 94 additions & 61 deletions packages/block-library/src/image/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) {
Expand All @@ -31,13 +35,15 @@ export default class ImageEdit extends React.Component {
this.state = {
progress: 0,
isUploadInProgress: false,
isUploadFailed: false,
};

this.mediaUpload = this.mediaUpload.bind( this );
this.addMediaUploadListener = this.addMediaUploadListener.bind( this );
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() {
Expand All @@ -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;

Expand All @@ -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;
}
}

Expand All @@ -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() {
Expand Down Expand Up @@ -170,55 +194,64 @@ export default class ImageEdit extends React.Component {
const progress = this.state.progress * 100;

return (
<View style={ { flex: 1 } }>
{ showSpinner && <Spinner progress={ progress } /> }
<BlockControls>
{ toolbarEditButton }
</BlockControls>
<InspectorControls>
{ inlineToolbarButtons }
</InspectorControls>
<ImageSize src={ url } >
{ ( 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 (
<View style={ { flex: 1 } } >
<Image
style={ { width: finalWidth, height: finalHeight, opacity } }
resizeMethod="scale"
source={ { uri: url } }
key={ url }
/>
</View>
);
} }
</ImageSize>
{ ( ! RichText.isEmpty( caption ) > 0 || isSelected ) && (
<View style={ { padding: 12, flex: 1 } }>
<TextInput
style={ { textAlign: 'center' } }
underlineColorAndroid="transparent"
value={ caption }
placeholder={ __( 'Write caption…' ) }
onChangeText={ ( newCaption ) => setAttributes( { caption: newCaption } ) }
/>
</View>
) }
</View>
<TouchableWithoutFeedback onPress={ this.onImagePressed } >
<View style={ { flex: 1 } }>
{ showSpinner && <Spinner progress={ progress } /> }
<BlockControls>
{ toolbarEditButton }
</BlockControls>
<InspectorControls>
{ inlineToolbarButtons }
</InspectorControls>
<ImageSize src={ url } >
{ ( 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 (
<View style={ { flex: 1 } } >
<ImageBackground
style={ { width: finalWidth, height: finalHeight, opacity } }
resizeMethod="scale"
source={ { uri: url } }
key={ url }
>
{ this.state.isUploadFailed &&
<View style={ styles.imageContainer } >
<Dashicon icon={ 'image-rotate' } ariaPressed={ 'dashicon-active' } />
<Text style={ styles.uploadFailedText }>{ __( 'Failed to insert media.\nPlease tap for options.' ) }</Text>
</View>
}
</ImageBackground>
</View>
);
} }
</ImageSize>
{ ( ! RichText.isEmpty( caption ) > 0 || isSelected ) && (
<View style={ { padding: 12, flex: 1 } }>
<TextInput
style={ { textAlign: 'center' } }
underlineColorAndroid="transparent"
value={ caption }
placeholder={ __( 'Write caption…' ) }
onChangeText={ ( newCaption ) => setAttributes( { caption: newCaption } ) }
/>
</View>
) }
</View>
</TouchableWithoutFeedback>
);
}
}
17 changes: 17 additions & 0 deletions packages/block-library/src/image/styles.native.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.imageContainer {
flex: 1;
justify-content: center;
align-items: center;
}

.uploadFailedText {
color: white;
font-size: 14;
margin-top: 5;
}

.uploadFailedContainer {
position: absolute;
flex-direction: column;
align-items: center;
}