Skip to content

Commit

Permalink
@wordpress/editor: Add estimated time to read to table of contents …
Browse files Browse the repository at this point in the history
…in editor (#41611)

* Add TimeToRead component

* Add TimeToRead to the table of contents panel

* Adjust average reading rate

* Use createInterpolateElement to show the minutes to read

* Re-order information in toc panel
  • Loading branch information
opr authored Jul 6, 2022
1 parent 299b894 commit bc071fc
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 2 deletions.
9 changes: 7 additions & 2 deletions packages/editor/src/components/table-of-contents/panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor';
* Internal dependencies
*/
import WordCount from '../word-count';
import TimeToRead from '../time-to-read';
import DocumentOutline from '../document-outline';
import CharacterCount from '../character-count';

Expand Down Expand Up @@ -38,15 +39,19 @@ function TableOfContentsPanel( { hasOutlineItemsDisabled, onRequestClose } ) {
tabIndex="0"
>
<ul role="list" className="table-of-contents__counts">
<li className="table-of-contents__count">
{ __( 'Words' ) }
<WordCount />
</li>
<li className="table-of-contents__count">
{ __( 'Characters' ) }
<span className="table-of-contents__number">
<CharacterCount />
</span>
</li>
<li className="table-of-contents__count">
{ __( 'Words' ) }
<WordCount />
{ __( 'Time to read' ) }
<TimeToRead />
</li>
<li className="table-of-contents__count">
{ __( 'Headings' ) }
Expand Down
59 changes: 59 additions & 0 deletions packages/editor/src/components/time-to-read/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* WordPress dependencies
*/
import { useSelect } from '@wordpress/data';
import { _x, _n, __, sprintf } from '@wordpress/i18n';
import { count as wordCount } from '@wordpress/wordcount';
import { createInterpolateElement } from '@wordpress/element';

/**
* Internal dependencies
*/
import { store as editorStore } from '../../store';

/**
* Average reading rate - based on average taken from
* https://irisreading.com/average-reading-speed-in-various-languages/
* (Characters/minute used for Chinese rather than words).
*
* @type {number} A rough estimate of the average reading rate across multiple languages.
*/
const AVERAGE_READING_RATE = 189;

export default function TimeToRead() {
const content = useSelect(
( select ) => select( editorStore ).getEditedPostAttribute( 'content' ),
[]
);

/*
* 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 minutesToRead = Math.round(
wordCount( content, wordCountType ) / AVERAGE_READING_RATE
);
const minutesToReadString =
minutesToRead === 0
? createInterpolateElement( __( '<span>< 1</span> minute' ), {
span: <span className="table-of-contents__number" />,
} )
: createInterpolateElement(
sprintf(
/* translators: %s is the number of minutes the post will take to read. */
_n(
'<span>%d</span> minute',
'<span>%d</span> minutes',
minutesToRead
),
minutesToRead
),
{
span: <span className="table-of-contents__number" />,
}
);

return <span className="time-to-read">{ minutesToReadString }</span>;
}

0 comments on commit bc071fc

Please sign in to comment.