From c3ff85f78cd8ee25660643048579d47bcbf5f9f4 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Thu, 11 Apr 2024 17:07:24 +0300 Subject: [PATCH 1/6] Editor: Add wordcount and reading time info in post card --- .../src/components/post-card-panel/index.js | 146 ++++++++++++++---- 1 file changed, 113 insertions(+), 33 deletions(-) diff --git a/packages/editor/src/components/post-card-panel/index.js b/packages/editor/src/components/post-card-panel/index.js index cfb830395ef1f..d974ffc39666e 100644 --- a/packages/editor/src/components/post-card-panel/index.js +++ b/packages/editor/src/components/post-card-panel/index.js @@ -15,45 +15,57 @@ import { } from '@wordpress/components'; import { store as coreStore } from '@wordpress/core-data'; import { useSelect } from '@wordpress/data'; -import { __, sprintf } from '@wordpress/i18n'; +import { __, _x, _n, sprintf } from '@wordpress/i18n'; import { humanTimeDiff } from '@wordpress/date'; import { decodeEntities } from '@wordpress/html-entities'; +import { count as wordCount } from '@wordpress/wordcount'; /** * Internal dependencies */ import { store as editorStore } from '../../store'; -import { TEMPLATE_POST_TYPE } from '../../store/constants'; +import { + TEMPLATE_POST_TYPE, + TEMPLATE_PART_POST_TYPE, +} from '../../store/constants'; import { unlock } from '../../lock-unlock'; import TemplateAreas from '../template-areas'; export default function PostCardPanel( { className, actions } ) { - const { modified, title, templateInfo, icon, postType } = useSelect( - ( select ) => { - const { - getEditedPostAttribute, - getCurrentPostType, - getCurrentPostId, - __experimentalGetTemplateInfo, - } = select( editorStore ); - const { getEditedEntityRecord } = select( coreStore ); - const _type = getCurrentPostType(); - const _id = getCurrentPostId(); - const _record = getEditedEntityRecord( 'postType', _type, _id ); - const _templateInfo = __experimentalGetTemplateInfo( _record ); - return { - title: - _templateInfo?.title || getEditedPostAttribute( 'title' ), - modified: getEditedPostAttribute( 'modified' ), - id: _id, - postType: _type, - templateInfo: _templateInfo, - icon: unlock( select( editorStore ) ).getPostIcon( _type, { - area: _record?.area, - } ), - }; - } - ); + const { + modified, + title, + templateInfo, + icon, + postType, + postContent, + isPostsPage, + } = useSelect( ( select ) => { + const { + getEditedPostAttribute, + getCurrentPostType, + getCurrentPostId, + __experimentalGetTemplateInfo, + } = select( editorStore ); + const { getEditedEntityRecord, getEntityRecord } = select( coreStore ); + const siteSettings = getEntityRecord( 'root', 'site' ); + const _type = getCurrentPostType(); + const _id = getCurrentPostId(); + const _record = getEditedEntityRecord( 'postType', _type, _id ); + const _templateInfo = __experimentalGetTemplateInfo( _record ); + return { + title: _templateInfo?.title || getEditedPostAttribute( 'title' ), + modified: getEditedPostAttribute( 'modified' ), + id: _id, + postType: _type, + templateInfo: _templateInfo, + icon: unlock( select( editorStore ) ).getPostIcon( _type, { + area: _record?.area, + } ), + isPostsPage: +_id === siteSettings?.page_for_posts, + postContent: _record?.content?.rendered || _record?.content, + }; + }, [] ); const description = templateInfo?.description; const lastEditedText = modified && @@ -62,7 +74,10 @@ export default function PostCardPanel( { className, actions } ) { __( 'Last edited %s.' ), humanTimeDiff( modified ) ); - + const showPostContentInfo = + ! [ TEMPLATE_POST_TYPE, TEMPLATE_PART_POST_TYPE ].includes( + postType + ) && ! isPostsPage; return (
- { ( description || lastEditedText ) && ( + { ( description || + lastEditedText || + showPostContentInfo ) && ( { description && { description } } - { lastEditedText && ( - { lastEditedText } - ) } + + { showPostContentInfo && ( + + ) }{ ' ' } + { lastEditedText && ( + { lastEditedText } + ) } + ) } { postType === TEMPLATE_POST_TYPE && } @@ -106,3 +130,59 @@ export default function PostCardPanel( { className, actions } ) { ); } + +// Taken from packages/editor/src/components/time-to-read/index.js. +const AVERAGE_READING_RATE = 189; + +// This component renders the wordcount and reading time for the post. +function PostContentInfo( { postContent } ) { + /* + * translators: If your word count is based on single characters (e.g. East Asian characters), + * enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'. + * Do not translate into your own language. + */ + const wordCountType = _x( 'words', 'Word count type. Do not translate!' ); + const wordsCounted = postContent + ? wordCount( postContent, wordCountType ) + : 0; + if ( ! wordsCounted ) { + return null; + } + const readingTime = Math.round( wordsCounted / AVERAGE_READING_RATE ); + let wordsCountText; + if ( ! wordsCounted.toLocaleString() ) { + wordsCountText = __( 'Unknown' ); + } else { + wordsCountText = + wordsCounted === 1 + ? __( '1 word' ) + : sprintf( + // translators: %s: the number of words in the post. + _n( '%s word', '%s words', wordsCounted ), + wordsCounted.toLocaleString() + ); + } + const readingTimeText = + readingTime <= 1 + ? __( '1 minute read time' ) + : sprintf( + // translators: %s: the number of words in the post. + _n( + '%s minute read time', + '%s minutes read time', + readingTime + ), + readingTime.toLocaleString() + ); + return ( + + { sprintf( + /* translators: 1: How many words a post has(eg. 30 words). 2: the number of minutes of read time(eg. 2 minutes read time) */ + /* translators: %1s: is the number of minutes. */ + '%1$s, %2$s.', + wordsCountText, + readingTimeText + ) } + + ); +} From db9d20070ad8fbfcd89a1ec6ab2138dad26aa454 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Thu, 11 Apr 2024 17:43:25 +0300 Subject: [PATCH 2/6] Apply suggestions from code review Co-authored-by: Miguel Fonseca <150562+mcsf@users.noreply.github.com> --- packages/editor/src/components/post-card-panel/index.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/editor/src/components/post-card-panel/index.js b/packages/editor/src/components/post-card-panel/index.js index d974ffc39666e..9296be70dd1c0 100644 --- a/packages/editor/src/components/post-card-panel/index.js +++ b/packages/editor/src/components/post-card-panel/index.js @@ -75,9 +75,8 @@ export default function PostCardPanel( { className, actions } ) { humanTimeDiff( modified ) ); const showPostContentInfo = - ! [ TEMPLATE_POST_TYPE, TEMPLATE_PART_POST_TYPE ].includes( - postType - ) && ! isPostsPage; + ! isPostsPage && + ! [ TEMPLATE_POST_TYPE, TEMPLATE_PART_POST_TYPE ].includes( postType ); return (
{ sprintf( - /* translators: 1: How many words a post has(eg. 30 words). 2: the number of minutes of read time(eg. 2 minutes read time) */ + /* translators: 1: How many words a post has (e.g. 30 words). 2: the number of minutes of read time (e.g. 2 minutes read time) */ /* translators: %1s: is the number of minutes. */ '%1$s, %2$s.', wordsCountText, From c05ea6048fe7aa4898bb8ee2294faa1b5b130ae7 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Thu, 11 Apr 2024 18:03:56 +0300 Subject: [PATCH 3/6] feedback part 1 --- packages/editor/src/components/post-actions/index.js | 2 +- packages/editor/src/components/post-card-panel/index.js | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/editor/src/components/post-actions/index.js b/packages/editor/src/components/post-actions/index.js index b3a6cee47d31f..379231b0a9dff 100644 --- a/packages/editor/src/components/post-actions/index.js +++ b/packages/editor/src/components/post-actions/index.js @@ -89,7 +89,7 @@ export default function PostActions( { onActionPerformed } ) { { sprintf( - /* translators: 1: How many words a post has (e.g. 30 words). 2: the number of minutes of read time (e.g. 2 minutes read time) */ - /* translators: %1s: is the number of minutes. */ + /* translators: 1: How many words a post has. 2: the number of minutes to read the post (e.g. 130 words, 2 minutes read time.) */ '%1$s, %2$s.', wordsCountText, readingTimeText From 46513c939d3126aa4e6d4cbf922bdc854a00617f Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Thu, 11 Apr 2024 18:06:05 +0300 Subject: [PATCH 4/6] feedback --- packages/editor/src/components/post-card-panel/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor/src/components/post-card-panel/index.js b/packages/editor/src/components/post-card-panel/index.js index 747f7ec04320a..140d6487e923c 100644 --- a/packages/editor/src/components/post-card-panel/index.js +++ b/packages/editor/src/components/post-card-panel/index.js @@ -177,7 +177,7 @@ function PostContentInfo( { postContent } ) { { sprintf( /* translators: 1: How many words a post has. 2: the number of minutes to read the post (e.g. 130 words, 2 minutes read time.) */ - '%1$s, %2$s.', + __( '%1$s, %2$s.' ), wordsCountText, readingTimeText ) } From e237a0751da464388d2e005f7d7cc233b9ec4e2f Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Thu, 11 Apr 2024 18:15:20 +0300 Subject: [PATCH 5/6] feedback --- .../src/components/post-card-panel/index.js | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/packages/editor/src/components/post-card-panel/index.js b/packages/editor/src/components/post-card-panel/index.js index 140d6487e923c..c4646207c969d 100644 --- a/packages/editor/src/components/post-card-panel/index.js +++ b/packages/editor/src/components/post-card-panel/index.js @@ -111,16 +111,12 @@ export default function PostCardPanel( { className, actions } ) { spacing={ 2 } > { description && { description } } - - { showPostContentInfo && ( - - ) }{ ' ' } - { lastEditedText && ( - { lastEditedText } - ) } - + { showPostContentInfo && ( + + ) } + { lastEditedText && ( + { lastEditedText } + ) } ) } { postType === TEMPLATE_POST_TYPE && } @@ -148,19 +144,16 @@ function PostContentInfo( { postContent } ) { return null; } const readingTime = Math.round( wordsCounted / AVERAGE_READING_RATE ); - let wordsCountText; - if ( ! wordsCounted.toLocaleString() ) { - wordsCountText = __( 'Unknown' ); - } else { - wordsCountText = - wordsCounted === 1 - ? __( '1 word' ) - : sprintf( - // translators: %s: the number of words in the post. - _n( '%s word', '%s words', wordsCounted ), - wordsCounted.toLocaleString() - ); - } + const wordsCountText = + wordsCounted.toLocaleString() && + ( wordsCounted === 1 + ? __( '1 word' ) + : sprintf( + // translators: %s: the number of words in the post. + _n( '%s word', '%s words', wordsCounted ), + wordsCounted.toLocaleString() + ) ); + const readingTimeText = readingTime <= 1 ? __( '1 minute read time' ) @@ -175,12 +168,19 @@ function PostContentInfo( { postContent } ) { ); return ( - { sprintf( - /* translators: 1: How many words a post has. 2: the number of minutes to read the post (e.g. 130 words, 2 minutes read time.) */ - __( '%1$s, %2$s.' ), - wordsCountText, - readingTimeText - ) } + { wordsCountText + ? sprintf( + /* translators: 1: How many words a post has. 2: the number of minutes to read the post (e.g. 130 words, 2 minutes read time.) */ + __( '%1$s, %2$s.' ), + wordsCountText, + readingTimeText + ) + : sprintf( + /* translators: %s is a short phrase without any closing punctuation (e.g. "2 minutes read time"). Please translate only if you need a punctuation sign other than a period. */ + __( '%s.' ), + wordsCountText, + readingTimeText + ) } ); } From 28135e7da0f220ef47a8c77e9bfb4d1b4c139c73 Mon Sep 17 00:00:00 2001 From: ntsekouras Date: Fri, 12 Apr 2024 11:24:31 +0300 Subject: [PATCH 6/6] address feedback --- .../src/components/post-card-panel/index.js | 46 ++++++------------- 1 file changed, 15 insertions(+), 31 deletions(-) diff --git a/packages/editor/src/components/post-card-panel/index.js b/packages/editor/src/components/post-card-panel/index.js index c4646207c969d..757040f6336b6 100644 --- a/packages/editor/src/components/post-card-panel/index.js +++ b/packages/editor/src/components/post-card-panel/index.js @@ -63,7 +63,7 @@ export default function PostCardPanel( { className, actions } ) { area: _record?.area, } ), isPostsPage: +_id === siteSettings?.page_for_posts, - postContent: _record?.content?.rendered || _record?.content, + postContent: getEditedPostAttribute( 'content' ), }; }, [] ); const description = templateInfo?.description; @@ -144,43 +144,27 @@ function PostContentInfo( { postContent } ) { return null; } const readingTime = Math.round( wordsCounted / AVERAGE_READING_RATE ); - const wordsCountText = - wordsCounted.toLocaleString() && - ( wordsCounted === 1 - ? __( '1 word' ) - : sprintf( - // translators: %s: the number of words in the post. - _n( '%s word', '%s words', wordsCounted ), - wordsCounted.toLocaleString() - ) ); - - const readingTimeText = + const wordsCountText = sprintf( + // translators: %s: the number of words in the post. + _n( '%s word', '%s words', wordsCounted ), + wordsCounted.toLocaleString() + ); + const minutesText = readingTime <= 1 - ? __( '1 minute read time' ) + ? __( '1 minute' ) : sprintf( // translators: %s: the number of minutes to read the post. - _n( - '%s minute read time', - '%s minutes read time', - readingTime - ), + _n( '%s minute', '%s minutes', readingTime ), readingTime.toLocaleString() ); return ( - { wordsCountText - ? sprintf( - /* translators: 1: How many words a post has. 2: the number of minutes to read the post (e.g. 130 words, 2 minutes read time.) */ - __( '%1$s, %2$s.' ), - wordsCountText, - readingTimeText - ) - : sprintf( - /* translators: %s is a short phrase without any closing punctuation (e.g. "2 minutes read time"). Please translate only if you need a punctuation sign other than a period. */ - __( '%s.' ), - wordsCountText, - readingTimeText - ) } + { sprintf( + /* translators: 1: How many words a post has. 2: the number of minutes to read the post (e.g. 130 words, 2 minutes read time.) */ + __( '%1$s, %2$s read time.' ), + wordsCountText, + minutesText + ) } ); }