feat: add blog comments via utterances

This commit is contained in:
Travis Fischer
2021-01-16 19:47:43 -05:00
parent 60d52e9350
commit bb67e6b940
5 changed files with 159 additions and 0 deletions

View File

@@ -25,6 +25,7 @@ import { Loading } from './Loading'
import { Page404 } from './Page404'
import { PageHead } from './PageHead'
import { Footer } from './Footer'
import { ReactUtterances } from './ReactUtterances'
import styles from './styles.module.css'
@@ -87,6 +88,20 @@ export const NotionPage: React.FC<types.PageProps> = ({
const canonicalPageUrl =
!isDev && getCanonicalPageUrl(site, recordMap)(pageId)
let comments: React.ReactNode = null
if (block.type === 'page' && block.parent_table === 'collection') {
comments = (
<ReactUtterances
repo='transitive-bullshit/transitivebullsh.it'
issueMap='issue-term'
issueTerm='title'
label='blog'
theme='preferred-color-scheme'
/>
)
}
return (
<IconContext.Provider value={{ style: { verticalAlign: 'middle' } }}>
<PageHead site={site} />
@@ -144,6 +159,7 @@ export const NotionPage: React.FC<types.PageProps> = ({
mapPageUrl={siteMapPageUrl}
mapImageUrl={mapNotionImageUrl}
searchNotion={searchNotion}
pageFooter={comments}
footer={<Footer />}
/>

View File

@@ -0,0 +1,96 @@
import React from 'react'
import styles from './styles.module.css'
export type MappingType =
| 'pathname'
| 'url'
| 'title'
| 'og:title'
| 'issue-number'
| 'issue-term'
export type Theme =
| 'github-light'
| 'github-dark'
| 'preferred-color-scheme'
| 'github-dark-orange'
| 'icy-dark'
| 'dark-blue'
| 'photon-dark'
interface ReactUtterancesProps {
repo: string
issueMap: MappingType
issueTerm?: string
issueNumber?: number
label?: string
theme: Theme
}
interface ReactUtterancesState {
pending: boolean
}
export class ReactUtterances extends React.Component<
ReactUtterancesProps,
ReactUtterancesState
> {
reference: React.RefObject<HTMLDivElement>
constructor(props: ReactUtterancesProps) {
super(props)
if (props.issueMap === 'issue-term' && props.issueTerm === undefined) {
throw Error(
"Property 'issueTerm' must be provided with issueMap 'issue-term'"
)
}
if (props.issueMap === 'issue-number' && props.issueNumber === undefined) {
throw Error(
"Property 'issueNumber' must be provided with issueMap 'issue-number'"
)
}
this.reference = React.createRef<HTMLDivElement>()
this.state = { pending: true }
}
componentDidMount(): void {
const { repo, issueMap, issueTerm, issueNumber, label, theme } = this.props
const scriptElement = document.createElement('script')
scriptElement.src = 'https://utteranc.es/client.js'
scriptElement.async = true
scriptElement.defer = true
scriptElement.setAttribute('repo', repo)
scriptElement.setAttribute('crossorigin', 'annonymous')
scriptElement.setAttribute('theme', theme)
scriptElement.onload = () => this.setState({ pending: false })
if (label) {
scriptElement.setAttribute('label', label)
}
if (issueMap === 'issue-number') {
scriptElement.setAttribute('issue-number', issueNumber!.toString())
} else if (issueMap === 'issue-term') {
scriptElement.setAttribute('issue-term', issueTerm!)
} else {
scriptElement.setAttribute('issue-term', issueMap)
}
// TODO: Check current availability
this.reference.current!.appendChild(scriptElement)
}
render(): React.ReactElement {
return (
<div className={styles.comments}>
<div className={styles.utterances} ref={this.reference}>
{this.state.pending && <p>Loading Comments...</p>}
</div>
</div>
)
}
}

View File

@@ -86,3 +86,22 @@
.linkedin:hover {
color: #0077b5;
}
.comments {
width: 100%;
margin-top: 2em;
border-top: 1px solid var(--fg-color-0);
}
.utterances {
margin-top: 2em;
width: 100%;
}
@media only screen and (min-width: 567px) {
.utterances {
width: calc(100% + 60px);
position: relative;
left: -60px;
}
}