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] File Block II #26360

Merged
merged 13 commits into from
Nov 17, 2020
24 changes: 22 additions & 2 deletions packages/block-editor/src/components/block-icon/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,33 @@ import { View } from 'react-native';
*/
import { Icon } from '@wordpress/components';
import { blockDefault } from '@wordpress/icons';
import { withPreferredColorScheme } from '@wordpress/compose';

export default function BlockIcon( { icon, showColors = false } ) {
/**
* Internal dependencies
*/
import styles from './style.scss';

export function BlockIcon( {
icon,
showColors = false,
getStylesFromColorScheme,
} ) {
if ( icon?.src === 'block-default' ) {
icon = {
src: blockDefault,
};
}

const renderedIcon = <Icon icon={ icon && icon.src ? icon.src : icon } />;
const renderedIcon = (
<Icon
icon={ icon && icon.src ? icon.src : icon }
{ ...getStylesFromColorScheme(
styles.iconPlaceholder,
styles.iconPlaceholderDark
) }
/>
);
const style = showColors
? {
backgroundColor: icon && icon.background,
Expand All @@ -26,3 +44,5 @@ export default function BlockIcon( { icon, showColors = false } ) {

return <View style={ style }>{ renderedIcon }</View>;
}

export default withPreferredColorScheme( BlockIcon );
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.iconPlaceholder {
fill: $gray-dark;
}

.iconPlaceholderDark {
fill: $white;
}
250 changes: 223 additions & 27 deletions packages/block-library/src/file/edit.native.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { View, Text } from 'react-native';
import { View, Text, Clipboard } from 'react-native';
import React from 'react';

/**
Expand All @@ -13,24 +13,39 @@ import {
MediaUploadProgress,
RichText,
PlainText,
BlockControls,
MediaUpload,
InspectorControls,
} from '@wordpress/block-editor';
import { file as icon } from '@wordpress/icons';
import {
ToolbarButton,
ToolbarGroup,
PanelBody,
ToggleControl,
BottomSheet,
} from '@wordpress/components';
import { file as icon, replace, button, external } from '@wordpress/icons';
import { Component } from '@wordpress/element';
import { __, _x } from '@wordpress/i18n';
import { withPreferredColorScheme } from '@wordpress/compose';

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

export default class FileEdit extends Component {
const URL_COPIED_NOTIFICATION_DURATION_MS = 1500;

export class FileEdit extends Component {
constructor( props ) {
super( props );

this.state = {
isUploadInProgress: false,
};

this.timerRef = null;

this.onSelectFile = this.onSelectFile.bind( this );
this.onChangeFileName = this.onChangeFileName.bind( this );
this.onChangeDownloadButtonText = this.onChangeDownloadButtonText.bind(
Expand All @@ -40,6 +55,14 @@ export default class FileEdit extends Component {
this.finishMediaUploadWithSuccess = this.finishMediaUploadWithSuccess.bind(
this
);
this.getFileComponent = this.getFileComponent.bind( this );
this.onChangeDownloadButtonVisibility = this.onChangeDownloadButtonVisibility.bind(
this
);
this.onCopyURL = this.onCopyURL.bind( this );
this.onChangeOpenInNewWindow = this.onChangeOpenInNewWindow.bind(
this
);
}

componentDidMount() {
Expand All @@ -53,6 +76,10 @@ export default class FileEdit extends Component {
}
}

componentWillUnmount() {
clearTimeout( this.timerRef );
}

onSelectFile( media ) {
this.props.setAttributes( {
href: media.url,
Expand All @@ -70,6 +97,29 @@ export default class FileEdit extends Component {
this.props.setAttributes( { downloadButtonText } );
}

onChangeDownloadButtonVisibility( showDownloadButton ) {
this.props.setAttributes( { showDownloadButton } );
}

onCopyURL() {
if ( this.state.isUrlCopied ) {
return;
}
const { href } = this.props.attributes;
Clipboard.setString( href );

this.setState( { isUrlCopied: true } );
this.timerRef = setTimeout( () => {
this.setState( { isUrlCopied: false } );
}, URL_COPIED_NOTIFICATION_DURATION_MS );
}

onChangeOpenInNewWindow( newValue ) {
this.props.setAttributes( {
textLinkTarget: newValue ? '_blank' : false,
} );
}

updateMediaProgress( payload ) {
const { setAttributes } = this.props;
if ( payload.mediaUrl ) {
Expand Down Expand Up @@ -110,24 +160,113 @@ export default class FileEdit extends Component {
);
}

render() {
const { attributes } = this.props;
const { href, fileName, downloadButtonText, id } = attributes;
getToolbarEditButton( open ) {
return (
<BlockControls>
<ToolbarGroup>
<ToolbarButton
title={ __( 'Edit file' ) }
icon={ replace }
onClick={ open }
/>
</ToolbarGroup>
</BlockControls>
);
}

if ( ! href ) {
return (
<MediaPlaceholder
icon={ <BlockIcon icon={ icon } /> }
labels={ {
title: __( 'File' ),
instructions: __( 'CHOOSE A FILE' ),
} }
onSelect={ this.onSelectFile }
onFocus={ this.props.onFocus }
allowedTypes={ [ 'other' ] }
/>
);
getInspectorControls(
{ showDownloadButton, textLinkTarget },
isUploadInProgress,
isUploadFailed
) {
const actionButtonStyle = this.props.getStylesFromColorScheme(
styles.actionButton,
styles.actionButtonDark
);

const isCopyUrlDisabled = isUploadFailed || isUploadInProgress;
const dimmedStyle = isCopyUrlDisabled && styles.disabledButton;
const finalButtonStyle = Object.assign(
{},
actionButtonStyle,
dimmedStyle
);

return (
<InspectorControls>
<PanelBody title={ __( 'File block settings' ) } />
<PanelBody>
<ToggleControl
icon={ external }
label={ __( 'Open in new tab' ) }
checked={ textLinkTarget === '_blank' }
onChange={ this.onChangeOpenInNewWindow }
/>
<ToggleControl
icon={ button }
label={ __( 'Show download button' ) }
checked={ showDownloadButton }
onChange={ this.onChangeDownloadButtonVisibility }
/>
<BottomSheet.Cell
disabled={ isCopyUrlDisabled }
label={
this.state.isUrlCopied
? __( 'Copied!' )
: __( 'Copy file URL' )
}
labelStyle={
this.state.isUrlCopied || finalButtonStyle
}
jd-alexander marked this conversation as resolved.
Show resolved Hide resolved
onPress={ this.onCopyURL }
/>
</PanelBody>
</InspectorControls>
);
}

getStyleForAlignment( align ) {
const getFlexAlign = ( alignment ) => {
switch ( alignment ) {
case 'right':
return 'flex-end';
case 'center':
return 'center';
default:
return 'flex-start';
}
};
return { alignSelf: getFlexAlign( align ) };
}

getTextAlignmentForAlignment( align ) {
switch ( align ) {
case 'right':
return 'right';
case 'center':
return 'center';
default:
return 'left';
}
}

getFileComponent( openMediaOptions, getMediaOptions ) {
const { attributes } = this.props;
const {
fileName,
downloadButtonText,
id,
showDownloadButton,
align,
} = attributes;

const dimmedStyle =
this.state.isUploadInProgress && styles.disabledButton;
const finalButtonStyle = Object.assign(
{},
styles.defaultButton,
dimmedStyle
);

return (
<MediaUploadProgress
Expand All @@ -138,34 +277,91 @@ export default class FileEdit extends Component {
}
onFinishMediaUploadWithFailure={ () => {} }
onMediaUploadStateReset={ this.mediaUploadStateReset }
renderContent={ ( { isUploadFailed, retryMessage } ) => {
renderContent={ ( {
isUploadInProgress,
isUploadFailed,
retryMessage,
} ) => {
if ( isUploadFailed ) {
return this.getErrorComponent( retryMessage );
}

return (
<View>
{ isUploadInProgress ||
this.getToolbarEditButton( openMediaOptions ) }
{ getMediaOptions() }
{ this.getInspectorControls(
attributes,
isUploadInProgress,
isUploadFailed
) }
<RichText
__unstableMobileNoFocusOnMount
etoledom marked this conversation as resolved.
Show resolved Hide resolved
fontSize={ 14 }
onChange={ this.onChangeFileName }
placeholder={ __( 'File name' ) }
rootTagsToEliminate={ [ 'p' ] }
tagName="p"
underlineColorAndroid="transparent"
value={ fileName }
deleteEnter={ true }
textAlign={ this.getTextAlignmentForAlignment(
align
) }
/>
<View style={ styles.defaultButton }>
<PlainText
value={ downloadButtonText }
onChange={ this.onChangeDownloadButtonText }
/>
</View>
{ showDownloadButton && (
<View
style={ [
finalButtonStyle,
this.getStyleForAlignment( align ),
] }
>
<PlainText
style={ styles.buttonText }
value={ downloadButtonText }
onChange={
this.onChangeDownloadButtonText
}
/>
</View>
) }
</View>
);
} }
/>
);
}

render() {
const { attributes } = this.props;
const { href } = attributes;

if ( ! href ) {
return (
<MediaPlaceholder
icon={ <BlockIcon icon={ icon } /> }
labels={ {
title: __( 'File' ),
instructions: __( 'CHOOSE A FILE' ),
} }
onSelect={ this.onSelectFile }
onFocus={ this.props.onFocus }
allowedTypes={ [ 'other' ] }
/>
);
}

return (
<MediaUpload
allowedTypes={ [ 'other' ] }
isReplacingMedia={ true }
onSelect={ this.onSelectFile }
render={ ( { open, getMediaOptions } ) => {
return this.getFileComponent( open, getMediaOptions );
} }
/>
);
}
}

export default withPreferredColorScheme( FileEdit );
Loading