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 Media File and Attachment Page options to the native Image block Link To menu #34846

Merged
merged 50 commits into from
Nov 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
5d681f7
Add initial UI for Image Link To options
dcalhoun Sep 14, 2021
2232a48
Intercept link settings navigation with callback instead of string
dcalhoun Sep 14, 2021
5dbc530
Align labels with web UI
dcalhoun Sep 14, 2021
216e4b5
Display selected link to option in Image block settings
dcalhoun Sep 14, 2021
3fc0c3c
Reset link destination to None when removing Custom URL
dcalhoun Sep 15, 2021
caa5aeb
Indicate selected link to option with check mark icon
dcalhoun Sep 15, 2021
717cf6c
Fix comment typo
dcalhoun Sep 15, 2021
5cb29af
Display correct value mask when URL value is set
dcalhoun Sep 15, 2021
3dde454
Reference Cell attached to BottomSheet component
dcalhoun Sep 15, 2021
2db29e5
Fix incorrect prop references
dcalhoun Sep 15, 2021
a75d41e
Correctly mask Custom URL value when a URL is set via a different option
dcalhoun Sep 15, 2021
648780e
Avoid passing current URL to link picker if it is not custom
dcalhoun Sep 15, 2021
9a806c3
Fix stale URL value
dcalhoun Sep 15, 2021
d9296cd
Fix unnecessary updates to attributes that resulted in bug
dcalhoun Sep 15, 2021
0c96e44
Fix attachment page URL
dcalhoun Sep 15, 2021
eb3befe
Fix incorrect link destination set when toggling new tab or setting rel
dcalhoun Sep 16, 2021
37374ee
Conditionally display Attachment Page option if URL exists
dcalhoun Sep 16, 2021
c766a90
Fix alignment for left-aligned selected icon
dcalhoun Sep 16, 2021
cea3cfb
Rename style selector to better describe intent
dcalhoun Sep 16, 2021
41ebf89
Remove irrelevant comment regarding setAttributes
dcalhoun Sep 16, 2021
79eb02c
Rename ImageOptionsScreen to ImageLinkDestinationsScreen
dcalhoun Sep 16, 2021
d67db6b
Add LinkDestination abstraction
dcalhoun Sep 16, 2021
d850dd3
Fix stale link picker value and React Navigation warning
dcalhoun Sep 20, 2021
b34cf62
Rename image link destination screen for consistency
dcalhoun Sep 21, 2021
3448fe9
Remove Custom URL placeholder
dcalhoun Sep 21, 2021
2ef5f65
Reduce spacing around left-side cell icons on Android
dcalhoun Sep 21, 2021
a2fd90d
Revert "Reduce spacing around left-side cell icons on Android"
dcalhoun Sep 21, 2021
5022e40
Fix select icon color
dcalhoun Sep 21, 2021
7223290
Fix selected icon styles for dark mode
dcalhoun Sep 21, 2021
542f91c
Update selected icon colors
dcalhoun Sep 21, 2021
31fc053
Merge branch 'trunk' of github.com:WordPress/gutenberg into feature/l…
dcalhoun Sep 21, 2021
ee167b7
Update change log
dcalhoun Sep 21, 2021
b97c858
Simplify unnecessarily complex conditional
dcalhoun Sep 21, 2021
4c1f665
Reference screen name cache rather than string literal
dcalhoun Sep 21, 2021
2d77121
Remove unnecessary mappedAttributes assignment
dcalhoun Sep 22, 2021
0749ad2
Reuse linkDestination parameter instead of new local assignment
dcalhoun Sep 22, 2021
fa8cea9
Refactor selected status of LinkDestination
dcalhoun Sep 22, 2021
350671b
Remove unused code
dcalhoun Oct 29, 2021
9160e7f
Remove undefined callback
dcalhoun Oct 29, 2021
d031ba8
Replace style-based key with index key
dcalhoun Sep 2, 2021
ec3c08c
Refactor existing Image edit tests to avoid referencing internals
dcalhoun Sep 2, 2021
e903510
Remove unnecessary native file extension reference
dcalhoun Sep 3, 2021
50eae9a
Avoid global act by awaiting specific change within Image component
dcalhoun Sep 3, 2021
209f191
Add missing React Navigation testing setup
dcalhoun Sep 6, 2021
8b9dacc
Add note regarding React Navigation async test error
dcalhoun Sep 6, 2021
2fdd8c1
Add Image Link To tests
dcalhoun Nov 1, 2021
cf4027f
Fix incorrect Link To value mask caused by stale route parameters
dcalhoun Nov 1, 2021
ac86a75
Merge branch 'trunk' of github.com:WordPress/gutenberg into feature/l…
dcalhoun Nov 1, 2021
9a02064
Fix erroneous URL display within Custom URL input
dcalhoun Nov 1, 2021
eace5ed
Format initialHtml seed consistently
dcalhoun Nov 1, 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
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { __ } from '@wordpress/i18n';
*/
import styles from './style.scss';
import BlockListAppender from '../block-list-appender';
import BlockListItem from './block-list-item.native';
import BlockListItem from './block-list-item';
import { store as blockEditorStore } from '../../store';

