升级react-notion-x,封装NotionPage

This commit is contained in:
tangly1024
2022-04-06 14:26:44 +08:00
parent 6de1102bfb
commit fdb1dcb622
14 changed files with 276 additions and 589 deletions

View File

@@ -1,19 +1,16 @@
import { getPageTableOfContents } from 'notion-utils'
import 'prismjs'
import 'prismjs/components/prism-bash'
import 'prismjs/components/prism-java'
import 'prismjs/components/prism-javascript'
import 'prismjs/components/prism-markup'
import 'prismjs/components/prism-python'
import 'prismjs/components/prism-typescript'
import { useRef } from 'react'
import ArticleDetail from './components/ArticleDetail'
import { ArticleLock } from './components/ArticleLock'
import HeaderArticle from './components/HeaderArticle'
import JumpToCommentButton from './components/JumpToCommentButton'
import TocDrawer from './components/TocDrawer'
import TocDrawerButton from './components/TocDrawerButton'
import LayoutBase from './LayoutBase'
import Comment from '@/components/Comment'
import NotionPage from '@/components/NotionPage'
import ArticleAdjacent from './components/ArticleAdjacent'
import ArticleCopyright from './components/ArticleCopyright'
import ArticleRecommend from './components/ArticleRecommend'
export const LayoutSlug = props => {
const { post, lock, validPassword } = props
@@ -27,27 +24,58 @@ export const LayoutSlug = props => {
const targetRef = typeof window !== 'undefined' ? document.getElementById('container') : null
const floatSlot = <>
{post?.toc?.length > 1 && <div className="block lg:hidden">
<TocDrawerButton
onClick={() => {
drawerRight?.current?.handleSwitchVisible()
}}
/>
</div>}
<JumpToCommentButton/>
</>
{post?.toc?.length > 1 && <div className="block lg:hidden">
<TocDrawerButton
onClick={() => {
drawerRight?.current?.handleSwitchVisible()
}}
/>
</div>}
<JumpToCommentButton />
</>
return (
<LayoutBase
headerSlot={<HeaderArticle {...props}/>}
headerSlot={<HeaderArticle {...props} />}
{...props}
showCategory={false}
showTag={false}
floatSlot={floatSlot}
>
<div className="w-full lg:shadow-sm lg:hover:shadow lg:border lg:rounded-xl lg:px-2 lg:py-4 bg-white dark:bg-hexo-black-gray dark:border-black">
{!lock && <ArticleDetail {...props} />}
{lock && <ArticleLock password={post.password} validPassword={validPassword} />}
{!lock && <div id="container" className="max-w-5xl overflow-x-auto flex-grow mx-auto md:w-full md:px-5 ">
<article itemScope itemType="https://schema.org/Movie" className="subpixel-antialiased" >
{/* Notion文章主体 */}
<section id='notion-article' className='px-5'>
{post.blockMap && <NotionPage post={post} />}
</section>
<section className="px-1 py-2 my-1 text-sm font-light overflow-auto text-gray-600 dark:text-gray-400">
{/* 文章内嵌广告 */}
<ins className="adsbygoogle"
style={{ display: 'block', textAlign: 'center' }}
data-adtest="on"
data-ad-layout="in-article"
data-ad-format="fluid"
data-ad-client="ca-pub-2708419466378217"
data-ad-slot="3806269138" />
</section>
<ArticleCopyright {...props} />
<ArticleRecommend {...props} />
<ArticleAdjacent {...props} />
</article>
<hr className='border-dashed' />
{/* 评论互动 */}
<div className="duration-200 overflow-x-auto bg-white dark:bg-hexo-black-gray px-3">
<Comment frontMatter={post} />
</div>
</div>}
</div>
<div className='block lg:hidden'>

View File

@@ -1,105 +0,0 @@
import Comment from '@/components/Comment'
import mediumZoom from 'medium-zoom'
import 'prismjs'
import 'prismjs/components/prism-bash'
import 'prismjs/components/prism-javascript'
import 'prismjs/components/prism-markup'
import 'prismjs/components/prism-python'
import 'prismjs/components/prism-typescript'
import { useEffect, useRef } from 'react'
import { Code, Collection, CollectionRow, Equation, NotionRenderer } from 'react-notion-x'
import ArticleAdjacent from './ArticleAdjacent'
import ArticleCopyright from './ArticleCopyright'
import ArticleRecommend from './ArticleRecommend'
/**
*
* @param {*} param0
* @returns
*/
export default function ArticleDetail (props) {
const { post } = props
const zoom = typeof window !== 'undefined' && mediumZoom({
container: '.notion-viewport',
background: 'rgba(0, 0, 0, 0.2)',
margin: getMediumZoomMargin()
})
const zoomRef = useRef(zoom ? zoom.clone() : null)
useEffect(() => {
// 将所有container下的所有图片添加medium-zoom
const container = document?.getElementById('container')
const imgList = container?.getElementsByTagName('img')
if (imgList && zoomRef.current) {
for (let i = 0; i < imgList.length; i++) {
(zoomRef.current).attach(imgList[i])
}
}
})
return (<div id="container" className="max-w-5xl overflow-x-auto flex-grow mx-auto md:w-full md:px-5 ">
<article itemScope itemType="https://schema.org/Movie" className="subpixel-antialiased" >
{/* Notion文章主体 */}
<section id='notion-article' className='px-5'>
{post.blockMap && (
<NotionRenderer
recordMap={post.blockMap}
mapPageUrl={mapPageUrl}
components={{
equation: Equation,
code: Code,
collectionRow: CollectionRow,
collection: Collection
}}
/>
)}
</section>
<section className="px-1 py-2 my-1 text-sm font-light overflow-auto text-gray-600 dark:text-gray-400">
{/* 文章内嵌广告 */}
<ins className="adsbygoogle"
style={{ display: 'block', textAlign: 'center' }}
data-adtest="on"
data-ad-layout="in-article"
data-ad-format="fluid"
data-ad-client="ca-pub-2708419466378217"
data-ad-slot="3806269138"/>
</section>
<ArticleCopyright {...props}/>
<ArticleRecommend {...props}/>
<ArticleAdjacent {...props}/>
</article>
<hr className='border-dashed'/>
{/* 评论互动 */}
<div className="duration-200 overflow-x-auto bg-white dark:bg-hexo-black-gray px-3">
<Comment frontMatter={post} />
</div>
</div>)
}
const mapPageUrl = id => {
return 'https://www.notion.so/' + id.replace(/-/g, '')
}
function getMediumZoomMargin () {
const width = window.innerWidth
if (width < 500) {
return 8
} else if (width < 800) {
return 20
} else if (width < 1280) {
return 30
} else if (width < 1600) {
return 40
} else if (width < 1920) {
return 48
} else {
return 72
}
}

View File

@@ -1,15 +1,9 @@
import BLOG from '@/blog.config'
import Link from 'next/link'
import React from 'react'
import {
Code,
Collection,
CollectionRow,
Equation,
NotionRenderer
} from 'react-notion-x'
import TagItemMini from './TagItemMini'
import CONFIG_HEXO from '../config_hexo'
import NotionPage from '@/components/NotionPage'
const BlogPostCard = ({ post, showSummary }) => {
const showPreview = CONFIG_HEXO.POST_LIST_PREVIEW && post.blockMap
@@ -22,18 +16,16 @@ const BlogPostCard = ({ post, showSummary }) => {
<div className="lg:p-8 p-4 flex flex-col w-full">
<Link href={`${BLOG.SUB_PATH}/article/${post.slug}`} passHref>
<a
className={`replace cursor-pointer hover:underline text-2xl font-sans ${
showPreview ? 'text-center' : ''
} leading-tight text-gray-700 dark:text-gray-100 hover:text-indigo-700 dark:hover:text-indigo-400`}
className={`replace cursor-pointer hover:underline text-2xl font-sans ${showPreview ? 'text-center' : ''
} leading-tight text-gray-700 dark:text-gray-100 hover:text-indigo-700 dark:hover:text-indigo-400`}
>
{post.title}
</a>
</Link>
<div
className={`flex mt-2 items-center ${
showPreview ? 'justify-center' : 'justify-start'
} flex-wrap dark:text-gray-500 text-gray-400 hover:text-indigo-700 dark:hover:text-indigo-400`}
className={`flex mt-2 items-center ${showPreview ? 'justify-center' : 'justify-start'
} flex-wrap dark:text-gray-500 text-gray-400 hover:text-indigo-700 dark:hover:text-indigo-400`}
>
<Link
href={`/archive#${post?.date?.start_date?.substr(0, 7)}`}
@@ -54,17 +46,7 @@ const BlogPostCard = ({ post, showSummary }) => {
{showPreview && (
<div className="overflow-ellipsis truncate">
<NotionRenderer
bodyClassName="max-h-full"
recordMap={post.blockMap}
mapPageUrl={mapPageUrl}
components={{
equation: Equation,
code: Code,
collectionRow: CollectionRow,
collection: Collection
}}
/>
<NotionPage post={post} />
</div>
)}
@@ -104,8 +86,4 @@ const BlogPostCard = ({ post, showSummary }) => {
)
}
const mapPageUrl = id => {
return 'https://www.notion.so/' + id.replace(/-/g, '')
}
export default BlogPostCard