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] Simplify media insertion flow #25031

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
67c84d9
automatically open the media options bottom sheet
jd-alexander Sep 2, 2020
e8940fd
remove the image if the cancel option is selected.
jd-alexander Sep 2, 2020
d795232
added the clear media option.
jd-alexander Sep 3, 2020
3c29025
fixed the order of the cancel button.
jd-alexander Sep 3, 2020
0bc20d7
put a newline to separate cancellation if logic from the code below
jd-alexander Sep 3, 2020
9f3269b
made variable names more meaningful.
jd-alexander Sep 3, 2020
7de89e0
shared the destructiveButton logic between the Image & Cover block.
jd-alexander Sep 3, 2020
d488ba8
Merge branch 'master' into rnmobile/simplify_image_insertion_flow
jd-alexander Sep 24, 2020
8163ce6
merging resolved conflicts.
jd-alexander Sep 24, 2020
6a9d981
reverted the Image Editing Button behavior to having the ability to …
jd-alexander Sep 29, 2020
3de9cf0
Reverted changes to the ImageComponent and passed in the Clear Media …
jd-alexander Sep 29, 2020
59c36db
remove the delete behavior from the image block.
jd-alexander Sep 29, 2020
3cdde20
Utilize a delay on iOS so that the inserter being closed doesn't dism…
jd-alexander Sep 29, 2020
60a3feb
remove unnecessary line.
jd-alexander Sep 29, 2020
8966c23
put the mediaPickerOptions back in the correct location to eliminate …
jd-alexander Sep 29, 2020
0bfe3d6
pass the autoOpenMediaUpload flag to the MediaUpload component so it …
jd-alexander Sep 30, 2020
f72c3ae
moved delaying logic to the MediaUpload onPickerPresent function.
jd-alexander Sep 30, 2020
0ce172c
Once the media is cleared then the picker should not be shown.
jd-alexander Sep 30, 2020
e608165
removed unneeded MEDIA_UPLOAD_CANCEL type
jd-alexander Sep 30, 2020
c104069
revert changes made to the Cover block with onClearMedia logic.
jd-alexander Sep 30, 2020
0628c3f
removed unneeded variable for autoOpenMediaUpload
jd-alexander Sep 30, 2020
4148aca
added auto open to the Video block.
jd-alexander Oct 1, 2020
cb8f9e0
added the auto open to the Image Gallery block.
jd-alexander Oct 1, 2020
ff3e869
removed unneeded state and passed the auto open logic as an expression.
jd-alexander Oct 1, 2020
3016466
paused auto open logic as an expression to autoOpenMediaUpload.
jd-alexander Oct 1, 2020
af882b8
added a comment about why the delay is necessary on iOS.
jd-alexander Oct 1, 2020
07cea7b
attempt at fixing tests.
jd-alexander Oct 2, 2020
7ad8fc8
Changed the iOS Picker's termination action text from Cancel to Dismiss.
jd-alexander Oct 8, 2020
3f113a7
changed button accessibility id from Cancel to Dismiss.
jd-alexander Oct 8, 2020
23dc6fe
Merge branch 'master' into rnmobile/simplify_image_insertion_flow
jd-alexander Oct 9, 2020
372306f
Merge branch 'master' into rnmobile/simplify_image_insertion_flow
jd-alexander Oct 9, 2020
f217d4a
use driver.sleep( 1000 ) to ensure that the bottom sheet is visible.
jd-alexander Oct 9, 2020
e598262
Merge branch 'master' into rnmobile/simplify_image_insertion_flow
jd-alexander Oct 12, 2020
e3d3eeb
Merge branch 'master' into rnmobile/simplify_image_insertion_flow
jd-alexander Oct 12, 2020
96d6b7a
Merge branch 'master' into rnmobile/simplify_image_insertion_flow
jd-alexander Oct 13, 2020
1b9656b
The Undo and clearMedia buttons do not trigger the media upload picker
jd-alexander Oct 14, 2020
653b416
bottom sheet is not triggered for undo operations on the video block.
jd-alexander Oct 16, 2020
252c74e
bottom sheet is not triggered for clear or undo gallery operations
jd-alexander Oct 16, 2020
458499a
Merge branch 'master' into rnmobile/simplify_image_insertion_flow
jd-alexander Oct 16, 2020
4691407
converted behavior to utilize hooks in the gallery component.
jd-alexander Oct 16, 2020
ae0c58c
added actions for the block insertion events.
jd-alexander Nov 11, 2020
7b49207
Updated actions, reducer and selectors to support block inserted.
jd-alexander Nov 12, 2020
6cf07a6
added block insertion event to menu.
jd-alexander Nov 12, 2020
206a83f
Added wasBlockJustInserted to utilize it to open the bottom sheet.
jd-alexander Nov 12, 2020
d3cfdfa
Removed already opened logic and bound the wasBlockJustInserted
jd-alexander Nov 12, 2020
2fcaaab
simplified redux approach for auto opening.
jd-alexander Nov 13, 2020
350aef7
removed unneeded true comparison
jd-alexander Nov 13, 2020
043a9b6
renamed the behavior from blockInsertionEvent to lastBlockInserted
jd-alexander Nov 14, 2020
20e79e4
added the wasBlockJustInserted call to the Image block.
jd-alexander Nov 14, 2020
2fec1cc
added wasBlockJustInserted functionality to the Gallery flow.
jd-alexander Nov 14, 2020
e396965
added wasBlockJustInserted to the Video component.
jd-alexander Nov 14, 2020
397b79f
Updated the comment so it's more meaningful.
jd-alexander Nov 14, 2020
ef86342
Merge branch 'master' into rnmobile/simplify_image_insertion_flow
jd-alexander Nov 14, 2020
cb7aeaf
improved the comment of the lastBlockInserted selector
jd-alexander Nov 14, 2020
6afbaf8
Update packages/editor/src/store/selectors.native.js
jd-alexander Nov 17, 2020
f114df8
Merge branch 'master' into rnmobile/simplify_image_insertion_flow
jd-alexander Mar 1, 2021
35b703b
fixed issues that arose during the merge.
jd-alexander Mar 1, 2021
fd49e34
removed optimist block from reducer combination.
jd-alexander Mar 1, 2021
d56673f
Merge branch 'trunk' into rnmobile/simplify_image_insertion_flow
jd-alexander Mar 1, 2021
f76fd03
Utilized the useDispatch hook approach for last block inserted.
jd-alexander Mar 1, 2021
fd0e7dd
fixed lint errors.
jd-alexander Mar 1, 2021
c1c0087
Utilized editorPage.driver instead of driver reference.
jd-alexander Mar 1, 2021
fb4d162
added unit tests for the selectors.
jd-alexander Mar 1, 2021
21ce189
renamed the title of test group to match with tests within the store
jd-alexander Mar 2, 2021
91556bc
removed unneeded client from CLEAR_LAST_BLOCK_INSERTED
jd-alexander Mar 2, 2021
7030c9d
added unit tests for the actions and reducers of the last block inserted
jd-alexander Mar 2, 2021
f664f27
made test values simpler.
jd-alexander Mar 2, 2021
d0a8610
added documentation for changes to the MediaPlaceholder component.
jd-alexander Mar 2, 2021
e23f7df
Merge branch 'trunk' into rnmobile/simplify_image_insertion_flow
jd-alexander Mar 2, 2021
ca7eee3
updated MediaUpload and MediaPlaceholder documentation.
jd-alexander Mar 2, 2021
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
4 changes: 4 additions & 0 deletions packages/block-editor/src/components/inserter/menu.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ function InserterMenu( {
insertDefaultBlock,
} = useDispatch( blockEditorStore );

const { addLastBlockInserted } = useDispatch( 'core/editor' );

const {
items,
destinationRootClientId,
Expand Down Expand Up @@ -110,6 +112,8 @@ function InserterMenu( {
innerBlocks
);

addLastBlockInserted( newBlock.clientId );

insertBlock( newBlock, insertionIndex, destinationRootClientId );
},
[ insertBlock, destinationRootClientId, insertionIndex ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ This property is similar to the `accept` property. The difference is the format
- Required: No
- Platform: Web | Mobile

### autoOpenMediaUpload

If true, the MediaUpload component auto-opens the picker of the respective platform.

- Type: `Boolean`
- Required: No
- Default: `false`
- Platform: Mobile

### className

Class name added to the placeholder.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ function MediaPlaceholder( props ) {
height,
backgroundColor,
hideContent,
autoOpenMediaUpload,
} = props;

// use ref to keep media array current for callbacks during rerenders
Expand Down Expand Up @@ -160,6 +161,7 @@ function MediaPlaceholder( props ) {
}
multiple={ multiple }
isReplacingMedia={ false }
autoOpenMediaUpload={ autoOpenMediaUpload }
render={ ( { open, getMediaOptions } ) => {
return (
<TouchableWithoutFeedback
Expand Down
9 changes: 9 additions & 0 deletions packages/block-editor/src/components/media-upload/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,15 @@ Only applies if `gallery === true`.
- Default: `false`
- Platform: Web

### autoOpenMediaUpload

If true, the picker of the respective platform auto-opens.

- Type: `Boolean`
- Required: No
- Default: `false`
- Platform: Mobile

### gallery

If true, the component will initiate all the states required to represent a gallery. By default, the media modal opens in the gallery edit frame, but that can be changed using the `addToGallery`flag.
Expand Down
32 changes: 28 additions & 4 deletions packages/block-editor/src/components/media-upload/index.native.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
/**
* External dependencies
*/
import { Platform } from 'react-native';

import { delay } from 'lodash';

/**
* WordPress dependencies
*/
import { Component } from '@wordpress/element';
import { Component, React } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { Picker } from '@wordpress/components';
import {
Expand All @@ -26,20 +33,21 @@ 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' );

const PICKER_OPENING_DELAY = 200;

export class MediaUpload extends Component {
constructor( props ) {
super( props );
this.onPickerPresent = this.onPickerPresent.bind( this );
this.onPickerSelect = this.onPickerSelect.bind( this );
this.getAllSources = this.getAllSources.bind( this );

this.state = {
otherMediaOptions: [],
};
}

componentDidMount() {
const { allowedTypes = [] } = this.props;
const { allowedTypes = [], autoOpenMediaUpload } = this.props;
getOtherMediaOptions( allowedTypes, ( otherMediaOptions ) => {
const otherMediaOptionsWithIcons = otherMediaOptions.map(
( option ) => {
Expand All @@ -54,6 +62,10 @@ export class MediaUpload extends Component {

this.setState( { otherMediaOptions: otherMediaOptionsWithIcons } );
} );

if ( autoOpenMediaUpload ) {
this.onPickerPresent();
}
}

getAllSources() {
Expand Down Expand Up @@ -136,8 +148,20 @@ export class MediaUpload extends Component {
}

onPickerPresent() {
const { autoOpenMediaUpload } = this.props;
const isIOS = Platform.OS === 'ios';

if ( this.picker ) {
this.picker.presentPicker();
// the delay below is required because on iOS this action sheet gets dismissed by the close event of the Inserter
// so this delay allows the Inserter to be closed fully before presenting action sheet.
if ( autoOpenMediaUpload && isIOS ) {
delay(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That doesn't look like the most stable approach. I wonder what's that close event you're talking about? Maybe we could fix the underlying issue?

Copy link
Contributor Author

@jd-alexander jd-alexander Nov 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out :) What I meant to say here is that when the Inserter is being closed and this media upload action sheet/modal is being shown at the same time it is closed as it opens. What I think is happening is whatever mechanism is being used internally by iOS to close the inserter modal also closes any other modals that are on the screen. So yes, I know this approach isn't stable but the slight delay just ensured the the new modal wouldn't be on the screen at the same time. I just realized Eduardo's comment spoke about this in detail :)

() => this.picker.presentPicker(),
PICKER_OPENING_DELAY
);
} else {
this.picker.presentPicker();
}
}
}

Expand Down
22 changes: 21 additions & 1 deletion packages/block-library/src/gallery/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {
import { Platform, useEffect, useState, useMemo } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { getBlobByURL, isBlobURL, revokeBlobURL } from '@wordpress/blob';
import { useDispatch, withSelect } from '@wordpress/data';
import { useDispatch, withSelect, withDispatch } from '@wordpress/data';
import { withViewportMatch } from '@wordpress/viewport';
import { View } from '@wordpress/primitives';
import { store as coreStore } from '@wordpress/core-data';
Expand Down Expand Up @@ -81,6 +81,7 @@ function GalleryEdit( props ) {
imageSizes,
resizedImages,
onFocus,
wasBlockJustInserted,
} = props;
const {
columns = defaultColumnsNumber( attributes ),
Expand Down Expand Up @@ -343,6 +344,9 @@ function GalleryEdit( props ) {
onError={ onUploadError }
notices={ hasImages ? undefined : noticeUI }
onFocus={ onFocus }
autoOpenMediaUpload={
guarani marked this conversation as resolved.
Show resolved Hide resolved
! hasImages && isSelected && wasBlockJustInserted()
}
/>
);

Expand Down Expand Up @@ -464,6 +468,22 @@ export default compose( [
resizedImages,
};
} ),
withDispatch( ( dispatch, { clientId }, { select } ) => {
return {
wasBlockJustInserted() {
const { clearLastBlockInserted } = dispatch( 'core/editor' );
const { wasBlockJustInserted } = select( 'core/editor' );

const result = wasBlockJustInserted( clientId );

if ( result ) {
clearLastBlockInserted();
return true;
}
return false;
},
};
} ),
jd-alexander marked this conversation as resolved.
Show resolved Hide resolved
withNotices,
withViewportMatch( { isNarrow: '< small' } ),
] )( GalleryEdit );
45 changes: 42 additions & 3 deletions packages/block-library/src/image/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import { __, sprintf } from '@wordpress/i18n';
import { getProtocol, hasQueryArg } from '@wordpress/url';
import { doAction, hasAction } from '@wordpress/hooks';
import { compose, withPreferredColorScheme } from '@wordpress/compose';
import { withSelect } from '@wordpress/data';
import { withSelect, withDispatch } from '@wordpress/data';
import {
image as placeholderIcon,
textColor,
Expand All @@ -66,7 +66,6 @@ const getUrlForSlug = ( image, { sizeSlug } ) => {
export class ImageEdit extends Component {
constructor( props ) {
super( props );

this.state = {
isCaptionSelected: false,
};
Expand Down Expand Up @@ -116,6 +115,7 @@ export class ImageEdit extends Component {
value: slug,
name,
} ) );
this.onClearMedia = this.onClearMedia.bind( this );
}

componentDidMount() {
Expand Down Expand Up @@ -340,6 +340,10 @@ export class ImageEdit extends Component {
}
}

onClearMedia() {
this.props.setAttributes( { id: null, url: null } );
}

getPlaceholderIcon() {
return (
<Icon
Expand Down Expand Up @@ -399,7 +403,13 @@ export class ImageEdit extends Component {

render() {
const { isCaptionSelected } = this.state;
const { attributes, isSelected, image, clientId } = this.props;
const {
attributes,
isSelected,
image,
clientId,
wasBlockJustInserted,
} = this.props;
const { align, url, alt, id, sizeSlug, className } = attributes;

const sizeOptionsValid = find( this.sizeOptions, [
Expand Down Expand Up @@ -461,6 +471,9 @@ export class ImageEdit extends Component {
onSelect={ this.onSelectMediaUploadOption }
icon={ this.getPlaceholderIcon() }
onFocus={ this.props.onFocus }
autoOpenMediaUpload={
isSelected && ! url && wasBlockJustInserted()
}
/>
</View>
);
Expand Down Expand Up @@ -520,6 +533,16 @@ export class ImageEdit extends Component {
this.onSelectMediaUploadOption
}
openMediaOptions={ openMediaOptions }
mediaPickerOptions={ [
{
destructiveButton: true,
id: 'clearMedia',
label: __( 'Clear Media' ),
onPress: this.onClearMedia,
separated: true,
value: 'clearMedia',
},
] }
retryMessage={ retryMessage }
url={ url }
shapeStyle={ styles[ className ] }
Expand Down Expand Up @@ -579,5 +602,21 @@ export default compose( [
imageSizes,
};
} ),
withDispatch( ( dispatch, { clientId }, { select } ) => {
return {
wasBlockJustInserted() {
const { clearLastBlockInserted } = dispatch( 'core/editor' );
const { wasBlockJustInserted } = select( 'core/editor' );

const result = wasBlockJustInserted( clientId );

if ( result ) {
clearLastBlockInserted();
return true;
}
return false;
},
};
} ),
withPreferredColorScheme,
] )( ImageEdit );
33 changes: 30 additions & 3 deletions packages/block-library/src/video/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
ToolbarGroup,
PanelBody,
} from '@wordpress/components';
import { withPreferredColorScheme } from '@wordpress/compose';
import { withPreferredColorScheme, compose } from '@wordpress/compose';
import {
BlockCaption,
MediaPlaceholder,
Expand All @@ -35,6 +35,7 @@ import { __, sprintf } from '@wordpress/i18n';
import { isURL, getProtocol } from '@wordpress/url';
import { doAction, hasAction } from '@wordpress/hooks';
import { video as SvgIcon, replace } from '@wordpress/icons';
import { withDispatch } from '@wordpress/data';

/**
* Internal dependencies
Expand Down Expand Up @@ -189,7 +190,12 @@ class VideoEdit extends Component {
}

render() {
const { setAttributes, attributes, isSelected } = this.props;
const {
setAttributes,
attributes,
isSelected,
wasBlockJustInserted,
} = this.props;
const { id, src } = attributes;
const { videoContainerHeight } = this.state;

Expand Down Expand Up @@ -221,6 +227,9 @@ class VideoEdit extends Component {
onSelect={ this.onSelectMediaUploadOption }
icon={ this.getIcon( ICON_TYPE.PLACEHOLDER ) }
onFocus={ this.props.onFocus }
autoOpenMediaUpload={
isSelected && ! src && wasBlockJustInserted()
}
/>
</View>
);
Expand Down Expand Up @@ -361,4 +370,22 @@ class VideoEdit extends Component {
}
}

export default withPreferredColorScheme( VideoEdit );
export default compose( [
withDispatch( ( dispatch, { clientId }, { select } ) => {
return {
wasBlockJustInserted() {
const { clearLastBlockInserted } = dispatch( 'core/editor' );
const { wasBlockJustInserted } = select( 'core/editor' );

const result = wasBlockJustInserted( clientId );

if ( result ) {
clearLastBlockInserted();
return true;
}
return false;
},
};
} ),
withPreferredColorScheme,
] )( VideoEdit );
2 changes: 1 addition & 1 deletion packages/components/src/mobile/picker/index.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Picker extends Component {
onHandleClosingBottomSheet,
} = this.props;
const labels = options.map( ( { label } ) => label );
const fullOptions = [ __( 'Cancel' ) ].concat( labels );
const fullOptions = [ __( 'Dismiss' ) ].concat( labels );

ActionSheetIOS.showActionSheetWithOptions(
{
Expand Down
25 changes: 25 additions & 0 deletions packages/editor/src/store/actions.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,28 @@ export function togglePostTitleSelection( isSelected = true ) {
export function* autosave() {
RNReactNativeGutenbergBridge.editorDidAutosave();
}

/**
* Returns an action object to track the last block that was inserted.
*
* @param {Object} clientId The client id of the block.
*
* @return {Object} Action object.
*/
export function addLastBlockInserted( clientId ) {
return {
type: 'ADD_LAST_BLOCK_INSERTED',
clientId,
};
}

/**
* Returns an action object to clear the last block that was inserted.
*
* @return {Object} Action object.
*/
export function clearLastBlockInserted() {
return {
type: 'CLEAR_LAST_BLOCK_INSERTED',
};
}
Loading