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

Add isAppender functionality on mobile #17195

Merged
merged 12 commits into from
Sep 25, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ If false the default placeholder style is used.
- Type: `Boolean`
- Required: No
- Default: `false`
- Platform: Web | Mobile

### isSelected

Whether the block is selected or not.

- Type: `Boolean`
- Required: No
- Platform: Mobile
Copy link
Contributor

Choose a reason for hiding this comment

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

It doesn't look like isSelected needs to be part of MediaPlaceholder API. Block can decide to render/not render the MediaPlaceholder due to its selected state.
Also as far as I see web also handles it this way without needing to add this to MediaPlaceholder API and we want to come close to web as much as possible.
Let me know if I am missing something.

Copy link
Member Author

Choose a reason for hiding this comment

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

According to the mobile gallery design, isAppender button should be displayed only when gallery block is selected, that's why there is a need to pass isSelected value from parent component into mediaPlaceholder. Please, correct me if I understood it wrongly.

Copy link
Contributor

@pinarol pinarol Aug 29, 2019

Choose a reason for hiding this comment

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

Could you be able to do some investigation about how this works on web? As far as I see mediaplaceholder isn't rendered if block is not selected on web as well. So how is it handled without some isSelected prop on Gallery block? We want to keep props of components as similar as possible between platforms.
Independent from this, it doesn't sound right for a component to have a prop named 'isSelected' where it actually decides rendering/not rendering it. 'isSelected' belongs to blocks and not applicable here as is. We need to change it to describe what it does for MediaPlaceholder.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, will investigate it!

Copy link
Member Author

@lukewalczak lukewalczak Aug 30, 2019

Choose a reason for hiding this comment

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

After the investigation, I've noticed that web media-placeholder accepts prop called dropZoneUIOnly={ hasImages && ! isSelected } which then within placeholder is rendering gallery with appender when dropZoneUIOnly === false otherwise without appender.

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we can make use of the same prop for parity, although, we don't currently have drag & drop of media. But it looks like a nice enhancement for the future. wdyt @koke ? I think we can start using dropZoneUIOnly on mobile too.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think dropZoneUIOnly is the right prop to use here. I checked the README and it's not documented anywhere. From what I'm seeing, as long as media upload is possible, the drop zone would be rendered on the web, and the UI to pick media is the variable here.

Adding dropZoneUIOnly to mobile would imply that we support drag and drop, and could be confusing. I'd rather flip the logic and have a showMediaSelectionUI (or another better name) prop that is set only when the block is selected.

Copy link
Member Author

Choose a reason for hiding this comment

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

The name you've proposed (showMediaSelectionUI) sounds good for me. Just to be sure, would you like to replace dropZoneUIOnly with showMediaSelectionUI on the web and have the same prop on mobile?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I would propose that change for the web as well

Copy link
Contributor

Choose a reason for hiding this comment

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

LGTM as soon as we keep the parity. 👍


### labels

Expand Down
103 changes: 69 additions & 34 deletions packages/block-editor/src/components/media-placeholder/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,27 @@ import { View, Text, TouchableWithoutFeedback } from 'react-native';
* WordPress dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import { MediaUpload, MEDIA_TYPE_IMAGE, MEDIA_TYPE_VIDEO } from '@wordpress/block-editor';
import {
MediaUpload,
MEDIA_TYPE_IMAGE,
MEDIA_TYPE_VIDEO,
} from '@wordpress/block-editor';
import { Dashicon } from '@wordpress/components';

/**
* Internal dependencies
*/
import styles from './styles.scss';

