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] Social icons #23017

Merged
merged 39 commits into from
Jul 9, 2020
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
01400dd
Initial work on social links
lukewalczak Jun 2, 2020
25f4d71
Style social links and their infra
lukewalczak Jun 5, 2020
835f7f2
Merge branch 'master' into rnmobile/social_links
lukewalczak Jun 5, 2020
7f35aac
Merge branch 'master' into rnmobile/social_links
lukewalczak Jun 8, 2020
b40ad02
Correct action sheet labels and add header
lukewalczak Jun 8, 2020
dafa685
Merge branch 'rnmobile/correct-action-sheet-labels' into rnmobile/soc…
lukewalczak Jun 8, 2020
5deb622
Merge branch 'master' into rnmobile/social_links
lukewalczak Jun 8, 2020
9f1ad97
Merge branch 'master' into rnmobile/social_links
lukewalczak Jun 15, 2020
ae263c4
Main social icons refactor
lukewalczak Jun 15, 2020
216f3cc
Refactor animation in social links, blur post title when unselected
lukewalczak Jun 16, 2020
85eb3ae
Wrap Svg in forwardRef to pass the ref to func component
lukewalczak Jun 16, 2020
76cf8d6
Add placeholder for inactive unselected icons
lukewalczak Jun 18, 2020
a0edba7
Correct undo in social links
lukewalczak Jun 18, 2020
4eae11c
Create link settings component
lukewalczak Jun 19, 2020
015ab5a
Merge branch 'rnmobile/link-settings' into rnmobile/social_links
lukewalczak Jun 19, 2020
08aeedc
Use LinkSettings
lukewalczak Jun 19, 2020
631daee
Display social icon name on mobile platform
lukewalczak Jun 22, 2020
0217143
Use usePrevious hook
lukewalczak Jun 23, 2020
036c6c4
Add props description, refactor some props
lukewalczak Jun 23, 2020
f56525e
Merge branch 'rnmobile/link-settings' into rnmobile/social_links
lukewalczak Jun 24, 2020
342228f
Merge branch 'master' into rnmobile/social_links
lukewalczak Jun 24, 2020
90f6ec1
Merge branch 'master' into rnmobile/social_links
lukewalczak Jun 24, 2020
ff15202
Correct e2e test
lukewalczak Jun 24, 2020
c74f14c
Code clean up
lukewalczak Jun 25, 2020
40333ea
Code refactor
lukewalczak Jun 25, 2020
3921817
Revert block picker changes
lukewalczak Jun 25, 2020
2ae940b
Merge branch 'master' into rnmobile/social_links
lukewalczak Jun 30, 2020
15949b9
Merge branch 'master' into rnmobile/social_links
lukewalczak Jun 30, 2020
8f274a8
Add a11y to social links
lukewalczak Jun 30, 2020
030ce31
Use button size variable
lukewalczak Jun 30, 2020
c10c55a
Refactor social icons
lukewalczak Jul 3, 2020
7a9575d
Revert post title changes
lukewalczak Jul 3, 2020
9fbb610
Merge branch 'master' into rnmobile/social_links
lukewalczak Jul 3, 2020
c58e64e
Code refactor, add svg wrapper
lukewalczak Jul 6, 2020
c3fc255
Merge branch 'master' into rnmobile/social_links
lukewalczak Jul 7, 2020
509c5cb
Remove initialAttributes
lukewalczak Jul 7, 2020
763459e
Merge branch 'master' into rnmobile/social_links
lukewalczak Jul 7, 2020
7c21866
Add check for block name
lukewalczak Jul 8, 2020
643b9e5
Merge branch 'master' into rnmobile/social_links
lukewalczak Jul 9, 2020
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 @@ -46,7 +46,7 @@ const BlockSelectionButton = ( {
rootBlockIcon && [
<Icon
key="parent-icon"
size={ 20 }
size={ 24 }
icon={ rootBlockIcon.src }
fill={ styles.icon.color }
/>,
Expand Down
67 changes: 38 additions & 29 deletions packages/block-editor/src/components/block-list/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -312,41 +312,50 @@ export class BlockList extends Component {
}

export default compose( [
withSelect( ( select, { rootClientId, orientation } ) => {
const {
getBlockCount,
getBlockOrder,
getSelectedBlockClientId,
isBlockInsertionPointVisible,
getSettings,
getBlockHierarchyRootClientId,
} = select( 'core/block-editor' );
withSelect(
( select, { rootClientId, orientation, filterInnerBlocks } ) => {
const {
getBlockCount,
getBlockOrder,
getSelectedBlockClientId,
isBlockInsertionPointVisible,
getSettings,
getBlockHierarchyRootClientId,
} = select( 'core/block-editor' );

const isStackedHorizontally = orientation === 'horizontal';
const isStackedHorizontally = orientation === 'horizontal';

const selectedBlockClientId = getSelectedBlockClientId();
const blockClientIds = getBlockOrder( rootClientId );
const selectedBlockClientId = getSelectedBlockClientId();

const isReadOnly = getSettings().readOnly;
let blockClientIds = getBlockOrder( rootClientId );
// Display only block which fulfill the condition in passed `filterInnerBlocks` function
if ( filterInnerBlocks ) {
blockClientIds = filterInnerBlocks( blockClientIds );
}

const rootBlockId = getBlockHierarchyRootClientId(
selectedBlockClientId
);
const hasRootInnerBlocks = !! getBlockCount( rootBlockId );
const isReadOnly = getSettings().readOnly;

const isFloatingToolbarVisible =
!! selectedBlockClientId && hasRootInnerBlocks;
const blockCount = getBlockCount( rootBlockId );

return {
blockClientIds,
blockCount: getBlockCount( rootClientId ),
isBlockInsertionPointVisible: isBlockInsertionPointVisible(),
isReadOnly,
isRootList: rootClientId === undefined,
isFloatingToolbarVisible,
isStackedHorizontally,
};
} ),
const rootBlockId = getBlockHierarchyRootClientId(
selectedBlockClientId
);
const hasRootInnerBlocks = !! blockCount;

const isFloatingToolbarVisible =
!! selectedBlockClientId && hasRootInnerBlocks;

return {
blockClientIds,
blockCount,
isBlockInsertionPointVisible: isBlockInsertionPointVisible(),
isReadOnly,
isRootList: rootClientId === undefined,
isFloatingToolbarVisible,
isStackedHorizontally,
};
}
),
withDispatch( ( dispatch ) => {
const { insertBlock, replaceBlock, clearSelectedBlock } = dispatch(
'core/block-editor'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ function UncontrolledInnerBlocks( props ) {
marginVertical,
marginHorizontal,
horizontalAlignment,
filterInnerBlocks,
} = props;

const block = useSelect(
Expand Down Expand Up @@ -80,6 +81,7 @@ function UncontrolledInnerBlocks( props ) {
contentStyle={ contentStyle }
onAddBlock={ onAddBlock }
onDeleteBlock={ onDeleteBlock }
filterInnerBlocks={ filterInnerBlocks }
/>
);

Expand Down
33 changes: 31 additions & 2 deletions packages/block-library/src/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import { Platform } from 'react-native';
import { sortBy } from 'lodash';

/**
* WordPress dependencies
Expand Down Expand Up @@ -60,6 +61,8 @@ import * as tagCloud from './tag-cloud';
import * as classic from './classic';
import * as group from './group';
import * as buttons from './buttons';
import * as socialLink from './social-link';
import * as socialLinks from './social-links';

export const coreBlocks = [
// Common blocks are grouped at the top to prioritize their display
Expand Down Expand Up @@ -108,6 +111,8 @@ export const coreBlocks = [
video,
classic,
buttons,
socialLink,
socialLinks,
].reduce( ( accumulator, block ) => {
accumulator[ block.name ] = block;
return accumulator;
Expand All @@ -130,20 +135,41 @@ const registerBlock = ( block ) => {
} );
};

/**
* Function to register a block variations e.g. social icons different types.
*
* @param {Object} block The block which variations will be registered.
*
*/
const registerBlockVariations = ( block ) => {
const { metadata, settings, name } = block;

sortBy( settings.variations, 'title' ).forEach( ( v ) => {
registerBlockType( `${ name }-${ v.name }`, {
...metadata,
name: `${ name }-${ v.name }`,
...settings,
icon: v.icon(),
title: v.title,
} );
} );
};

// only enable code block for development
// eslint-disable-next-line no-undef
const devOnly = ( block ) => ( !! __DEV__ ? block : null );

const iOSOnly = ( block ) =>
Platform.OS === 'ios' ? block : devOnly( block );

// Hide the Classic block
// Hide the Classic block and SocialLink block
addFilter(
'blocks.registerBlockType',
'core/react-native-editor',
( settings, name ) => {
const hiddenBlocks = [ 'core/freeform', 'core/social-link' ];
if (
name === 'core/freeform' &&
hiddenBlocks.includes( name ) &&
hasBlockSupport( settings, 'inserter', true )
) {
settings.supports = {
Expand Down Expand Up @@ -193,9 +219,12 @@ export const registerCoreBlocks = () => {
latestPosts,
verse,
cover,
socialLink,
socialLinks,
iOSOnly( pullquote ),
].forEach( registerBlock );

registerBlockVariations( socialLink );
setDefaultBlockName( paragraph.name );
setFreeformContentHandlerName( classic.name );
setUnregisteredTypeHandlerName( missing.name );
Expand Down
209 changes: 209 additions & 0 deletions packages/block-library/src/social-link/edit.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
/**
* External dependencies
*/
import { View, Animated, Easing, TouchableWithoutFeedback } from 'react-native';

/**
* WordPress dependencies
*/
import { BlockControls } from '@wordpress/block-editor';
import { useEffect, useState, useRef } from '@wordpress/element';
import {
ToolbarGroup,
ToolbarButton,
LinkSettings,
} from '@wordpress/components';
import { compose, usePreferredColorSchemeStyle } from '@wordpress/compose';
import { __, sprintf } from '@wordpress/i18n';
import { link, Icon } from '@wordpress/icons';
import { withSelect } from '@wordpress/data';
/**
* Internal dependencies
*/
import { getIconBySite, getNameBySite } from './social-list';
import styles from './editor.scss';

const ANIMATION_DELAY = 300;
const ANIMATION_DURATION = 400;

const linkSettingsOptions = {
url: {
label: __( 'URL' ),
placeholder: __( 'Add URL' ),
autoFocus: true,
},
linkLabel: {
label: __( 'Link label' ),
placeholder: __( 'None' ),
},
footer: {
label: __( 'Briefly describe the link to help screen reader user' ),
},
};

const SocialLinkEdit = ( {
attributes,
setAttributes,
isSelected,
onFocus,
name,
} ) => {
const { url, service = name } = attributes;
const [ isLinkSheetVisible, setIsLinkSheetVisible ] = useState( false );
const [ hasUrl, setHasUrl ] = useState( !! url );

const activeIcon =
styles[ `wp-social-link-${ service }` ] || styles[ `wp-social-link` ];

const inactiveIcon = usePreferredColorSchemeStyle(
styles.inactiveIcon,
styles.inactiveIconDark
);

const animatedValue = useRef( new Animated.Value( 0 ) ).current;

const IconComponent = getIconBySite( service )();
const socialLinkName = getNameBySite( service );

// When new social icon is added link sheet is opened automatically
useEffect( () => {
if ( isSelected && ! url ) {
setIsLinkSheetVisible( true );
}
}, [] );

useEffect( () => {
if ( ! url ) {
setHasUrl( false );
animatedValue.setValue( 0 );
} else if ( url ) {
animateColors();
}
}, [ url ] );

const interpolationColors = {
backgroundColor: animatedValue.interpolate( {
inputRange: [ 0, 1 ],
outputRange: [
inactiveIcon.backgroundColor,
activeIcon.backgroundColor,
],
} ),
color: animatedValue.interpolate( {
inputRange: [ 0, 1 ],
outputRange: [ inactiveIcon.color, activeIcon.color ],
} ),
stroke: '',
};

const { backgroundColor, color, stroke } = hasUrl
? activeIcon
: interpolationColors;

function animateColors() {
Animated.sequence( [
Animated.delay( ANIMATION_DELAY ),
Animated.timing( animatedValue, {
toValue: 1,
duration: ANIMATION_DURATION,
easing: Easing.circle,
} ),
] ).start( () => setHasUrl( true ) );
}

function onCloseSettingsSheet() {
setIsLinkSheetVisible( false );
}

function onOpenSettingsSheet() {
setIsLinkSheetVisible( true );
}

function onEmptyURL() {
animatedValue.setValue( 0 );
setHasUrl( false );
}

function onIconPress() {
if ( isSelected ) {
setIsLinkSheetVisible( true );
} else {
onFocus();
}
}

const accessibilityHint = url
? sprintf(
// translators: %s: social link name e.g: "Instagram".
__( '%s has URL set' ),
socialLinkName
)
: sprintf(
// translators: %s: social link name e.g: "Instagram".
__( '%s has no URL set' ),
socialLinkName
);

return (
<View>
{ isSelected && (
<BlockControls>
<ToolbarGroup>
<ToolbarButton
title={ sprintf(
// translators: %s: social link name e.g: "Instagram".
__( 'Add link to %s' ),
socialLinkName
) }
icon={ link }
onClick={ onOpenSettingsSheet }
isActive={ url }
/>
</ToolbarGroup>
</BlockControls>
) }
<LinkSettings
isVisible={ isLinkSheetVisible }
attributes={ attributes }
onEmptyURL={ onEmptyURL }
onClose={ onCloseSettingsSheet }
setAttributes={ setAttributes }
options={ linkSettingsOptions }
withBottomSheet={ true }
/>
<TouchableWithoutFeedback
onPress={ onIconPress }
accessibilityRole={ 'button' }
accessibilityLabel={ sprintf(
// translators: %s: social link name e.g: "Instagram".
__( '%s social icon' ),
socialLinkName
) }
accessibilityHint={ accessibilityHint }
>
<Animated.View
style={ [ styles.iconContainer, { backgroundColor } ] }
>
<Icon
animated
icon={ IconComponent }
style={ { stroke, color } }
/>
</Animated.View>
</TouchableWithoutFeedback>
</View>
);
};

export default compose( [
withSelect( ( select, { clientId } ) => {
const { getBlock } = select( 'core/block-editor' );

const block = getBlock( clientId );
const name = block.name.substring( 17 );
geriux marked this conversation as resolved.
Show resolved Hide resolved

return {
name,
};
} ),
] )( SocialLinkEdit );
Loading