Skip to content

Commit

Permalink
Merge pull request #12 from Automattic/feature/block-manager
Browse files Browse the repository at this point in the history
First very rough version of a block manager
  • Loading branch information
hypest authored Mar 20, 2018
2 parents b0be086 + cee033b commit 3f840cd
Show file tree
Hide file tree
Showing 6 changed files with 264 additions and 19 deletions.
19 changes: 2 additions & 17 deletions App.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,10 @@
// @flow

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import BlockManager from './block-management/block-manager';

export default class App extends React.Component<{}> {
render() {
return (
<View style={ styles.container }>
<Text>Open up App.js to start working on your app!</Text>
<Text>Changes you make will automatically reload.</Text>
<Text>Shake your phone to open the developer menu.</Text>
</View>
);
return <BlockManager />;
}
}

const styles = StyleSheet.create( {
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
} );
65 changes: 65 additions & 0 deletions block-management/block-holder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* @format
* @flow
*/

import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import Toolbar from './toolbar';

type PropsType = {
index: number,
blockType: string,
content: string,
onToolbarButtonPressed: ( button: number, index: number ) => void,
};
type StateType = { selected: boolean, focused: boolean };

export default class BlockHolder extends React.Component<PropsType, StateType> {
state = {
selected: false,
focused: true,
};

renderToolbarIfBlockFocused() {
if ( this.state.focused ) {
return (
<Toolbar index={ this.props.index } onButtonPressed={ this.props.onToolbarButtonPressed } />
);
} else {
// Return empty view, toolbar won't be rendered
return <View />;
}
}

render() {
// TODO: This is a place holder, this should call the edit() method of the block depending on this.props.blockType
return (
<View style={ styles.blockHolder }>
<View style={ styles.blockTitle }>
<Text>BlockType: { this.props.blockType }</Text>
</View>
<View style={ styles.blockContent }>
<Text>{ this.props.content }</Text>
</View>
{ this.renderToolbarIfBlockFocused.bind( this )() }
</View>
);
}
}

const styles = StyleSheet.create( {
blockHolder: {
flex: 1,
},
blockContent: {
backgroundColor: 'white',
padding: 10,
},
blockTitle: {
backgroundColor: 'grey',
paddingLeft: 10,
paddingTop: 4,
paddingBottom: 4,
},
} );
120 changes: 120 additions & 0 deletions block-management/block-manager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/**
* @format
* @flow
*/

import React from 'react';
import { StyleSheet, Text, View, FlatList, TextInput } from 'react-native';
import BlockHolder from './block-holder';
import { ToolbarButton } from './constants';

type PropsType = {};
type StateType = {
refresh: boolean,
blocks: Array<{ key: string, blockType: string, content: string }>,
};

