added read time on index and post pages

This commit is contained in:
Rick van Lieshout 2022-09-29 22:28:06 +02:00
parent 619758c175
commit 6a9ceb9670
22 changed files with 103 additions and 50 deletions

View File

@ -4,8 +4,6 @@ This is the repository for my personal blog/website [rickvanlieshout.com](https:
## Todo
- "time to read" (https://www.gatsbyjs.com/plugins/gatsby-remark-reading-time/)
<!-- migrations -->
- migrate resume
@ -14,4 +12,3 @@ This is the repository for my personal blog/website [rickvanlieshout.com](https:
<!-- optional stuff -->
- release to sftp or gh-pages
- lighthouse doesn't like the blue... :)

View File

@ -52,7 +52,7 @@ const createPages: GatsbyNode["createPages"] = async ({ graphql, actions }) => {
createPage({
path: node.fields.slug,
component: constants.templates.postTemplate,
context: { slug: node.fields.slug },
context: { slug: node.fields.slug, readingTime: node?.fields?.readingTime },
});
}
});

View File

@ -1,15 +1,12 @@
import { GatsbyNode } from "gatsby";
import { createFilePath } from "gatsby-source-filesystem";
import readingTime from "reading-time";
import * as constants from "./constants";
import * as types from "./types";
import * as utils from "./utils";
const onCreateNode: GatsbyNode["onCreateNode"] = ({
node,
actions,
getNode,
}) => {
const onCreateNode: GatsbyNode["onCreateNode"] = ({ node, actions, getNode }) => {
const { createNodeField } = actions;
if (node.internal.type === "MarkdownRemark") {
@ -31,12 +28,7 @@ const onCreateNode: GatsbyNode["onCreateNode"] = ({
if (tags) {
const value = tags.map((tag) =>
utils.concat(
constants.routes.tagRoute,
"/",
utils.toKebabCase(tag),
"/",
),
utils.concat(constants.routes.tagRoute, "/", utils.toKebabCase(tag), "/")
);
createNodeField({ node, name: "tagSlugs", value });
@ -47,11 +39,17 @@ const onCreateNode: GatsbyNode["onCreateNode"] = ({
constants.routes.categoryRoute,
"/",
utils.toKebabCase(category),
"/",
"/"
);
createNodeField({ node, name: "categorySlug", value });
}
createNodeField({
node,
name: "readingTime",
value: readingTime(node.rawMarkdownBody as string),
});
}
};

View File

@ -19,6 +19,9 @@ const pagesQuery = async (graphql: CreatePagesArgs["graphql"]) => {
}
fields {
slug
readingTime {
text
}
}
}
}

View File

@ -18,6 +18,9 @@ const postsQuery = async (graphql: CreatePagesArgs["graphql"]) => {
node {
fields {
slug
readingTime {
text
}
}
}
}

View File

@ -13,6 +13,9 @@ interface Fields {
slug?: string;
categorySlug?: string;
tagSlugs?: Array<string>;
readingTime?: {
text: string;
};
}
interface Node extends GatsbyNode {

13
package-lock.json generated
View File

@ -43,7 +43,8 @@
"react-cookie-consent": "^8.0.1",
"react-dom": "^18.2.0",
"react-helmet": "^6.1.0",
"react-toggle": "^4.1.3"
"react-toggle": "^4.1.3",
"reading-time": "^1.5.0"
},
"devDependencies": {
"@jest/globals": "^27.5.1",
@ -29075,6 +29076,11 @@
"node": ">=8.10.0"
}
},
"node_modules/reading-time": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz",
"integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg=="
},
"node_modules/recursive-readdir": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
@ -55669,6 +55675,11 @@
"picomatch": "^2.2.1"
}
},
"reading-time": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz",
"integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg=="
},
"recursive-readdir": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",

View File

