Skip to content

Commit

Permalink
[RNMobile] Latest Posts Block v1 Support in Mobile (#20301)
Browse files Browse the repository at this point in the history
* Display basic support block for Latest Posts

* Update UI of Latest Posts Placeholder

* Add Post Content Control to the Latest post config menu

* Add support for Post Content Settings and Post Meta Data settings

* Expose QueryControls to Mobile

* Add Post Sorting and options for Latest Post Block

* Refactor LatestPost to allow hooks in component mounting for api requests

* Fix Style issue

* Add Network call on Latest-Posts to fetch categories

* Reorder Options in Latest Posts

* Show configure menu in Latests Posts on focus and on tap of configure

* Reorganize consts

* Reorganize consts

* Mmove web refrences to use defined constants

* Reorder Latest Post Settings to match Web

* Adjust setting for Categories selection

* Fix Prettier issue

* Resolve PHP style issue

* Adjust data parsing for Android

* Adjust the way of identifying the way to parse categoriesList

* Remove Clear Settings and rename the configure button to customize

* Remove function that automatically prompts the settings when tapping on the block

* Implement text and control changes from design feedback

* Adjust separators for Latest Post

* Adjust latest-post post content label to be more excerpt centric, and update wording of related control.

* Update label of excerpt length on latest-posts

* Adjust casing of customize label

* Align customize style with add media empty state

* Fix style issue

* Move set attribute events out of the render function

* Add developer comment for platform differences

* Refactor syntax on set functions

* Modify inspector controls to follow the style of the attribute setters

* Update design of block title

* Update spacing around block

* Add type checking to block non array responses from categoreis request
  • Loading branch information
chipsnyder authored Mar 11, 2020
1 parent 34afbfd commit 12b81b0
Show file tree
Hide file tree
Showing 11 changed files with 425 additions and 76 deletions.
1 change: 1 addition & 0 deletions packages/block-library/src/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ export const registerCoreBlocks = () => {
button,
spacer,
shortcode,
latestPosts,
devOnly( verse ),
cover,
].forEach( registerBlock );
Expand Down
72 changes: 72 additions & 0 deletions packages/block-library/src/latest-posts/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"name": "core/latest-posts",
"category": "widgets",
"attributes": {
"align": {
"type": "string",
"enum": ["left", "center", "right", "wide", "full"]
},
"className": {
"type": "string"
},
"categories": {
"type": "array"
},
"postsToShow": {
"type": "number",
"default": 5
},
"displayPostContent": {
"type": "boolean",
"default": false
},
"displayPostContentRadio": {
"type": "string",
"default": "excerpt"
},
"excerptLength": {
"type": "number",
"default": 55
},
"displayPostDate": {
"type": "boolean",
"default": false
},
"postLayout": {
"type": "string",
"default": "list"
},
"columns": {
"type": "number",
"default": 3
},
"order": {
"type": "string",
"default": "desc"
},
"orderBy": {
"type": "string",
"default": "date"
},
"displayFeaturedImage": {
"type": "boolean",
"default": false
},
"featuredImageAlign": {
"type": "string",
"enum": ["left", "center", "right"]
},
"featuredImageSizeSlug": {
"type": "string",
"default":"thumbnail"
},
"featuredImageSizeWidth": {
"type": "number",
"default":null
},
"featuredImageSizeHeight": {
"type": "number",
"default":null
}
}
}
3 changes: 3 additions & 0 deletions packages/block-library/src/latest-posts/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const MIN_EXCERPT_LENGTH = 10;
export const MAX_EXCERPT_LENGTH = 100;
export const MAX_POSTS_COLUMNS = 6;
14 changes: 11 additions & 3 deletions packages/block-library/src/latest-posts/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,21 @@ import {
import { withSelect } from '@wordpress/data';
import { pin, list, grid } from '@wordpress/icons';

/**
* Internal dependencies
*/
import {
MIN_EXCERPT_LENGTH,
MAX_EXCERPT_LENGTH,
MAX_POSTS_COLUMNS,
} from './constants';

/**
* Module Constants
*/
const CATEGORIES_LIST_QUERY = {
per_page: -1,
};
const MAX_POSTS_COLUMNS = 6;

class LatestPostsEdit extends Component {
constructor() {
Expand Down Expand Up @@ -150,8 +158,8 @@ class LatestPostsEdit extends Component {
onChange={ ( value ) =>
setAttributes( { excerptLength: value } )
}
min={ 10 }
max={ 100 }
min={ MIN_EXCERPT_LENGTH }
max={ MAX_EXCERPT_LENGTH }
/>
) }
</PanelBody>
Expand Down
261 changes: 261 additions & 0 deletions packages/block-library/src/latest-posts/edit.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
/**
* External dependencies
*/
import { TouchableWithoutFeedback, View, Text } from 'react-native';
import { isEmpty } from 'lodash';

/**
* WordPress dependencies
*/
import { Component } from '@wordpress/element';
import { compose, withPreferredColorScheme } from '@wordpress/compose';
import { withDispatch } from '@wordpress/data';
import { coreBlocks } from '@wordpress/block-library';
import { __ } from '@wordpress/i18n';
import { postList as icon } from '@wordpress/icons';
import { InspectorControls } from '@wordpress/block-editor';
import { fetchRequest } from 'react-native-gutenberg-bridge';
import {
Icon,
PanelBody,
ToggleControl,
RangeControl,
QueryControls,
} from '@wordpress/components';

/**
* Internal dependencies
*/
import styles from './style.scss';
import { MIN_EXCERPT_LENGTH, MAX_EXCERPT_LENGTH } from './constants';

class LatestPostsEdit extends Component {
constructor() {
super( ...arguments );
this.state = {
categoriesList: [],
};
this.onSetDisplayPostContent = this.onSetDisplayPostContent.bind(
this
);
this.onSetDisplayPostContentRadio = this.onSetDisplayPostContentRadio.bind(
this
);
this.onSetExcerptLength = this.onSetExcerptLength.bind( this );
this.onSetDisplayPostDate = this.onSetDisplayPostDate.bind( this );
this.onSetOrder = this.onSetOrder.bind( this );
this.onSetOrderBy = this.onSetOrderBy.bind( this );
this.onSetPostsToShow = this.onSetPostsToShow.bind( this );
this.onSetCategories = this.onSetCategories.bind( this );
this.getInspectorControls = this.getInspectorControls.bind( this );
}

componentDidMount() {
this.isStillMounted = true;
this.fetchRequest = fetchRequest( '/wp/v2/categories' )
.then( ( categoriesList ) => {
if ( this.isStillMounted ) {
let parsedCategoriesList = categoriesList;

// TODO: remove this check after `fetchRequest` types are made consist across platforms
// (see: https://github.com/wordpress-mobile/gutenberg-mobile/issues/1961)
if ( typeof categoriesList === 'string' ) {
parsedCategoriesList = JSON.parse( categoriesList );
}

if ( isEmpty( parsedCategoriesList ) ) {
parsedCategoriesList = [];
}

this.setState( {
categoriesList: parsedCategoriesList,
} );
}
} )
.catch( () => {
if ( this.isStillMounted ) {
this.setState( { categoriesList: [] } );
}
} );
}

componentWillUnmount() {
this.isStillMounted = false;
}

onSetDisplayPostContent( value ) {
const { setAttributes } = this.props;
setAttributes( { displayPostContent: value } );
}

onSetDisplayPostContentRadio( value ) {
const { setAttributes } = this.props;
setAttributes( {
displayPostContentRadio: value ? 'excerpt' : 'full_post',
} );
}

onSetExcerptLength( value ) {
const { setAttributes } = this.props;
setAttributes( { excerptLength: value } );
}

onSetDisplayPostDate( value ) {
const { setAttributes } = this.props;
setAttributes( { displayPostDate: value } );
}

onSetOrder( value ) {
const { setAttributes } = this.props;
setAttributes( { order: value } );
}

onSetOrderBy( value ) {
const { setAttributes } = this.props;
setAttributes( { orderBy: value } );
}

onSetPostsToShow( value ) {
const { setAttributes } = this.props;
setAttributes( { postsToShow: value } );
}

onSetCategories( value ) {
const { setAttributes } = this.props;
setAttributes( {
categories: '' !== value ? value.toString() : undefined,
} );
}

getInspectorControls() {
const { attributes } = this.props;
const {
displayPostContent,
displayPostContentRadio,
excerptLength,
displayPostDate,
order,
orderBy,
postsToShow,
categories,
} = attributes;

const { categoriesList } = this.state;
const displayExcerptPostContent = displayPostContentRadio === 'excerpt';

return (
<InspectorControls>
<PanelBody title={ __( 'Post content settings' ) }>
<ToggleControl
label={ __( 'Show post content' ) }
checked={ displayPostContent }
onChange={ this.onSetDisplayPostContent }
separatorType={
displayPostContent ? 'fullWidth' : 'none'
}
/>
{ displayPostContent && (
<ToggleControl
label={ __( 'Only show excerpt' ) }
checked={ displayExcerptPostContent }
onChange={ this.onSetDisplayPostContentRadio }
separatorType={
displayExcerptPostContent ? 'fullWidth' : 'none'
}
/>
) }
{ displayPostContent && displayExcerptPostContent && (
<RangeControl
label={ __( 'Excerpt length (words)' ) }
value={ excerptLength }
onChange={ this.onSetExcerptLength }
min={ MIN_EXCERPT_LENGTH }
max={ MAX_EXCERPT_LENGTH }
separatorType="none"
/>
) }
</PanelBody>

<PanelBody title={ __( 'Post meta settings' ) }>
<ToggleControl
label={ __( 'Display post date' ) }
checked={ displayPostDate }
onChange={ this.onSetDisplayPostDate }
separatorType="none"
/>
</PanelBody>

<PanelBody title={ __( 'Sorting and filtering' ) }>
<QueryControls
{ ...{ order, orderBy } }
numberOfItems={ postsToShow }
categoriesList={ categoriesList }
selectedCategoryId={
undefined !== categories ? Number( categories ) : ''
}
onOrderChange={ this.onSetOrder }
onOrderByChange={ this.onSetOrderBy }
onCategoryChange={ this.onSetCategories }
onNumberOfItemsChange={ this.onSetPostsToShow }
/>
</PanelBody>
</InspectorControls>
);
}

render() {
const {
getStylesFromColorScheme,
name,
openGeneralSidebar,
isSelected,
} = this.props;

const blockType = coreBlocks[ name ];

const blockStyle = getStylesFromColorScheme(
styles.latestPostBlock,
styles.latestPostBlockDark
);

const iconStyle = getStylesFromColorScheme(
styles.latestPostBlockIcon,
styles.latestPostBlockIconDark
);

const titleStyle = getStylesFromColorScheme(
styles.latestPostBlockMessage,
styles.latestPostBlockMessageDark
);

return (
<TouchableWithoutFeedback
accessible={ ! isSelected }
disabled={ ! isSelected }
onPress={ openGeneralSidebar }
>
<View style={ blockStyle }>
{ this.getInspectorControls() }
<Icon icon={ icon } { ...iconStyle } />
<Text style={ titleStyle }>
{ blockType.settings.title }
</Text>
<Text style={ styles.latestPostBlockSubtitle }>
{ __( 'CUSTOMIZE' ) }
</Text>
</View>
</TouchableWithoutFeedback>
);
}
}

export default compose( [
withDispatch( ( dispatch ) => {
const { openGeneralSidebar } = dispatch( 'core/edit-post' );

return {
openGeneralSidebar: () => openGeneralSidebar( 'edit-post/block' ),
};
} ),
withPreferredColorScheme,
] )( LatestPostsEdit );
5 changes: 3 additions & 2 deletions packages/block-library/src/latest-posts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import { postList as icon } from '@wordpress/icons';
* Internal dependencies
*/
import edit from './edit';
import metadata from './block.json';

export const name = 'core/latest-posts';
const { name } = metadata;
export { metadata, name };

export const settings = {
title: __( 'Latest Posts' ),
description: __( 'Display a list of your most recent posts.' ),
icon,
category: 'widgets',
keywords: [ __( 'recent posts' ) ],
supports: {
align: true,
Expand Down
Loading

0 comments on commit 12b81b0

Please sign in to comment.