diff --git a/.eslintrc b/.eslintrc
index 11c23a0a..aaefbec8 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -12,6 +12,7 @@
"files": ["**/*.ts", "**/*.tsx"],
"parser": "@typescript-eslint/parser",
"extends": [
+ "plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:jsx-a11y/recommended",
"prettier/@typescript-eslint",
@@ -32,7 +33,8 @@
"ecmaFeatures": {
"jsx": true
},
- "project": "./tsconfig.json"
+ "project": "./tsconfig.json",
+ "tsconfigRootDir": "./"
}
}
]
diff --git a/jest/__fixtures__/avatar.json b/jest/__fixtures__/avatar.json
new file mode 100644
index 00000000..f540fd70
--- /dev/null
+++ b/jest/__fixtures__/avatar.json
@@ -0,0 +1,20 @@
+{
+ "edges": [
+ {
+ "node": {
+ "childImageSharp": {
+ "fixed": {
+ "aspectRatio": 1,
+ "width": 80,
+ "height": 80,
+ "src": "/static/b61a09d5f4cbd9d8b2844091590ddea4/fce1d/avatar.jpg",
+ "srcSet": "/static/b61a09d5f4cbd9d8b2844091590ddea4/fce1d/avatar.jpg 1x,\n/static/b61a09d5f4cbd9d8b2844091590ddea4/c4de8/avatar.jpg 1.5x,\n/static/b61a09d5f4cbd9d8b2844091590ddea4/c3234/avatar.jpg 2x",
+ "srcWebp": "/static/b61a09d5f4cbd9d8b2844091590ddea4/ad6b8/avatar.webp",
+ "srcSetWebp": "/static/b61a09d5f4cbd9d8b2844091590ddea4/ad6b8/avatar.webp 1x,\n/static/b61a09d5f4cbd9d8b2844091590ddea4/5c322/avatar.webp 1.5x,\n/static/b61a09d5f4cbd9d8b2844091590ddea4/5bf6b/avatar.webp 2x",
+ "originalName": "avatar.jpg"
+ }
+ }
+ }
+ }
+ ]
+}
diff --git a/jest/__mocks__/gatsby.ts b/jest/__mocks__/gatsby.ts
index 67e6940e..ee8e8621 100644
--- a/jest/__mocks__/gatsby.ts
+++ b/jest/__mocks__/gatsby.ts
@@ -4,25 +4,11 @@ const gatsby = jest.requireActual('gatsby')
export default {
...gatsby,
graphql: jest.fn(),
- Link: jest.fn().mockImplementation(
- // these props are invalid for an `a` tag
- ({
- /* eslint-disable @typescript-eslint/no-unused-vars */
- activeClassName,
- activeStyle,
- getProps,
- innerRef,
- ref,
- replace,
- to,
- /* eslint-enable @typescript-eslint/no-unused-vars */
- ...rest
- }) =>
- React.createElement('a', {
- ...rest,
- href: to
- })
- ),
+ Link: jest
+ .fn()
+ .mockImplementation(({ to, ...rest }) =>
+ React.createElement('a', { ...rest, href: to })
+ ),
StaticQuery: jest.fn(),
useStaticQuery: jest.fn()
}
diff --git a/package.json b/package.json
index 3f3a4442..28cb2d0b 100644
--- a/package.json
+++ b/package.json
@@ -98,6 +98,7 @@
"@types/react-helmet": "^5.0.11",
"@types/react-modal": "^3.8.3",
"@types/react-transition-group": "^4.2.3",
+ "@types/shortid": "0.0.29",
"@types/web3": "^1.0.20",
"@typescript-eslint/eslint-plugin": "^2.3.3",
"@typescript-eslint/parser": "^2.3.3",
@@ -121,6 +122,7 @@
"pify": "^4.0.1",
"prettier": "^1.18.2",
"prettier-stylelint": "^0.4.2",
+ "shortid": "^2.2.15",
"stylelint": "^11.1.1",
"stylelint-config-css-modules": "^1.5.0",
"stylelint-config-prettier": "^6.0.0",
diff --git a/src/components/atoms/Qr.test.tsx b/src/components/atoms/Qr.test.tsx
index 20c86528..5666f4da 100644
--- a/src/components/atoms/Qr.test.tsx
+++ b/src/components/atoms/Qr.test.tsx
@@ -1,10 +1,10 @@
import React from 'react'
-import { render, fireEvent, wait } from '@testing-library/react'
+import { render, fireEvent } from '@testing-library/react'
import Qr from './Qr'
describe('Qr', () => {
- it('renders without crashing', async () => {
+ it('renders without crashing', () => {
const { container } = render()
expect(container.firstChild).toBeInTheDocument()
fireEvent.click(container.querySelector('button'))
diff --git a/src/components/molecules/IconLinks.tsx b/src/components/molecules/IconLinks.tsx
index 7b21e1e2..e8cbd97e 100644
--- a/src/components/molecules/IconLinks.tsx
+++ b/src/components/molecules/IconLinks.tsx
@@ -20,6 +20,8 @@ function NetworkIcon({ link }: { link: string }) {
Icon =
} else if (link.includes('feed.json')) {
Icon =
+ } else {
+ return null
}
return Icon
diff --git a/src/components/molecules/Pagination.tsx b/src/components/molecules/Pagination.tsx
index 9a1670d6..b1fc066a 100644
--- a/src/components/molecules/Pagination.tsx
+++ b/src/components/molecules/Pagination.tsx
@@ -1,23 +1,26 @@
import React from 'react'
import { Link } from 'gatsby'
+import shortid from 'shortid'
import styles from './Pagination.module.scss'
-const PageNumber = ({ i, current }: { i: number; current?: boolean }) => (
-
- {i + 1}
-
-)
+function PageNumber({ i, current }: { i: number; current?: boolean }) {
+ const classes = current ? styles.current : styles.number
+ const link = i === 0 ? '' : `/page/${i + 1}`
-const PrevNext = ({
+ return (
+
+ {i + 1}
+
+ )
+}
+
+function PrevNext({
prevPagePath,
nextPagePath
}: {
prevPagePath?: string
nextPagePath?: string
-}) => {
+}) {
const link = prevPagePath || nextPagePath
const rel = prevPagePath ? 'prev' : 'next'
const title = prevPagePath ? 'Newer Posts' : 'Older Posts'
@@ -45,13 +48,13 @@ export default function Pagination({
const prevPagePath = currentPageNumber === 2 ? '/' : `/page/${prevPage}`
const nextPagePath = `/page/${nextPage}`
- return nextPage && nextPage > 1 ? (
+ return (
{Array.from({ length: numPages }, (_, i) => (
@@ -59,5 +62,5 @@ export default function Pagination({
- ) : null
+ )
}
diff --git a/src/components/molecules/Vcard.test.tsx b/src/components/molecules/Vcard.test.tsx
new file mode 100644
index 00000000..a29c4247
--- /dev/null
+++ b/src/components/molecules/Vcard.test.tsx
@@ -0,0 +1,28 @@
+import React from 'react'
+import { render } from '@testing-library/react'
+
+import { VcardPure as Vcard } from './Vcard'
+import avatar from '../../../jest/__fixtures__/avatar.json'
+
+const links = [
+ 'twitter.com',
+ 'github.com',
+ 'facebook.com',
+ 'feed.xml',
+ 'feed.json',
+ 'whatever'
+]
+
+describe('Vcard', () => {
+ it('renders without crashing', () => {
+ const { container } = render(
+
+ )
+ expect(container.firstChild).toBeInTheDocument()
+ })
+})
diff --git a/src/components/molecules/Vcard.tsx b/src/components/molecules/Vcard.tsx
index 6410a7a9..a604a933 100644
--- a/src/components/molecules/Vcard.tsx
+++ b/src/components/molecules/Vcard.tsx
@@ -1,33 +1,21 @@
import React from 'react'
import { graphql, useStaticQuery } from 'gatsby'
-import Img from 'gatsby-image'
+import Img, { FixedObject } from 'gatsby-image'
import IconLinks from './IconLinks'
import styles from './Vcard.module.scss'
import { useSiteMetadata } from '../../hooks/use-site-metadata'
-const query = graphql`
- query {
- avatar: allFile(filter: { name: { eq: "avatar" } }) {
- edges {
- node {
- childImageSharp {
- fixed(width: 80, height: 80, quality: 90) {
- ...GatsbyImageSharpFixed_withWebp_noBase64
- }
- }
- }
- }
- }
- }
-`
-
-export default function Vcard() {
- const data = useStaticQuery(query)
- const { author, rss, jsonfeed } = useSiteMetadata()
- const { twitter, github, name, uri } = author
- const avatar = data.avatar.edges[0].node.childImageSharp.fixed
- const links = [twitter, github, rss, jsonfeed]
-
+export function VcardPure({
+ avatar,
+ uri,
+ name,
+ links
+}: {
+ avatar: FixedObject
+ uri: string
+ name: string
+ links: string[]
+}) {
return (
@@ -42,3 +30,29 @@ export default function Vcard() {
)
}
+
+export default function Vcard() {
+ const query = graphql`
+ query {
+ avatar: allFile(filter: { name: { eq: "avatar" } }) {
+ edges {
+ node {
+ childImageSharp {
+ fixed(width: 80, height: 80, quality: 90) {
+ ...GatsbyImageSharpFixed_withWebp_noBase64
+ }
+ }
+ }
+ }
+ }
+ }
+ `
+
+ const data = useStaticQuery(query)
+ const { author, rss, jsonfeed } = useSiteMetadata()
+ const { twitter, github, name, uri } = author
+ const avatar = data.avatar.edges[0].node.childImageSharp.fixed
+ const links = [twitter, github, rss, jsonfeed]
+
+ return
+}
diff --git a/src/hooks/use-site-metadata.ts b/src/hooks/use-site-metadata.ts
index 48110ebe..7914ef48 100644
--- a/src/hooks/use-site-metadata.ts
+++ b/src/hooks/use-site-metadata.ts
@@ -1,38 +1,38 @@
import { useStaticQuery, graphql } from 'gatsby'
-const query = graphql`
- query {
- site {
- siteMetadata {
- siteTitle
- siteTitleShort
- siteDescription
- siteUrl
- author {
- name
- email
- uri
- twitter
- github
- facebook
- bitcoin
- ether
+export const useSiteMetadata = () => {
+ const query = graphql`
+ query {
+ site {
+ siteMetadata {
+ siteTitle
+ siteTitleShort
+ siteDescription
+ siteUrl
+ author {
+ name
+ email
+ uri
+ twitter
+ github
+ facebook
+ bitcoin
+ ether
+ }
+ typekitID
+ menu {
+ title
+ link
+ }
+ rss
+ jsonfeed
+ itemsPerPage
+ repoContentPath
}
- typekitID
- menu {
- title
- link
- }
- rss
- jsonfeed
- itemsPerPage
- repoContentPath
}
}
- }
-`
+ `
-export const useSiteMetadata = () => {
const { site } = useStaticQuery(query)
return site.siteMetadata
}
diff --git a/src/templates/Posts.tsx b/src/templates/Posts.tsx
index 2933d77e..7c59cafe 100644
--- a/src/templates/Posts.tsx
+++ b/src/templates/Posts.tsx
@@ -20,10 +20,15 @@ export default function Posts({
}: {
data: any
location: Location
- pageContext: { tag: string; currentPageNumber: number; numPages: number }
+ pageContext: {
+ tag: string
+ currentPageNumber: number
+ numPages: number
+ nextPage: number
+ }
}) {
const edges = data.allMarkdownRemark.edges
- const { tag, currentPageNumber, numPages } = pageContext
+ const { tag, currentPageNumber, numPages, nextPage } = pageContext
const PostsList = edges.map(({ node }: { node: any }) => {
const { type, linkurl, title, image } = node.frontmatter
@@ -75,7 +80,7 @@ export default function Posts({
>{`Page ${currentPageNumber} / ${numPages}`}
)}
{PostsList}
-
+ {nextPage && nextPage > 1 && }
)
}
diff --git a/tsconfig.json b/tsconfig.json
index 0323eb41..7c47c1d7 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -9,7 +9,8 @@
"lib": ["dom", "esnext"],
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
- "allowJs": true
+ "allowJs": true,
+ "resolveJsonModule": true
},
"exclude": ["node_modules", "public", ".cache", "*.js"],
"include": ["./src/**/*", "./jest/**/*"]