import { siteConfig } from '@/lib/config' import { compressImage, mapImgUrl } from '@/lib/notion/mapImage' import { isBrowser, loadExternalResource } from '@/lib/utils' import mediumZoom from '@fisch0920/medium-zoom' import 'katex/dist/katex.min.css' import dynamic from 'next/dynamic' import { useEffect, useRef } from 'react' import { NotionRenderer } from 'react-notion-x' /** * 整个站点的核心组件 * 将Notion数据渲染成网页 * @param {*} param0 * @returns */ const NotionPage = ({ post, className }) => { // 是否关闭数据库和画册的点击跳转 const POST_DISABLE_GALLERY_CLICK = siteConfig('POST_DISABLE_GALLERY_CLICK') const POST_DISABLE_DATABASE_CLICK = siteConfig('POST_DISABLE_DATABASE_CLICK') const SPOILER_TEXT_TAG = siteConfig('SPOILER_TEXT_TAG') const zoom = isBrowser && mediumZoom({ // container: '.notion-viewport', background: 'rgba(0, 0, 0, 0.2)', margin: getMediumZoomMargin() }) const zoomRef = useRef(zoom ? zoom.clone() : null) const IMAGE_ZOOM_IN_WIDTH = siteConfig('IMAGE_ZOOM_IN_WIDTH', 1200) // 页面首次打开时执行的勾子 useEffect(() => { // 检测当前的url并自动滚动到对应目标 autoScrollToHash() }, []) // 页面文章发生变化时会执行的勾子 useEffect(() => { // 相册视图点击禁止跳转,只能放大查看图片 if (POST_DISABLE_GALLERY_CLICK) { // 针对页面中的gallery视图,点击后是放大图片还是跳转到gallery的内部页面 processGalleryImg(zoomRef?.current) } // 页内数据库点击禁止跳转,只能查看 if (POST_DISABLE_DATABASE_CLICK) { processDisableDatabaseUrl() } /** * 放大查看图片时替换成高清图像 */ const observer = new MutationObserver((mutationsList, observer) => { mutationsList.forEach(mutation => { if ( mutation.type === 'attributes' && mutation.attributeName === 'class' ) { if (mutation.target.classList.contains('medium-zoom-image--opened')) { // 等待动画完成后替换为更高清的图像 setTimeout(() => { // 获取该元素的 src 属性 const src = mutation?.target?.getAttribute('src') // 替换为更高清的图像 mutation?.target?.setAttribute( 'src', compressImage(src, IMAGE_ZOOM_IN_WIDTH) ) }, 800) } } }) }) // 监视页面元素和属性变化 observer.observe(document.body, { attributes: true, subtree: true, attributeFilter: ['class'] }) return () => { observer.disconnect() } }, [post]) useEffect(() => { // Spoiler文本功能 if (SPOILER_TEXT_TAG) { import('lodash/escapeRegExp').then(escapeRegExp => { Promise.all([ loadExternalResource('/js/spoilerText.js', 'js'), loadExternalResource('/css/spoiler-text.css', 'css') ]).then(() => { window.textToSpoiler && window.textToSpoiler(escapeRegExp.default(SPOILER_TEXT_TAG)) }) }) } // 查找所有具有 'notion-collection-page-properties' 类的元素,删除notion自带的页面properties const timer = setTimeout(() => { // 查找所有具有 'notion-collection-page-properties' 类的元素 const elements = document.querySelectorAll( '.notion-collection-page-properties' ) // 遍历这些元素并将其从 DOM 中移除 elements?.forEach(element => { element?.remove() }) }, 1000) // 1000 毫秒 = 1 秒 // 清理定时器,防止组件卸载时执行 return () => clearTimeout(timer) }, [post]) return (