Skip to content

Commit

Permalink
Merge pull request #150 from wordpress-mobile/feature/html-inputview-…
Browse files Browse the repository at this point in the history
…component

Adding HTMLTextInput component
  • Loading branch information
etoledom authored Sep 24, 2018
2 parents 6a8d736 + b57b828 commit e564692
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 64 deletions.
59 changes: 5 additions & 54 deletions src/block-management/block-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@
*/

import React from 'react';
import { Platform, Switch, Text, View, FlatList, TextInput, KeyboardAvoidingView } from 'react-native';
import { Platform, Switch, Text, View, FlatList, KeyboardAvoidingView } from 'react-native';
import RecyclerViewList, { DataSource } from 'react-native-recyclerview-list';
import BlockHolder from './block-holder';
import { ToolbarButton } from './constants';
import type { BlockType } from '../store/';
import styles from './block-manager.scss';
import BlockPicker from './block-picker';
import HTMLTextInput from '../components/html-text-input';

// Gutenberg imports
import {
createBlock,
serialize,
} from '@wordpress/blocks';
import { createBlock } from '@wordpress/blocks';

export type BlockListType = {
onChange: ( clientId: string, attributes: mixed ) => void,
Expand All @@ -38,12 +36,9 @@ type StateType = {
inspectBlocks: boolean,
blockTypePickerVisible: boolean,
selectedBlockType: string,
html: string,
};

export default class BlockManager extends React.Component<PropsType, StateType> {
_htmlTextInput: TextInput = null;

constructor( props: PropsType ) {
super( props );
this.state = {
Expand All @@ -52,7 +47,6 @@ export default class BlockManager extends React.Component<PropsType, StateType>
inspectBlocks: false,
blockTypePickerVisible: false,
selectedBlockType: 'core/paragraph', // just any valid type to start from
html: '', // This is used to hold the Android html text input state.
};
}

Expand Down Expand Up @@ -140,25 +134,6 @@ export default class BlockManager extends React.Component<PropsType, StateType>
}
}

serializeToHtml() {
return this.props.blocks
.map( ( block ) => {
if ( block.name === 'aztec' ) {
return '<aztec>' + block.attributes.content + '</aztec>\n\n';
}

return serialize( [ block ] ) + '\n\n';
} )
.reduce( ( prevVal, value ) => {
return prevVal + value;
}, '' );
}

parseHTML( html: string ) {
const { parseBlocksAction } = this.props;
parseBlocksAction( html );
}

componentDidUpdate() {
// List has been updated, tell the recycler view to update the view
this.state.dataSource.setDirty();
Expand Down Expand Up @@ -251,12 +226,7 @@ export default class BlockManager extends React.Component<PropsType, StateType>
}

handleSwitchEditor = ( showHtml: boolean ) => {
if ( ! showHtml ) {
const html = this._htmlTextInput._lastNativeText;
this.parseHTML( html );
}
const html = this.serializeToHtml();
this.setState( { showHtml, html } );
this.setState( { showHtml } );
}

handleInspectBlocksChanged = ( inspectBlocks: boolean ) => {
Expand Down Expand Up @@ -289,28 +259,9 @@ export default class BlockManager extends React.Component<PropsType, StateType>
);
}

onChangeHTML = ( html: string ) => {
if ( Platform.OS === 'android' ) {
this.setState( { html } );
}
}

renderHTML() {
const behavior = Platform.OS === 'ios' ? 'padding' : null;
const htmlInputRef = ( el ) => this._htmlTextInput = el;

return (
<KeyboardAvoidingView style={ { flex: 1 } } behavior={ behavior }>
<TextInput
textAlignVertical="top"
multiline
ref={ htmlInputRef }
numberOfLines={ 0 }
style={ styles.htmlView }
value={ this.state.html }
onChangeText={ ( html ) => this.onChangeHTML( html ) }
/>
</KeyboardAvoidingView>
<HTMLTextInput { ...this.props } />
);
}
}
10 changes: 0 additions & 10 deletions src/block-management/block-manager.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,6 @@
flex: 1;
}

.htmlView {
font-family: $default-monospace-font;
flex: 1;
background-color: #eee;
padding-left: 8;
padding-right: 8;
padding-top: 8;
padding-bottom: 8;
}

.switch {
flex-direction: row;
justify-content: flex-start;
Expand Down
78 changes: 78 additions & 0 deletions src/components/html-text-input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* @format
* @flow
*/

import React from 'react';
import { Platform, TextInput, KeyboardAvoidingView } from 'react-native';
import styles from './html-text-input.scss';

// Gutenberg imports
import { serialize } from '@wordpress/blocks';

type PropsType = {
blocks: Array<Object>,
parseBlocksAction: string => mixed,
};

type StateType = {
html: string,
};

export default class HTMLInputView extends React.Component<PropsType, StateType> {
state = {
html: '',
}

componentDidMount() {
const html = this.serializeBlocksToHtml();
this.setState( { html } );
}

componentWillUnmount() {
//TODO: Blocking main thread
this.props.parseBlocksAction( this.state.html );
}

shouldComponentUpdate() {
const isIOS = Platform.OS === 'ios';
if ( isIOS ) {
// iOS TextInput gets jumpy if it's updated on every key stroke.
// The first render will always be empty, so:
// If the previous state was empty, we let update the component to show the next state.
return this.state.html === '';
}
return true;
}

serializeBlocksToHtml() {
return this.props.blocks
.map( this.serializeBlock )
.join( '' );
}

serializeBlock( block: Object ) {
if ( block.name === 'aztec' ) {
return '<aztec>' + block.attributes.content + '</aztec>\n\n';
}

return serialize( [ block ] ) + '\n\n';
}

render() {
const behavior = Platform.OS === 'ios' ? 'padding' : null;

return (
<KeyboardAvoidingView style={ styles.container } behavior={ behavior }>
<TextInput
textAlignVertical="top"
multiline
numberOfLines={ 0 }
style={ styles.htmlView }
value={ this.state.html }
onChangeText={ ( html ) => this.setState( { html } ) }
/>
</KeyboardAvoidingView>
);
}
}
18 changes: 18 additions & 0 deletions src/components/html-text-input.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/** @format */

@import '../variables.scss';

.htmlView {
font-family: $default-monospace-font;
flex: 1;
background-color: #eee;
padding-left: 8;
padding-right: 8;
padding-top: 8;
padding-bottom: 8;
}

.container {
flex: 1;
}

0 comments on commit e564692

Please sign in to comment.