export default class BlockManager extends React.Component<PropsType, StateType> {
constructor( props: PropsType ) {
super( props );
// TODO: block state should be externalized (shared with Gutenberg at some point?).
// If not it should be created from a string parsing (commented HTML to json).
this.state = {
refresh: false,
blocks: [
{
key: '0',
blockType: 'title',
content: 'Hello World',
},
{
key: '1',
blockType: 'paragraph',
content:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer tempor tincidunt sapien, quis dictum orci sollicitudin quis. Proin sed elit id est pulvinar feugiat vitae eget dolor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
},
{
key: '2',
blockType: 'paragraph',
content:
'書籍やウェブページや広告などのデザインのプロトタイプを制作したり顧客にプレゼンテーションしたりする際に、まだ正式な文章の出来上がっていないテキスト部分の書体(フォント)、タイポグラフィ、レイアウトなどといった視覚的なデザインを調整したりわかりやすく見せるために用いられる。',
},
{
key: '3',
blockType: 'code',
content: 'if name == "World":\n return "Hello World"\nelse:\n return "Hello Pony"',
},
{
key: '4',
blockType: 'paragraph',
content:
'Лорем ипсум долор сит амет, адиписци трацтатос еа еум. Меа аудиам малуиссет те, хас меис либрис елеифенд ин. Нец ех тота деленит сусципит. Яуас порро инструцтиор но нец.',
},
],
};
}

onToolbarButtonPressed( button: number, index: number ) {
console.log( 'Button: ' + button + ' - index: ' + index );
var blocks = this.state.blocks;
switch ( button ) {
case ToolbarButton.UP:
if ( index == 0 ) return;
var tmp = blocks[ index ];
blocks[ index ] = blocks[ index - 1 ];
blocks[ index - 1 ] = tmp;
break;
case ToolbarButton.DOWN:
if ( index == blocks.length - 1 ) return;
var tmp = blocks[ index ];
blocks[ index ] = blocks[ index + 1 ];
blocks[ index + 1 ] = tmp;
break;
case ToolbarButton.DELETE:
blocks.splice( index, 1 );
break;
case ToolbarButton.SETTINGS:
// TODO: implement settings
break;
}
this.setState( { blocks: blocks, refresh: ! this.state.refresh } );
}

render() {
return (
<View style={ styles.container }>
<View style={ { height: 30 } } />
<FlatList
style={ styles.list }
data={ this.state.blocks }
extraData={ this.state.refresh }
renderItem={ this.renderItem.bind( this ) }
/>
</View>
);
}

renderItem( value: {
item: { key: string, blockType: string, content: string },
index: number,
} ) {
return (
<BlockHolder
onToolbarButtonPressed={ this.onToolbarButtonPressed.bind( this ) }
index={ value.index }
{ ...value.item }
/>
);
}
}

const styles = StyleSheet.create( {
container: {
flex: 1,
backgroundColor: '#caa',
},
list: {
flex: 1,
backgroundColor: '#ccc',
},
} );
14 changes: 14 additions & 0 deletions block-management/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* @format
* @flow
*/

const ToolbarButton = {
UP: 1,
DOWN: 2,
SETTINGS: 3,
DELETE: 4,
};
type ToolbarButtonType = $Keys<typeof ToolbarButton>;

export { ToolbarButton };
61 changes: 61 additions & 0 deletions block-management/toolbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/** @format */

import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { ToolbarButton } from './constants';

type PropsType = {
index: number,
onButtonPressed: ( button: number, index: number ) => void,
};

export default class Toolbar extends React.Component<PropsType> {
render() {
return (
<View style={ styles.toolbar }>
<Button
style={ styles.toolbarButton }
onPress={ this.props.onButtonPressed.bind( this, ToolbarButton.UP, this.props.index ) }
title="Up"
/>
<Button
style={ styles.toolbarButton }
onPress={ this.props.onButtonPressed.bind( this, ToolbarButton.DOWN, this.props.index ) }
title="Down"
/>
<Button
style={ styles.toolbarButton }
onPress={ this.props.onButtonPressed.bind(
this,
ToolbarButton.SETTINGS,
this.props.index
) }
title="Settings"
/>
<Button
style={ styles.toolbarButton }
onPress={ this.props.onButtonPressed.bind(
this,
ToolbarButton.DELETE,
this.props.index
) }
title="Delete"
/>
</View>
);
}
}

const styles = StyleSheet.create( {
toolbar: {
height: 34,
backgroundColor: 'white',
flexDirection: 'row',
justifyContent: 'space-between',
paddingLeft: 20,
paddingRight: 20,
},
toolbarButton: {
padding: 4,
},
} );
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"ios": "react-native-scripts ios",
"test": "node node_modules/jest/bin/jest.js",
"flow": "flow",
"prettier": "prettier --write *js",
"prettier-check": "prettier -l *js"
"prettier": "prettier --write *.js *block-management/*.js",
"prettier-check": "prettier -l *.js *block-management/*.js"
},
"jest": {
"preset": "jest-expo"
Expand Down

0 comments on commit 3f840cd

Please sign in to comment.