/** * 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 );