const BlockListContext = createContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
BottomSheet,
ColorSettings,
FocalPointSettingsPanel,
ImageLinkDestinationsScreen,
LinkPickerScreen,
} from '@wordpress/components';
import { compose } from '@wordpress/compose';
Expand All @@ -21,6 +22,7 @@ export const blockSettingsScreens = {
color: 'Color',
focalPoint: 'FocalPoint',
linkPicker: 'linkPicker',
imageLinkDestinations: 'imageLinkDestinations',
};

function BottomSheetSettings( {
Expand Down Expand Up @@ -75,6 +77,11 @@ function BottomSheetSettings( {
returnScreenName={ blockSettingsScreens.settings }
/>
</BottomSheet.NavigationScreen>
<BottomSheet.NavigationScreen
name={ blockSettingsScreens.imageLinkDestinations }
>
<ImageLinkDestinationsScreen { ...props } />
</BottomSheet.NavigationScreen>
</BottomSheet.NavigationContainer>
</BottomSheet>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ function StylePreview( { onPress, isActive, style, url } ) {
);

const getOutline = ( outlineStyles ) =>
outlineStyles.map( ( outlineStyle ) => {
outlineStyles.map( ( outlineStyle, index ) => {
return (
<Animated.View
style={ [ outlineStyle, { opacity }, styles[ name ] ] }
key={ JSON.stringify( outlineStyle ) }
key={ index }
/>
);
} );
Expand Down
176 changes: 114 additions & 62 deletions packages/block-library/src/image/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
* External dependencies
*/
import { View, TouchableWithoutFeedback } from 'react-native';
import { useRoute } from '@react-navigation/native';

/**
* WordPress dependencies
*/
import { Component } from '@wordpress/element';
import { Component, useEffect } from '@wordpress/element';
import {
requestMediaImport,
mediaUploadSync,
Expand Down Expand Up @@ -41,6 +42,7 @@ import {
BlockAlignmentToolbar,
BlockStyles,
store as blockEditorStore,
blockSettingsScreens,
} from '@wordpress/block-editor';
import { __, _x, sprintf } from '@wordpress/i18n';
import { getProtocol, hasQueryArg } from '@wordpress/url';
Expand All @@ -63,6 +65,7 @@ import styles from './styles.scss';
import { getUpdatedLinkTargetSettings } from './utils';

import {
LINK_DESTINATION_NONE,
LINK_DESTINATION_CUSTOM,
LINK_DESTINATION_ATTACHMENT,
LINK_DESTINATION_MEDIA,
Expand All @@ -76,6 +79,101 @@ const getUrlForSlug = ( image, sizeSlug ) => {
return image?.media_details?.sizes?.[ sizeSlug ]?.source_url;
};

function LinkSettings( {
attributes,
image,
isLinkSheetVisible,
setMappedAttributes,
} ) {
const route = useRoute();
const { href: url, label, linkDestination, linkTarget, rel } = attributes;

// Persist attributes passed from child screen
useEffect( () => {
const { inputValue: newUrl } = route.params || {};

let newLinkDestination;
switch ( newUrl ) {
case attributes.url:
newLinkDestination = LINK_DESTINATION_MEDIA;
break;
case image?.link:
newLinkDestination = LINK_DESTINATION_ATTACHMENT;
break;
case '':
newLinkDestination = LINK_DESTINATION_NONE;
break;
default:
newLinkDestination = LINK_DESTINATION_CUSTOM;
break;
}

setMappedAttributes( {
url: newUrl,
linkDestination: newLinkDestination,
} );
}, [ route.params?.inputValue ] );

let valueMask;
switch ( linkDestination ) {
case LINK_DESTINATION_MEDIA:
valueMask = __( 'Media File' );
break;
case LINK_DESTINATION_ATTACHMENT:
valueMask = __( 'Attachment Page' );
break;
case LINK_DESTINATION_CUSTOM:
valueMask = __( 'Custom URL' );
break;
default:
valueMask = __( 'None' );
break;
}

const linkSettingsOptions = {
url: {
valueMask,
autoFocus: false,
autoFill: true,
},
openInNewTab: {
label: __( 'Open in new tab' ),
},
linkRel: {
label: __( 'Link Rel' ),
placeholder: _x( 'None', 'Link rel attribute value placeholder' ),
},
};

return (
<PanelBody title={ __( 'Link Settings' ) }>
<LinkSettingsNavigation
isVisible={ isLinkSheetVisible }
url={ url }
rel={ rel }
label={ label }
linkTarget={ linkTarget }
setAttributes={ setMappedAttributes }
withBottomSheet={ false }
hasPicker
options={ linkSettingsOptions }
showIcon={ false }
onLinkCellPressed={ ( { navigation } ) => {
navigation.navigate(
blockSettingsScreens.imageLinkDestinations,
{
inputValue: attributes.href,
linkDestination: attributes.linkDestination,
imageUrl: attributes.url,
attachmentPageUrl: image?.link,
}
);
} }
/>
</PanelBody>
);
}

export class ImageEdit extends Component {
constructor( props ) {
super( props );
Expand All @@ -96,7 +194,6 @@ export class ImageEdit extends Component {
);
this.updateMediaProgress = this.updateMediaProgress.bind( this );
this.updateImageURL = this.updateImageURL.bind( this );
this.onSetLinkDestination = this.onSetLinkDestination.bind( this );
this.onSetNewTab = this.onSetNewTab.bind( this );
this.onSetSizeSlug = this.onSetSizeSlug.bind( this );
this.onImagePressed = this.onImagePressed.bind( this );
Expand All @@ -108,25 +205,6 @@ export class ImageEdit extends Component {
);
this.setMappedAttributes = this.setMappedAttributes.bind( this );
this.onSizeChangeValue = this.onSizeChangeValue.bind( this );

this.linkSettingsOptions = {
url: {
label: __( 'Image Link URL' ),
placeholder: __( 'Add URL' ),
autoFocus: false,
autoFill: true,
},
openInNewTab: {
label: __( 'Open in new tab' ),
},
linkRel: {
label: __( 'Link Rel' ),
placeholder: _x(
'None',
'Link rel attribute value placeholder'
),
},
};
}

componentDidMount() {
Expand Down Expand Up @@ -282,13 +360,6 @@ export class ImageEdit extends Component {
} );
}

onSetLinkDestination( href ) {
this.props.setAttributes( {
linkDestination: LINK_DESTINATION_CUSTOM,
href,
} );
}

onSetNewTab( value ) {
const updatedLinkTarget = getUpdatedLinkTargetSettings(
value,
Expand Down Expand Up @@ -383,45 +454,23 @@ export class ImageEdit extends Component {
: width;
}

setMappedAttributes( { url: href, ...restAttributes } ) {
setMappedAttributes( { url: href, linkDestination, ...restAttributes } ) {
const { setAttributes } = this.props;
if ( ! href && ! linkDestination ) {
linkDestination = LINK_DESTINATION_NONE;
} else if ( ! linkDestination ) {
linkDestination = LINK_DESTINATION_CUSTOM;
}

return href === undefined
? setAttributes( {
...restAttributes,
linkDestination: LINK_DESTINATION_CUSTOM,
} )
return href === undefined || href === this.props.attributes.href
? setAttributes( restAttributes )
: setAttributes( {
...restAttributes,
linkDestination,
href,
linkDestination: LINK_DESTINATION_CUSTOM,
} );
}

getLinkSettings() {
const { isLinkSheetVisible } = this.state;
const {
attributes: { href: url, ...unMappedAttributes },
} = this.props;
const mappedAttributes = { ...unMappedAttributes, url };

return (
<LinkSettingsNavigation
isVisible={ isLinkSheetVisible }
url={ mappedAttributes.url }
rel={ mappedAttributes.rel }
label={ mappedAttributes.label }
linkTarget={ mappedAttributes.linkTarget }
onClose={ this.dismissSheet }
setAttributes={ this.setMappedAttributes }
withBottomSheet={ false }
hasPicker
options={ this.linkSettingsOptions }
showIcon={ false }
/>
);
}

getAltTextSettings() {
const {
attributes: { alt },
Expand Down Expand Up @@ -583,9 +632,12 @@ export class ImageEdit extends Component {
) }
{ this.getAltTextSettings() }
</PanelBody>
<PanelBody title={ __( 'Link Settings' ) }>
{ this.getLinkSettings( true ) }
</PanelBody>
<LinkSettings
attributes={ this.props.attributes }
image={ this.props.image }
isLinkSheetVisible={ this.state.isLinkSheetVisible }
setMappedAttributes={ this.setMappedAttributes }
/>
<PanelBody
title={ __( 'Featured Image' ) }
titleStyle={ styles.featuredImagePanelTitle }
Expand Down
Loading