feat: lots of refactors and improvements

This commit is contained in:
Travis Fischer
2022-03-23 04:05:22 -04:00
parent c0904c8811
commit 5417bb9bbc
27 changed files with 830 additions and 3062 deletions

View File

@@ -26,7 +26,7 @@ export const Footer: React.FC<{
return (
<footer className={styles.footer}>
<div className={styles.copyright}>Copyright 2021 {config.author}</div>
<div className={styles.copyright}>Copyright 2022 {config.author}</div>
{hasMounted ? (
<div className={styles.settings}>

View File

@@ -1,4 +1,5 @@
import * as React from 'react'
import Image from 'next/image'
import Head from 'next/head'
import Link from 'next/link'
import dynamic from 'next/dynamic'
@@ -33,10 +34,13 @@ import { PageActions } from './PageActions'
import { Footer } from './Footer'
import { PageSocial } from './PageSocial'
import { GitHubShareButton } from './GitHubShareButton'
import { ReactUtterances } from './ReactUtterances'
import styles from './styles.module.css'
// -----------------------------------------------------------------------------
// dynamic imports for optional components
// -----------------------------------------------------------------------------
// const Code = dynamic(() =>
// import('react-notion-x').then((notion) => notion.Code)
// )
@@ -51,21 +55,15 @@ import styles from './styles.module.css'
// ssr: false
// }
// )
// TODO: PDF support via "react-pdf" package has numerous troubles building
// with next.js
//
// const Pdf = dynamic(
// () => import('react-notion-x').then((notion) => notion.Pdf),
// () => import('react-notion-x').then((notion) => (notion as any).Pdf),
// { ssr: false }
// )
const Equation = dynamic(() =>
import('react-notion-x').then((notion) => notion.Equation)
)
// we're now using a much lighter-weight tweet renderer react-static-tweets
// instead of the official iframe-based embed widget from twitter
// const Tweet = dynamic(() => import('react-tweet-embed'))
//
// const Equation = dynamic(() =>
// import('react-notion-x').then((notion) => notion.Equation)
// )
const Modal = dynamic(
() => import('react-notion-x').then((notion) => notion.Modal),
@@ -139,22 +137,10 @@ export const NotionPage: React.FC<types.PageProps> = ({
const socialDescription =
getPageDescription(block, recordMap) ?? config.description
let comments: React.ReactNode = null
let pageAside: React.ReactChild = null
// only display comments and page actions on blog post pages
if (isBlogPost) {
if (config.utterancesGitHubRepo) {
comments = (
<ReactUtterances
repo={config.utterancesGitHubRepo}
issueMap='issue-term'
issueTerm='title'
theme={darkMode.value ? 'photon-dark' : 'github-light'}
/>
)
}
const tweet = getPageTweet(block, recordMap)
if (tweet) {
pageAside = <PageActions tweet={tweet} />
@@ -249,15 +235,43 @@ export const NotionPage: React.FC<types.PageProps> = ({
<a {...props} />
</Link>
),
image: ({
src,
alt,
width,
height,
className,
style,
...rest
}) => {
const layout = width && height ? 'intrinsic' : 'fill'
return (
<Image
{...rest}
className={className}
src={src}
alt={alt}
width={layout === 'intrinsic' && width}
height={layout === 'intrinsic' && height}
objectFit={style?.objectFit}
objectPosition={style?.objectPosition}
layout={layout}
/>
)
},
code: Code,
collection: Collection,
collectionRow: CollectionRow,
tweet: Tweet,
modal: Modal,
equation: Equation
modal: Modal
}}
recordMap={recordMap}
rootPageId={site.rootNotionPageId}
rootDomain={site.domain}
fullPage={!isLiteMode}
darkMode={darkMode.value}
previewImages={site.previewImages !== false}
@@ -270,7 +284,6 @@ export const NotionPage: React.FC<types.PageProps> = ({
mapPageUrl={siteMapPageUrl}
mapImageUrl={mapNotionImageUrl}
searchNotion={searchNotion}
pageFooter={comments}
pageAside={pageAside}
footer={
<Footer

View File

@@ -28,7 +28,8 @@ export const Page404: React.FC<types.PageProps> = ({ site, pageId, error }) => {
) : (
pageId && (
<p>
Make sure that Notion page "{pageId}" is publicly accessible.
Make sure that Notion page &quot;{pageId}&quot; is publicly
accessible.
</p>
)
)}

View File

@@ -1,110 +0,0 @@
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>
scriptElement: any
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 }
}
UNSAFE_componentWillReceiveProps(props) {
// this.scriptElement.setAttribute('theme', props.theme)
const iframe = document.querySelector('iframe.utterances-frame') as any
if (iframe) {
iframe.contentWindow.postMessage(
{ type: 'set-theme', theme: props.theme },
'https://utteranc.es/'
)
}
}
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.scriptElement = scriptElement
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

@@ -107,19 +107,6 @@
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;
}
}
@media only screen and (max-width: 566px) {
.footer {
flex-direction: column;