/**
* External dependencies
*/
import { identity } from 'lodash';
import { Text, View, Platform, TouchableWithoutFeedback } from 'react-native';
/**
* WordPress dependencies
*/
import { Component } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { withDispatch, withSelect } from '@wordpress/data';
import { compose, withPreferredColorScheme } from '@wordpress/compose';
import { createBlock, isUnmodifiedDefaultBlock } from '@wordpress/blocks';
import { KeyboardAwareFlatList, ReadableContentView } from '@wordpress/components';
/**
* Internal dependencies
*/
import styles from './style.scss';
import BlockListBlock from './block';
import BlockListAppender from '../block-list-appender';
import FloatingToolbar from './block-mobile-floating-toolbar';
const innerToolbarHeight = 44;
export class BlockList extends Component {
constructor() {
super( ...arguments );
this.renderItem = this.renderItem.bind( this );
this.renderAddBlockSeparator = this.renderAddBlockSeparator.bind( this );
this.renderBlockListFooter = this.renderBlockListFooter.bind( this );
this.renderDefaultBlockAppender = this.renderDefaultBlockAppender.bind( this );
this.onCaretVerticalPositionChange = this.onCaretVerticalPositionChange.bind( this );
this.scrollViewInnerRef = this.scrollViewInnerRef.bind( this );
this.addBlockToEndOfPost = this.addBlockToEndOfPost.bind( this );
this.shouldFlatListPreventAutomaticScroll = this.shouldFlatListPreventAutomaticScroll.bind( this );
}
addBlockToEndOfPost( newBlock ) {
this.props.insertBlock( newBlock, this.props.blockCount );
}
blockHolderBorderStyle() {
return this.props.isFullyBordered ? styles.blockHolderFullBordered : styles.blockHolderSemiBordered;
}
onCaretVerticalPositionChange( targetId, caretY, previousCaretY ) {
KeyboardAwareFlatList.handleCaretVerticalPositionChange( this.scrollViewRef, targetId, caretY, previousCaretY );
}
scrollViewInnerRef( ref ) {
this.scrollViewRef = ref;
}
shouldFlatListPreventAutomaticScroll() {
return this.props.isBlockInsertionPointVisible;
}
renderDefaultBlockAppender() {
return (
);
}
render() {
const { clearSelectedBlock, blockClientIds, isFullyBordered, title, header, withFooter = true, renderAppender, isFirstBlock, selectedBlockParentId } = this.props;
const showFloatingToolbar = isFirstBlock && selectedBlockParentId !== '';
return (
{ showFloatingToolbar && }
{ renderAppender && blockClientIds.length > 0 &&
}
);
}
isReplaceable( block ) {
if ( ! block ) {
return false;
}
return isUnmodifiedDefaultBlock( block );
}
renderItem( { item: clientId, index } ) {
const blockHolderFocusedStyle = this.props.getStylesFromColorScheme( styles.blockHolderFocused, styles.blockHolderFocusedDark );
const { shouldShowBlockAtIndex, shouldShowInsertionPoint } = this.props;
return (
{ shouldShowInsertionPoint( clientId ) && this.renderAddBlockSeparator() }
{ shouldShowBlockAtIndex( index ) && (
) }
);
}
renderAddBlockSeparator() {
const lineStyle = this.props.getStylesFromColorScheme( styles.lineStyleAddHere, styles.lineStyleAddHereDark );
const labelStyle = this.props.getStylesFromColorScheme( styles.labelStyleAddHere, styles.labelStyleAddHereDark );
return (
{ __( 'ADD BLOCK HERE' ) }
);
}
renderBlockListFooter() {
const paragraphBlock = createBlock( 'core/paragraph' );
return (
{
this.addBlockToEndOfPost( paragraphBlock );
} } >
);
}
}
export default compose( [
withSelect( ( select, { rootClientId } ) => {
const {
getBlockCount,
getBlockIndex,
getBlockOrder,
getSelectedBlockClientId,
getBlockInsertionPoint,
isBlockInsertionPointVisible,
getSelectedBlock,
getBlockRootClientId,
} = select( 'core/block-editor' );
const selectedBlockClientId = getSelectedBlockClientId();
const blockClientIds = getBlockOrder( rootClientId );
const insertionPoint = getBlockInsertionPoint();
const blockInsertionPointIsVisible = isBlockInsertionPointVisible();
const selectedBlock = getSelectedBlock();
const isSelectedGroup = selectedBlock && selectedBlock.name === 'core/group';
const shouldShowInsertionPoint = ( clientId ) => {
return (
blockInsertionPointIsVisible &&
insertionPoint.rootClientId === rootClientId &&
blockClientIds[ insertionPoint.index ] === clientId
);
};
const selectedBlockIndex = getBlockIndex( selectedBlockClientId, rootClientId );
const isFirstBlock = selectedBlockIndex === 0;
const selectedBlockParentId = getBlockRootClientId( selectedBlockClientId );
const shouldShowBlockAtIndex = ( index ) => {
const shouldHideBlockAtIndex = (
! isSelectedGroup && blockInsertionPointIsVisible &&
// if `index` === `insertionPoint.index`, then block is replaceable
index === insertionPoint.index &&
// only hide selected block
index === selectedBlockIndex
);
return ! shouldHideBlockAtIndex;
};
return {
blockClientIds,
blockCount: getBlockCount( rootClientId ),
isBlockInsertionPointVisible: isBlockInsertionPointVisible(),
shouldShowBlockAtIndex,
shouldShowInsertionPoint,
selectedBlockClientId,
isFirstBlock,
selectedBlockParentId,
};
} ),
withDispatch( ( dispatch ) => {
const {
insertBlock,
replaceBlock,
clearSelectedBlock,
} = dispatch( 'core/block-editor' );
return {
clearSelectedBlock,
insertBlock,
replaceBlock,
};
} ),
withPreferredColorScheme,
] )( BlockList );