function MediaPlaceholder( props ) {
const { mediaType, labels = {}, icon, onSelectURL } = props;
const {
mediaType,
labels = {},
icon,
onSelectURL,
isAppender,
isSelected,
} = props;

const isImage = MEDIA_TYPE_IMAGE === mediaType;
const isVideo = MEDIA_TYPE_VIDEO === mediaType;
Expand Down Expand Up @@ -46,40 +58,63 @@ function MediaPlaceholder( props ) {
accessibilityHint = __( 'Double tap to select a video' );
}

const renderContent = () => {
if ( isAppender === undefined || ! isAppender ) {
return (
<>
<View style={ styles.modalIcon }>{ icon }</View>
<Text style={ styles.emptyStateTitle }>{ placeholderTitle }</Text>
<Text style={ styles.emptyStateDescription }>{ instructions }</Text>
</>
);
} else if ( isAppender && isSelected ) {
return (
<Dashicon
icon="plus-alt"
style={ styles.addBlockButton }
color={ styles.addBlockButton.color }
size={ styles.addBlockButton.size }
/>
);
}
};

if ( isAppender && ! isSelected ) {
return null;
Copy link
Contributor

Choose a reason for hiding this comment

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

it looks like there's sth wrong here, it is returning null if disableMediaButtons is undefined or false.

}

return (
<MediaUpload
mediaType={ mediaType }
onSelectURL={ onSelectURL }
render={ ( { open, getMediaOptions } ) => {
return (
<TouchableWithoutFeedback
accessibilityLabel={ sprintf(
/* translators: accessibility text for the media block empty state. %s: media type */
__( '%s block. Empty' ),
placeholderTitle
) }
accessibilityRole={ 'button' }
accessibilityHint={ accessibilityHint }
onPress={ ( event ) => {
props.onFocus( event );
open();
} }
>
<View style={ styles.emptyStateContainer }>
{ getMediaOptions() }
<View style={ styles.modalIcon }>
{ icon }
<View style={ { flex: 1 } }>
<MediaUpload
mediaType={ mediaType }
onSelectURL={ onSelectURL }
render={ ( { open, getMediaOptions } ) => {
return (
<TouchableWithoutFeedback
accessibilityLabel={ sprintf(
/* translators: accessibility text for the media block empty state. %s: media type */
__( '%s block. Empty' ),
placeholderTitle
) }
accessibilityRole={ 'button' }
accessibilityHint={ accessibilityHint }
onPress={ ( event ) => {
props.onFocus( event );
open();
} }>
<View
style={ [
styles.emptyStateContainer,
isAppender && styles.isAppender,
] }>
{ getMediaOptions() }
{ renderContent() }
</View>
<Text style={ styles.emptyStateTitle }>
{ placeholderTitle }
</Text>
<Text style={ styles.emptyStateDescription }>
{ instructions }
</Text>
</View>
</TouchableWithoutFeedback>
);
} } />
</TouchableWithoutFeedback>
);
} }
/>
</View>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,18 @@
align-items: center;
fill: $gray-dark;
}

.isAppender {
height: auto;
background-color: $white;
border: $border-width solid $light-gray-500;
border-radius: 4px;
}

.addBlockButton {
color: $white;
background-color: $dark-gray-500;
border-radius: $icon-button-size-small / 2;
overflow: hidden;
size: $icon-button-size-small;
}
14 changes: 6 additions & 8 deletions packages/block-library/src/image/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,12 @@ class ImageEdit extends React.Component {

if ( ! url ) {
return (
<View style={ { flex: 1 } } >
<MediaPlaceholder
mediaType={ MEDIA_TYPE_IMAGE }
onSelectURL={ this.onSelectMediaUploadOption }
icon={ this.getIcon( false ) }
onFocus={ this.props.onFocus }
/>
</View>
<MediaPlaceholder
mediaType={ MEDIA_TYPE_IMAGE }
onSelectURL={ this.onSelectMediaUploadOption }
icon={ this.getIcon( false ) }
onFocus={ this.props.onFocus }
/>
);
}

Expand Down
14 changes: 6 additions & 8 deletions packages/block-library/src/video/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,12 @@ class VideoEdit extends React.Component {

if ( ! id ) {
return (
<View style={ { flex: 1 } } >
<MediaPlaceholder
mediaType={ MEDIA_TYPE_VIDEO }
onSelectURL={ this.onSelectMediaUploadOption }
icon={ this.getIcon( false, true ) }
onFocus={ this.props.onFocus }
/>
</View>
<MediaPlaceholder
mediaType={ MEDIA_TYPE_VIDEO }
onSelectURL={ this.onSelectMediaUploadOption }
icon={ this.getIcon( false, true ) }
onFocus={ this.props.onFocus }
/>
);
}

Expand Down