mirror of
https://github.com/d0zingcat/nextjs-notion-starter-kit.git
synced 2026-05-13 15:09:47 +00:00
feat: lots of refactors and improvements
This commit is contained in:
@@ -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}>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 "{pageId}" is publicly
|
||||
accessible.
|
||||
</p>
|
||||
)
|
||||
)}
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user