44 */
55
66import React from 'react' ;
7- import { Platform , Switch , Text , View , FlatList } from 'react-native' ;
7+ import { Platform , Switch , Text , View , FlatList , Picker } from 'react-native' ;
88import RecyclerViewList , { DataSource } from 'react-native-recyclerview-list' ;
99import BlockHolder from './block-holder' ;
1010import { ToolbarButton } from './constants' ;
1111import type { BlockType } from '../store/' ;
1212import styles from './block-manager.scss' ;
1313// Gutenberg imports
14- import { getBlockType , serialize , createBlock } from '@wordpress/blocks' ;
14+ import { getBlockType , getBlockTypes , serialize , createBlock } from '@wordpress/blocks' ;
1515
1616export type BlockListType = {
1717 onChange : ( clientId : string , attributes : mixed ) => void ,
@@ -29,16 +29,21 @@ type PropsType = BlockListType;
2929type StateType = {
3030 dataSource : DataSource ,
3131 showHtml : boolean ,
32+ blockTypePickerVisible : boolean ,
33+ selectedBlockType : string ,
3234} ;
3335
3436export default class BlockManager extends React . Component < PropsType , StateType > {
3537 _recycler = null ;
38+ availableBlockTypes = getBlockTypes ( ) ;
3639
3740 constructor ( props : PropsType ) {
3841 super ( props ) ;
3942 this . state = {
4043 dataSource : new DataSource ( this . props . blocks , ( item : BlockType ) => item . clientId ) ,
4144 showHtml : false ,
45+ blockTypePickerVisible : false ,
46+ selectedBlockType : 'core/paragraph' , // just any valid type to start from
4247 } ;
4348 }
4449
@@ -56,6 +61,41 @@ export default class BlockManager extends React.Component<PropsType, StateType>
5661 return - 1 ;
5762 }
5863
64+ findDataSourceIndexForFocusedItem ( ) {
65+ for ( let i = 0 ; i < this . state . dataSource . size ( ) ; ++ i ) {
66+ const block = this . state . dataSource . get ( i ) ;
67+ if ( block . focused === true ) {
68+ return i ;
69+ }
70+ }
71+ return - 1 ;
72+ }
73+
74+ // TODO: in the near future this will likely be changed to onShowBlockTypePicker and bound to this.props
75+ // once we move the action to the toolbar
76+ showBlockTypePicker ( ) {
77+ this . setState ( { ...this . state , blockTypePickerVisible : true } ) ;
78+ }
79+
80+ onBlockTypeSelected ( itemValue : string ) {
81+ this . setState ( { ...this . state , selectedBlockType : itemValue , blockTypePickerVisible : false } ) ;
82+
83+ // find currently focused block
84+ const focusedItemIndex = this . findDataSourceIndexForFocusedItem ( ) ;
85+ const clientIdFocused = this . state . dataSource . get ( focusedItemIndex ) . clientId ;
86+
87+ // create an empty block of the selected type
88+ const newBlock = createBlock ( itemValue , { content : 'new test text for a ' + itemValue + ' block' } ) ;
89+ newBlock . focused = false ;
90+
91+ // set it into the datasource, and use the same object instance to send it to props/redux
92+ this . state . dataSource . splice ( focusedItemIndex + 1 , 0 , newBlock ) ;
93+ this . props . createBlockAction ( newBlock . clientId , newBlock , clientIdFocused ) ;
94+
95+ // now set the focus
96+ this . props . focusBlockAction ( newBlock . clientId ) ;
97+ }
98+
5999 onToolbarButtonPressed ( button : number , clientId : string ) {
60100 const dataSourceBlockIndex = this . getDataSourceIndexFromUid ( clientId ) ;
61101 switch ( button ) {
@@ -72,11 +112,7 @@ export default class BlockManager extends React.Component<PropsType, StateType>
72112 this . props . deleteBlockAction ( clientId ) ;
73113 break ;
74114 case ToolbarButton . PLUS :
75- // TODO: block type picker here instead of hardcoding a core/code block
76- const newBlock = createBlock ( 'core/paragraph' , { content : 'new test text for a core/paragraph block' } ) ;
77- const newBlockWithFocusedState = { ...newBlock , focused : false } ;
78- this . state . dataSource . splice ( dataSourceBlockIndex + 1 , 0 , newBlockWithFocusedState ) ;
79- this . props . createBlockAction ( newBlockWithFocusedState . clientId , newBlockWithFocusedState , clientId ) ;
115+ this . showBlockTypePicker ( ) ;
80116 break ;
81117 case ToolbarButton . SETTINGS :
82118 // TODO: implement settings
@@ -146,6 +182,20 @@ export default class BlockManager extends React.Component<PropsType, StateType>
146182 ) ;
147183 }
148184
185+ const blockTypePicker = (
186+ < View >
187+ < Picker
188+ selectedValue = { this . state . selectedBlockType }
189+ onValueChange = { ( itemValue ) => {
190+ this . onBlockTypeSelected ( itemValue ) ;
191+ } } >
192+ { this . availableBlockTypes . map ( ( item , index ) => {
193+ return ( < Picker . Item label = { item . title } value = { item . name } key = { index + 1 } /> ) ;
194+ } ) }
195+ </ Picker >
196+ </ View >
197+ ) ;
198+
149199 return (
150200 < View style = { styles . container } >
151201 < View style = { { height : 30 } } />
@@ -160,6 +210,7 @@ export default class BlockManager extends React.Component<PropsType, StateType>
160210 </ View >
161211 { this . state . showHtml && < Text style = { styles . htmlView } > { this . serializeToHtml ( ) } </ Text > }
162212 { ! this . state . showHtml && list }
213+ { this . state . blockTypePickerVisible && blockTypePicker }
163214 </ View >
164215 ) ;
165216 }
0 commit comments