Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Mobile - Clipboard refactor
Browse files Browse the repository at this point in the history
Gerardo Pacheco committed Nov 24, 2020
1 parent 0ac08dc commit cc9044a
Showing 5 changed files with 149 additions and 93 deletions.
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import { partial, first, castArray, last, compact } from 'lodash';
/**
* WordPress dependencies
*/
import { ToolbarButton, Picker } from '@wordpress/components';
import { ClipboardContext, ToolbarButton, Picker } from '@wordpress/components';
import {
getBlockType,
getDefaultBlockName,
@@ -19,7 +19,7 @@ import { __, sprintf } from '@wordpress/i18n';
import { withDispatch, withSelect } from '@wordpress/data';
import { withInstanceId, compose } from '@wordpress/compose';
import { moreHorizontalMobile } from '@wordpress/icons';
import { useRef } from '@wordpress/element';
import { useRef, useContext } from '@wordpress/element';
/**
* Internal dependencies
*/
@@ -40,15 +40,19 @@ const BlockActionsMenu = ( {
anchorNodeRef,
getBlocksByClientId,
selectedBlockClientId,
updateClipboard,
createSuccessNotice,
duplicateBlock,
removeBlocks,
pasteBlock,
isPasteEnabled,
canInsertBlockType,
rootClientId,
} ) => {
const pickerRef = useRef();
const moversOptions = { keys: [ 'icon', 'actionTitle' ] };
const {
clipboard: { current: currentClipboard },
updateClipboard,
} = useContext( ClipboardContext );

const {
actionTitle: {
@@ -115,11 +119,29 @@ const BlockActionsMenu = ( {
wrapBlockSettings && settingsOption,
copyButtonOption,
cutButtonOption,
isPasteEnabled && pasteButtonOption,
isPasteEnabled() && pasteButtonOption,
duplicateButtonOption,
deleteOption,
] );

function onPasteBlock() {
if ( ! currentClipboard ) {
return;
}

pasteBlock( rawHandler( { HTML: currentClipboard } )[ 0 ] );
}

function isPasteEnabled() {
const clipboardBlock =
currentClipboard && rawHandler( { HTML: currentClipboard } )[ 0 ];

return (
clipboardBlock &&
canInsertBlockType( clipboardBlock.name, rootClientId )
);
}

function onPickerSelect( value ) {
switch ( value ) {
case deleteOption.value:
@@ -156,7 +178,7 @@ const BlockActionsMenu = ( {
);
break;
case pasteButtonOption.value:
pasteBlock();
onPasteBlock();
createSuccessNotice(
// translators: displayed right after the block is pasted.
__( 'Block pasted' )
@@ -228,7 +250,6 @@ export default compose(
getSelectedBlockClientIds,
canInsertBlockType,
} = select( 'core/block-editor' );
const { getClipboard } = select( 'core/editor' );
const normalizedClientIds = castArray( clientIds );
const block = getBlock( normalizedClientIds );
const blockName = getBlockName( normalizedClientIds );
@@ -250,13 +271,6 @@ export default compose(
const isEmptyDefaultBlock =
isExactlyOneBlock && isDefaultBlock && isEmptyContent;

const clipboard = getClipboard();
const clipboardBlock =
clipboard && rawHandler( { HTML: clipboard } )[ 0 ];
const isPasteEnabled =
clipboardBlock &&
canInsertBlockType( clipboardBlock.name, rootClientId );

return {
isFirst: firstIndex === 0,
isLast: lastIndex === blockOrder.length - 1,
@@ -266,16 +280,11 @@ export default compose(
getBlocksByClientId,
selectedBlockClientId: getSelectedBlockClientIds(),
currentIndex: firstIndex,
isPasteEnabled,
clipboardBlock,
canInsertBlockType,
};
} ),
withDispatch(
(
dispatch,
{ clientIds, rootClientId, currentIndex, clipboardBlock },
{ select }
) => {
( dispatch, { clientIds, rootClientId, currentIndex }, { select } ) => {
const {
moveBlocksDown,
moveBlocksUp,
@@ -285,7 +294,6 @@ export default compose(
replaceBlocks,
} = dispatch( 'core/block-editor' );
const { openGeneralSidebar } = dispatch( 'core/edit-post' );
const { updateClipboard } = dispatch( 'core/editor' );
const { getBlockSelectionEnd, getBlock } = select(
'core/block-editor'
);
@@ -296,13 +304,12 @@ export default compose(
onMoveUp: partial( moveBlocksUp, clientIds, rootClientId ),
openGeneralSidebar: () =>
openGeneralSidebar( 'edit-post/block' ),
updateClipboard,
createSuccessNotice,
duplicateBlock() {
return duplicateBlocks( clientIds );
},
removeBlocks,
pasteBlock: () => {
pasteBlock: ( clipboardBlock ) => {
const canReplaceBlock = isUnmodifiedDefaultBlock(
getBlock( getBlockSelectionEnd() )
);
139 changes: 80 additions & 59 deletions packages/block-editor/src/components/inserter/menu.native.js
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ import {
BottomSheet,
BottomSheetConsumer,
InserterButton,
ClipboardConsumer,
} from '@wordpress/components';

/**
@@ -111,6 +112,37 @@ export class InserterMenu extends Component {
this.setState( { numberOfColumns, itemWidth, maxWidth } );
}

getItems( clipboard ) {
const {
items,
canInsertBlockType,
destinationRootClientId,
getBlockType,
} = this.props;

const { current: currentClipboard } = clipboard;
const clipboardBlock =
currentClipboard && rawHandler( { HTML: currentClipboard } )[ 0 ];
const shouldAddClipboardBlock =
clipboardBlock &&
canInsertBlockType( clipboardBlock.name, destinationRootClientId );

return shouldAddClipboardBlock
? [
{
...pick( getBlockType( clipboardBlock.name ), [
'name',
'icon',
] ),
id: 'clipboard',
initialAttributes: clipboardBlock.attributes,
innerBlocks: clipboardBlock.innerBlocks,
},
...items,
]
: items;
}

renderItem( { item } ) {
const { itemWidth, maxWidth } = this.state;
const { onSelect } = this.props;
@@ -125,48 +157,55 @@ export class InserterMenu extends Component {
}

render() {
const { items } = this.props;
const { numberOfColumns } = this.state;

return (
<BottomSheet
isVisible={ true }
onClose={ this.onClose }
hideHeader
hasNavigation
>
<TouchableHighlight accessible={ false }>
<BottomSheetConsumer>
{ ( { listProps, safeAreaBottomInset } ) => (
<FlatList
onLayout={ this.onLayout }
key={ `InserterUI-${ numberOfColumns }` } //re-render when numberOfColumns changes
keyboardShouldPersistTaps="always"
numColumns={ numberOfColumns }
data={ items }
ItemSeparatorComponent={ () => (
<TouchableWithoutFeedback
accessible={ false }
>
<View style={ styles.rowSeparator } />
</TouchableWithoutFeedback>
<ClipboardConsumer>
{ ( { clipboard } ) => (
<BottomSheet
isVisible={ true }
onClose={ this.onClose }
hideHeader
hasNavigation
>
<TouchableHighlight accessible={ false }>
<BottomSheetConsumer>
{ ( { listProps, safeAreaBottomInset } ) => (
<FlatList
onLayout={ this.onLayout }
key={ `InserterUI-${ numberOfColumns }` } //re-render when numberOfColumns changes
keyboardShouldPersistTaps="always"
numColumns={ numberOfColumns }
data={ this.getItems( clipboard ) }
ItemSeparatorComponent={ () => (
<TouchableWithoutFeedback
accessible={ false }
>
<View
style={
styles.rowSeparator
}
/>
</TouchableWithoutFeedback>
) }
keyExtractor={ ( item ) => item.name }
renderItem={ this.renderItem }
{ ...listProps }
contentContainerStyle={ [
...listProps.contentContainerStyle,
{
paddingBottom:
safeAreaBottomInset ||
styles.list.paddingBottom,
},
] }
/>
) }
keyExtractor={ ( item ) => item.name }
renderItem={ this.renderItem }
{ ...listProps }
contentContainerStyle={ [
...listProps.contentContainerStyle,
{
paddingBottom:
safeAreaBottomInset ||
styles.list.paddingBottom,
},
] }
/>
) }
</BottomSheetConsumer>
</TouchableHighlight>
</BottomSheet>
</BottomSheetConsumer>
</TouchableHighlight>
</BottomSheet>
) }
</ClipboardConsumer>
);
}
}
@@ -182,7 +221,6 @@ export default compose(
canInsertBlockType,
} = select( 'core/block-editor' );
const { getChildBlockNames, getBlockType } = select( 'core/blocks' );
const { getClipboard } = select( 'core/editor' );

let destinationRootClientId = rootClientId;
if ( ! destinationRootClientId && ! clientId && ! isAppender ) {
@@ -199,31 +237,14 @@ export default compose(
const {
__experimentalShouldInsertAtTheTop: shouldInsertAtTheTop,
} = getSettings();
const clipboard = getClipboard();
const clipboardBlock =
clipboard && rawHandler( { HTML: clipboard } )[ 0 ];
const shouldAddClipboardBlock =
clipboardBlock &&
canInsertBlockType( clipboardBlock.name, destinationRootClientId );

return {
rootChildBlocks: getChildBlockNames( destinationRootBlockName ),
items: shouldAddClipboardBlock
? [
{
...pick( getBlockType( clipboardBlock.name ), [
'name',
'icon',
] ),
id: 'clipboard',
initialAttributes: clipboardBlock.attributes,
innerBlocks: clipboardBlock.innerBlocks,
},
...getInserterItems( destinationRootClientId ),
]
: getInserterItems( destinationRootClientId ),
items: getInserterItems( destinationRootClientId ),
destinationRootClientId,
shouldInsertAtTheTop,
getBlockType,
canInsertBlockType,
};
} ),
withDispatch( ( dispatch, ownProps, { select } ) => {
5 changes: 5 additions & 0 deletions packages/components/src/index.native.js
Original file line number Diff line number Diff line change
@@ -81,6 +81,11 @@ export { default as LinkSettingsNavigation } from './mobile/link-settings/link-s
export { default as Image, IMAGE_DEFAULT_FOCAL_POINT } from './mobile/image';
export { default as ImageEditingButton } from './mobile/image/image-editing-button';
export { default as InserterButton } from './mobile/inserter-button';
export {
default as ClipboardProvider,
ClipboardContext,
ClipboardConsumer,
} from './mobile/clipboard';

// Utils
export { colorsUtils } from './mobile/color-settings/utils';
21 changes: 21 additions & 0 deletions packages/components/src/mobile/clipboard/index.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* WordPress dependencies
*/
import { createContext, useCallback, useRef } from '@wordpress/element';

export const ClipboardContext = createContext( {} );
const { Provider, Consumer } = ClipboardContext;
export { Consumer as ClipboardConsumer };

export default function ClipboardProvider( { children } ) {
const clipboard = useRef();
const updateClipboard = useCallback( ( clipboardUpdate ) => {
clipboard.current = clipboardUpdate;
}, [] );

return (
<Provider value={ { clipboard, updateClipboard } }>
{ children }
</Provider>
);
}
22 changes: 12 additions & 10 deletions packages/edit-post/src/editor.native.js
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ import { parse, serialize, rawHandler } from '@wordpress/blocks';
import { withDispatch, withSelect } from '@wordpress/data';
import { compose } from '@wordpress/compose';
import { subscribeSetFocusOnTitle } from '@wordpress/react-native-bridge';
import { SlotFillProvider } from '@wordpress/components';
import { SlotFillProvider, ClipboardProvider } from '@wordpress/components';
import { Preview } from '@wordpress/block-editor';

/**
@@ -145,15 +145,17 @@ class Editor extends Component {

return (
<SlotFillProvider>
<EditorProvider
settings={ editorSettings }
post={ normalizedPost }
initialEdits={ initialEdits }
useSubRegistry={ false }
{ ...props }
>
{ this.editorMode( initialHtml, editorMode ) }
</EditorProvider>
<ClipboardProvider>
<EditorProvider
settings={ editorSettings }
post={ normalizedPost }
initialEdits={ initialEdits }
useSubRegistry={ false }
{ ...props }
>
{ this.editorMode( initialHtml, editorMode ) }
</EditorProvider>
</ClipboardProvider>
</SlotFillProvider>
);
}

0 comments on commit cc9044a

Please sign in to comment.