@ -78,7 +78,8 @@
"react-cookie-consent": "^8.0.1",
"react-dom": "^18.2.0",
"react-helmet": "^6.1.0",
"react-toggle": "^4.1.3"
"react-toggle": "^4.1.3",
"reading-time": "^1.5.0"
},
"devDependencies": {
"@jest/globals": "^27.5.1",

View File

@ -5,7 +5,6 @@ import { Link } from "gatsby";
import * as styles from "./Feed.module.scss";
import { Edge } from "@/types";
type Props = {
edges: Array<Edge>;
};
@ -17,12 +16,14 @@ const Feed: React.FC<Props> = ({ edges }: Props) => (
<div className={styles.meta}>
<time
className={styles.time}
dateTime={new Date(edge.node.frontmatter.date).toLocaleDateString(
"en-US",
{ year: "numeric", month: "long", day: "numeric" },
)}
dateTime={new Date(edge.node.frontmatter.date).toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "numeric",
})}
>
{new Date(edge.node.frontmatter.date).toLocaleDateString("en-US", {
{new Date(edge.node.frontmatter.date).toLocaleDateString("en-Us", {
day: "numeric",
year: "numeric",
month: "long",
})}
@ -39,11 +40,9 @@ const Feed: React.FC<Props> = ({ edges }: Props) => (
{edge.node.frontmatter.title}
</Link>
</h2>
<p className={styles.description}>
{edge.node.frontmatter.description}
</p>
<p className={styles.description}>{edge.node.frontmatter.description}</p>
<Link className={styles.more} to={edge.node.fields.slug}>
Read
Read ({edge.node.fields.readingTime?.text})
</Link>
</div>
))}

View File

@ -7,7 +7,7 @@ exports[`Feed renders correctly 1`] = `
<time
dateTime="September 1, 2016"
>
September 2016
September 1, 2016
</time>
<span />
<span>
@ -31,7 +31,8 @@ exports[`Feed renders correctly 1`] = `
<a
href="/posts/perfecting-the-art-of-perfection"
>
Read
Read (
)
</a>
</div>
<div>
@ -39,7 +40,7 @@ exports[`Feed renders correctly 1`] = `
<time
dateTime="September 1, 2016"
>
September 2016
September 1, 2016
</time>
<span />
<span>
@ -63,7 +64,8 @@ exports[`Feed renders correctly 1`] = `
<a
href="/posts/the-birth-of-movable-type"
>
Read
Read (
)
</a>
</div>
</div>

View File

@ -9,13 +9,23 @@
.title {
font-size: $typographic-base-font-size * 2;
font-weight: 600;
margin-bottom: 0px !important;
margin-left: auto;
margin-right: auto;
max-width: $layout-post-width;
text-align: center;
@include line-height(1.65);
@include margin-top(1);
@include margin-bottom(0);
}
.subTitle {
font-size: $typographic-base-font-size;
font-style: italic;
margin-left: auto;
margin-right: auto;
margin-top: 0px;
max-width: $layout-post-width;
text-align: center;
}
.body {
@ -48,7 +58,7 @@
max-width: $layout-post-width;
}
h2 > a {
h2>a {
visibility: hidden;
}
@ -80,7 +90,7 @@
@include margin-bottom(1.125);
}
h2 > a {
h2>a {
visibility: unset;
@include padding-right(1);
}

View File

@ -6,15 +6,17 @@ import * as styles from "./Content.module.scss";
interface Props {
title: string;
body: string;
subTitle?: string;
}
const Content: React.FC<Props> = ({ body, title }: Props) => {
const Content: React.FC<Props> = ({ body, title, subTitle }: Props) => {
const { author } = useSiteMetadata();
return (
<>
<PostHeader author={author} />
<div className={styles.content}>
<h1 className={styles.title}>{title}</h1>
<h2 className={styles.subTitle}>- {subTitle}</h2>
<div className={styles.body} dangerouslySetInnerHTML={{ __html: body }} />
</div>
</>

View File

@ -138,6 +138,9 @@ exports[`Content renders correctly 1`] = `
<h1>
Perfecting the Art of Perfection
</h1>
<h2>
-
</h2>
<div
dangerouslySetInnerHTML={
{

View File

@ -13,13 +13,13 @@ interface Props {
const Post: React.FC<Props> = ({ post }: Props) => {
const { html } = post;
const { tagSlugs, slug } = post.fields;
const { tagSlugs, slug, readingTime } = post.fields;
const { tags, title, date, disqusId } = post.frontmatter;
return (
<div className={styles.post}>
<div className={styles.content}>
<Content body={html} title={title} />
<Content body={html} title={title} subTitle={readingTime?.text} />
</div>
<div className={styles.footer}>

View File

@ -139,6 +139,9 @@ exports[`Post renders correctly 1`] = `
<h1>
Perfecting the Art of Perfection
</h1>
<h2>
-
</h2>
<div
dangerouslySetInnerHTML={
{

View File

@ -258,7 +258,7 @@ exports[`CategoryTemplate renders correctly 1`] = `
<time
dateTime="September 1, 2016"
>
September 2016
September 1, 2016
</time>
<span />
<span>
@ -282,7 +282,8 @@ exports[`CategoryTemplate renders correctly 1`] = `
<a
href="/posts/perfecting-the-art-of-perfection"
>
Read
Read (
)
</a>
</div>
<div>
@ -290,7 +291,7 @@ exports[`CategoryTemplate renders correctly 1`] = `
<time
dateTime="September 1, 2016"
>
September 2016
September 1, 2016
</time>
<span />
<span>
@ -314,7 +315,8 @@ exports[`CategoryTemplate renders correctly 1`] = `
<a
href="/posts/the-birth-of-movable-type"
>
Read
Read (
)
</a>
</div>
</div>

View File

@ -54,6 +54,9 @@ export const query = graphql`
fields {
categorySlug
slug
readingTime {
text
}
}
frontmatter {
description

View File

@ -255,7 +255,7 @@ exports[`IndexTemplate renders correctly 1`] = `
<time
dateTime="September 1, 2016"
>
September 2016
September 1, 2016
</time>
<span />
<span>
@ -279,7 +279,8 @@ exports[`IndexTemplate renders correctly 1`] = `
<a
href="/posts/perfecting-the-art-of-perfection"
>
Read
Read (
)
</a>
</div>
<div>
@ -287,7 +288,7 @@ exports[`IndexTemplate renders correctly 1`] = `
<time
dateTime="September 1, 2016"
>
September 2016
September 1, 2016
</time>
<span />
<span>
@ -311,7 +312,8 @@ exports[`IndexTemplate renders correctly 1`] = `
<a
href="/posts/the-birth-of-movable-type"
>
Read
Read (
)
</a>
</div>
</div>

View File

@ -38,6 +38,9 @@ export const query = graphql`
fields {
slug
tagSlugs
readingTime {
text
}
}
frontmatter {
date

View File

@ -140,6 +140,9 @@ exports[`PostTemplate renders correctly 1`] = `
<h1>
Perfecting the Art of Perfection
</h1>
<h2>
-
</h2>
<div
dangerouslySetInnerHTML={
{

View File

@ -258,7 +258,7 @@ exports[`TagTemplate renders correctly 1`] = `
<time
dateTime="September 1, 2016"
>
September 2016
September 1, 2016
</time>
<span />
<span>
@ -282,7 +282,8 @@ exports[`TagTemplate renders correctly 1`] = `
<a
href="/posts/perfecting-the-art-of-perfection"
>
Read
Read (
)
</a>
</div>
<div>
@ -290,7 +291,7 @@ exports[`TagTemplate renders correctly 1`] = `
<time
dateTime="September 1, 2016"
>
September 2016
September 1, 2016
</time>
<span />
<span>
@ -314,7 +315,8 @@ exports[`TagTemplate renders correctly 1`] = `
<a
href="/posts/the-birth-of-movable-type"
>
Read
Read (
)
</a>
</div>
</div>

View File

@ -2,6 +2,9 @@ interface Fields {
slug: string;
categorySlug: string;
tagSlugs?: Array<string>;
readingTime?: {
text: string;
};
}
export default Fields;