diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-11-06 18:08:04 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-11-11 18:15:27 +0100 |
| commit | c9c1c90b30e243563bb4f731da15b3fe657556d2 (patch) | |
| tree | 8263c176b4096e2893b9d9319bfa7edb01fce188 /src/utils | |
| parent | 2771de88f40a5f4ed7480bd8614532dda72deeda (diff) | |
refactor(components): replace Summary component with PostPreview
* rename component to PostPreview because Summary is an HTML element
and it could lead to confusion
* replace `title` and `titleLevel` with `heading` and `headingLvl`
because `title` is a native attribute
* rename `intro` prop to `excerpt`
* extract `cover` from `meta` prop
* rewrite meta type
* extract meta logic into a new component
Diffstat (limited to 'src/utils')
| -rw-r--r-- | src/utils/helpers/index.ts | 1 | ||||
| -rw-r--r-- | src/utils/helpers/pages.tsx (renamed from src/utils/helpers/pages.ts) | 36 | ||||
| -rw-r--r-- | src/utils/helpers/reading-time.test.ts | 31 | ||||
| -rw-r--r-- | src/utils/helpers/reading-time.ts | 46 |
4 files changed, 107 insertions, 7 deletions
diff --git a/src/utils/helpers/index.ts b/src/utils/helpers/index.ts index 14487e6..f340a49 100644 --- a/src/utils/helpers/index.ts +++ b/src/utils/helpers/index.ts @@ -1,6 +1,7 @@ export * from './author'; export * from './images'; export * from './pages'; +export * from './reading-time'; export * from './rss'; export * from './schema-org'; export * from './strings'; diff --git a/src/utils/helpers/pages.ts b/src/utils/helpers/pages.tsx index 84854cd..556b4fb 100644 --- a/src/utils/helpers/pages.ts +++ b/src/utils/helpers/pages.tsx @@ -1,4 +1,5 @@ -import type { LinksListItems, Post } from '../../components'; +import NextImage from 'next/image'; +import type { LinksListItems, PostData } from '../../components'; import { getArticleFromRawData } from '../../services/graphql'; import type { Article, @@ -72,13 +73,32 @@ export const getLinksListItems = (links: PageLink[]): LinksListItems[] => * Retrieve the posts list with the article URL. * * @param {Article[]} posts - An array of articles. - * @returns {Post[]} An array of posts with full article URL. + * @returns {PostData[]} An array of posts with full article URL. */ -export const getPostsWithUrl = (posts: Article[]): Post[] => - posts.map((post) => { +export const getPostsWithUrl = (posts: Article[]): PostData[] => + posts.map(({ intro, meta, slug, title, ...post }) => { return { ...post, - url: `/article/${post.slug}`, + cover: meta.cover ? <NextImage {...meta.cover} /> : undefined, + excerpt: intro, + heading: title, + meta: { + publicationDate: meta.dates.publication, + updateDate: meta.dates.update, + wordsCount: meta.wordsCount, + author: meta.author?.name, + thematics: meta.thematics, + topics: meta.topics, + comments: + meta.commentsCount === undefined + ? undefined + : { + count: meta.commentsCount, + postHeading: title, + url: `${ROUTES.ARTICLE}/${slug}#comments`, + }, + }, + url: `${ROUTES.ARTICLE}/${slug}`, }; }); @@ -86,9 +106,11 @@ export const getPostsWithUrl = (posts: Article[]): Post[] => * Retrieve the posts list from raw data. * * @param {EdgesResponse<RawArticle>[]} rawData - The raw data. - * @returns {Post[]} An array of posts. + * @returns {PostData[]} An array of posts. */ -export const getPostsList = (rawData: EdgesResponse<RawArticle>[]): Post[] => { +export const getPostsList = ( + rawData: EdgesResponse<RawArticle>[] +): PostData[] => { const articlesList: RawArticle[] = []; rawData.forEach((articleData) => { articleData.edges.forEach((edge) => { diff --git a/src/utils/helpers/reading-time.test.ts b/src/utils/helpers/reading-time.test.ts new file mode 100644 index 0000000..24181a6 --- /dev/null +++ b/src/utils/helpers/reading-time.test.ts @@ -0,0 +1,31 @@ +import { describe, it } from '@jest/globals'; +import { getReadingTimeFrom } from './reading-time'; + +describe('reading-time', () => { + it('can transform a words count into a reading time in minutes', () => { + const wordsCount = 250; + + // With the default settings, 250 words should be rounded to one minute. + expect(getReadingTimeFrom(wordsCount).inMinutes()).toBe(1); + }); + + it('can transform a words count into a reading time in minutes and seconds', () => { + const wordsCount = 1200; + const readingTime = getReadingTimeFrom(wordsCount).inMinutesAndSeconds(); + + expect(readingTime.minutes).toBeGreaterThan(1); + expect(readingTime.seconds).toBeGreaterThan(0); + }); + + it('can use a custom words per minute setting', () => { + const wordsCount = 100; + const wordsPerMinute = 100; + const readingTime = getReadingTimeFrom( + wordsCount, + wordsPerMinute + ).inMinutesAndSeconds(); + + expect(readingTime.minutes).toBe(1); + expect(readingTime.seconds).toBe(0); + }); +}); diff --git a/src/utils/helpers/reading-time.ts b/src/utils/helpers/reading-time.ts new file mode 100644 index 0000000..6cdeba4 --- /dev/null +++ b/src/utils/helpers/reading-time.ts @@ -0,0 +1,46 @@ +export type GetReadingTimeReturn = { + /** + * The reading time rounded to minutes. + */ + inMinutes: () => number; + /** + * The reading time in minutes and seconds. + */ + inMinutesAndSeconds: () => { + minutes: number; + seconds: number; + }; +}; + +/** + * Retrieve the reading time from a words count. + * + * @param {number} wordsCount - The number of words. + * @param {number} [wordsPerMinute] - How many words can we read per minute? + * @returns {GetReadingTimeReturn} Two methods to retrieve the reading time. + */ +export const getReadingTimeFrom = ( + wordsCount: number, + wordsPerMinute = 245 +): GetReadingTimeReturn => { + const ONE_MINUTE_IN_SECONDS = 60; + const wordsPerSecond = wordsPerMinute / ONE_MINUTE_IN_SECONDS; + const estimatedTimeInSeconds = wordsCount / wordsPerSecond; + + return { + inMinutes: () => Math.round(estimatedTimeInSeconds / ONE_MINUTE_IN_SECONDS), + inMinutesAndSeconds: () => { + const estimatedTimeInMinutes = Math.floor( + estimatedTimeInSeconds / ONE_MINUTE_IN_SECONDS + ); + + return { + minutes: estimatedTimeInMinutes, + seconds: Math.round( + estimatedTimeInSeconds - + estimatedTimeInMinutes * ONE_MINUTE_IN_SECONDS + ), + }; + }, + }; +}; |
