diff --git a/blog.config.js b/blog.config.js index 2d4fd3f2..3a160835 100644 --- a/blog.config.js +++ b/blog.config.js @@ -9,8 +9,10 @@ const BLOG = { process.env.NOTION_PAGE_ID || '02ab3b8678004aa69e9e415905ef32a5', // Important page_id!!!Duplicate Template from https://www.notion.so/tanghh/02ab3b8678004aa69e9e415905ef32a5 NOTION_ACCESS_TOKEN: process.env.NOTION_ACCESS_TOKEN || '', // Useful if you prefer not to make your database public DEBUG: process.env.NEXT_PUBLIC_DEBUG || false, // 是否显示调试按钮 + FACEBOOK_PAGE_ID: process.env.NEXT_PUBLIC_FACEBOOK_PAGE_ID || '', //Facebook Page ID 來啟用 messenger 聊天功能 FACEBOOK_APP_ID: process.env.NEXT_PUBLIC_FACEBOOK_APP_ID || '', //Facebook App ID 來啟用 messenger 聊天功能 + FACEBOOK_PAGE: process.env.NEXT_PUBLIC_FACEBOOK_PAGE || 'https://www.facebook.com/tw.andys.pro', // Facebook Page 的連結 THEME: process.env.NEXT_PUBLIC_THEME || 'next', // 主题, 支持 ['next','hexo',"fukasawa','medium'] THEME_SWITCH: process.env.NEXT_PUBLIC_THEME_SWITCH || false, // 是否显示切换主题按钮 diff --git a/components/CommonHead.js b/components/CommonHead.js index aad15497..7f129995 100644 --- a/components/CommonHead.js +++ b/components/CommonHead.js @@ -12,6 +12,8 @@ const CommonHead = ({ meta, children }) => { const description = meta?.description || BLOG.DESCRIPTION const type = meta?.type || 'website' const keywords = meta?.tags || BLOG.KEYWORDS + const lang = BLOG.LANG.replace('-', '_') // Facebook OpenGraph 要 zh_CN 這樣的格式才抓得到語言 + const category = meta?.category || BLOG.KEYWORDS || '軟體科技' // section 主要是像是 category 這樣的分類,Facebook 用這個來抓連結的分類 return ( @@ -31,11 +33,12 @@ const CommonHead = ({ meta, children }) => { )} - + + @@ -50,6 +53,8 @@ const CommonHead = ({ meta, children }) => { content={meta.date || meta.createdTime} /> + + )} {children} diff --git a/components/NotionPage.js b/components/NotionPage.js new file mode 100644 index 00000000..c2fe6c3c --- /dev/null +++ b/components/NotionPage.js @@ -0,0 +1,91 @@ + +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 'prismjs/components/prism-java' + +import { NotionRenderer } from 'react-notion-x' +import mediumZoom from 'medium-zoom' +import { useEffect, useRef } from 'react' +import dynamic from 'next/dynamic' + +const Code = dynamic(() => + import('react-notion-x/build/third-party/code').then((m) => m.Code) +) +const Collection = dynamic(() => + import('react-notion-x/build/third-party/collection').then( + (m) => m.Collection + ) +) +const Equation = dynamic(() => + import('react-notion-x/build/third-party/equation').then((m) => m.Equation) +) +const Pdf = dynamic( + () => import('react-notion-x/build/third-party/pdf').then((m) => m.Pdf), + { + ssr: false + } +) +const Modal = dynamic( + () => import('react-notion-x/build/third-party/modal').then((m) => m.Modal), + { + ssr: false + } +) +const NotionPage = ({ post }) => { + 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 +} + +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 + } +} + +export default NotionPage diff --git a/lib/lang/en-US.js b/lib/lang/en-US.js index 00414875..9f8fc94a 100644 --- a/lib/lang/en-US.js +++ b/lib/lang/en-US.js @@ -32,7 +32,9 @@ export default { ARTICLE_DETAIL: 'Article Details', PASSWORD_ERROR: 'Password Error!', ARTICLE_LOCK_TIPS: 'Please Enter the password:', - SUBMIT: 'Submit' + SUBMIT: 'Submit', + POST_TIME: 'Post on', + LAST_EDITED_TIME: 'Last edited' }, PAGINATION: { PREV: 'Prev', diff --git a/lib/lang/zh-CN.js b/lib/lang/zh-CN.js index 4417a270..435aeb96 100644 --- a/lib/lang/zh-CN.js +++ b/lib/lang/zh-CN.js @@ -34,7 +34,9 @@ export default { ARTICLE_DETAIL: '文章详情', PASSWORD_ERROR: '密码错误!', ARTICLE_LOCK_TIPS: '文章已上锁,请输入访问密码', - SUBMIT: '提交' + SUBMIT: '提交', + POST_TIME: '发布于', + LAST_EDITED_TIME: '最后更新' }, PAGINATION: { PREV: '上一页', diff --git a/lib/lang/zh-TW.js b/lib/lang/zh-TW.js index a7f648f4..673fe109 100644 --- a/lib/lang/zh-TW.js +++ b/lib/lang/zh-TW.js @@ -34,7 +34,9 @@ export default { ARTICLE_DETAIL: '完整文章', PASSWORD_ERROR: '密碼錯誤!', ARTICLE_LOCK_TIPS: '文章已上鎖,請輸入訪問密碼', - SUBMIT: '提交' + SUBMIT: '提交', + POST_TIME: '发布于', + LAST_EDITED_TIME: '最后更新' }, PAGINATION: { PREV: '上一頁', diff --git a/lib/notion/getAllPosts.js b/lib/notion/getAllPosts.js index cfbbafa8..fbe588da 100644 --- a/lib/notion/getAllPosts.js +++ b/lib/notion/getAllPosts.js @@ -2,6 +2,7 @@ import BLOG from '@/blog.config' import getAllPageIds from './getAllPageIds' import getPageProperties from './getPageProperties' import { defaultMapImageUrl } from 'react-notion-x' +import formatDate from '@/lib/formatDate' import { getNotionPageData } from '@/lib/notion/getNotionData' import { delCacheData } from '@/lib/cache/cache_manager' @@ -12,7 +13,7 @@ import { delCacheData } from '@/lib/cache/cache_manager' * @param pageType 页面类型数组 ['Post','Page'] * @returns {Promise<*[]>} */ -export async function getAllPosts ({ notionPageData, from, pageType }) { +export async function getAllPosts({ notionPageData, from, pageType }) { if (!notionPageData) { notionPageData = await getNotionPageData({ from }) } @@ -31,8 +32,8 @@ export async function getAllPosts ({ notionPageData, from, pageType }) { const id = pageIds[i] const properties = (await getPageProperties(id, pageBlock, schema)) || null properties.slug = properties.slug ?? properties.id - properties.createdTime = new Date(pageBlock[id].value?.created_time).toString() // FIXME 似乎没有created_time 字段了 - properties.lastEditedTime = new Date(pageBlock[id].value?.last_edited_time).toString() // FIXME 似乎没有created_time 字段了 + properties.createdTime = formatDate(new Date(pageBlock[id].value?.created_time).toString(), BLOG.LANG) + properties.lastEditedTime = formatDate(new Date(pageBlock[id].value?.last_edited_time).toString(), BLOG.LANG) properties.fullWidth = pageBlock[id].value?.format?.page_full_width ?? false properties.page_cover = getPostCover(id, pageBlock) ?? null properties.content = pageBlock[id].value?.content ?? [] @@ -65,7 +66,7 @@ export async function getAllPosts ({ notionPageData, from, pageType }) { } // 从Block获取封面图;优先取PageCover,否则取内容图片 -function getPostCover (id, block) { +function getPostCover(id, block) { const pageCover = block[id].value?.format?.page_cover if (pageCover) { if (pageCover.startsWith('/')) return 'https://www.notion.so' + pageCover @@ -78,7 +79,7 @@ function getPostCover (id, block) { * @param {*} param0 * @returns */ -export async function getAllPostCount ({ notionPageData, from }) { +export async function getAllPostCount({ notionPageData, from }) { if (!notionPageData) { notionPageData = await getNotionPageData({ from }) } diff --git a/lib/notion/getPageProperties.js b/lib/notion/getPageProperties.js index 56ded539..3dcc7735 100644 --- a/lib/notion/getPageProperties.js +++ b/lib/notion/getPageProperties.js @@ -1,7 +1,7 @@ import { getTextContent, getDateValue } from 'notion-utils' import { NotionAPI } from 'notion-client' -async function getPageProperties (id, block, schema, authToken) { +async function getPageProperties(id, block, schema, authToken) { const rawProperties = Object.entries(block?.[id]?.value?.properties || []) const excludeProperties = ['date', 'select', 'multi_select', 'person'] const properties = {} diff --git a/lib/notion/getPostBlocks.js b/lib/notion/getPostBlocks.js index 0db5a582..52cbdf32 100644 --- a/lib/notion/getPostBlocks.js +++ b/lib/notion/getPostBlocks.js @@ -2,7 +2,7 @@ import BLOG from '@/blog.config' import { NotionAPI } from 'notion-client' import { getDataFromCache, setDataToCache } from '@/lib/cache/cache_manager' -export async function getPostBlocks (id, from, slice, retryCount = 3) { +export async function getPostBlocks(id, from, slice, retryCount = 3) { const cacheKey = 'page_block_' + id let pageBlock = await getDataFromCache(cacheKey) if (pageBlock) { @@ -32,13 +32,13 @@ export async function getPostBlocks (id, from, slice, retryCount = 3) { } /** - * + * 获取到的blockMap删除不需要的字段 * @param {*} id 页面ID * @param {*} pageBlock 页面元素 * @param {*} slice 截取数量 * @returns */ -function filterPostBlocks (id, pageBlock, slice) { +function filterPostBlocks(id, pageBlock, slice) { const clonePageBlock = deepClone(pageBlock) let count = 0 @@ -51,8 +51,6 @@ function filterPostBlocks (id, pageBlock, slice) { count++ delete b?.role delete b?.value?.version - delete b?.value?.created_time - delete b?.value?.last_edited_time delete b?.value?.created_by_table delete b?.value?.created_by_id delete b?.value?.last_edited_by_table @@ -67,7 +65,7 @@ function filterPostBlocks (id, pageBlock, slice) { return clonePageBlock } -function deepClone (obj) { +function deepClone(obj) { const newObj = Array.isArray(obj) ? [] : {} if (obj && typeof obj === 'object') { for (const key in obj) { diff --git a/lib/rss.js b/lib/rss.js index a2afe0d6..3d75d888 100644 --- a/lib/rss.js +++ b/lib/rss.js @@ -1,16 +1,8 @@ import { Feed } from 'feed' import BLOG from '@/blog.config' import ReactDOMServer from 'react-dom/server' -import { - NotionRenderer, - Equation, - Code, - Collection, - CollectionRow -} from 'react-notion-x' import { getPostBlocks } from './notion' - -const mapPageUrl = id => 'https://www.notion.so/' + id.replace(/-/g, '') +import NotionPage from '@/components/NotionPage' const createFeedContent = async post => { // 加密的文章内容只返回摘要 @@ -19,18 +11,7 @@ const createFeedContent = async post => { } const blockMap = await getPostBlocks(post.id, 'rss-content') if (blockMap) { - const content = ReactDOMServer.renderToString( - - ) + const content = ReactDOMServer.renderToString() const regexExp = /
.*?<\/svg>
.*?<\/div><\/div>
.*?<\/div><\/div><\/div><\/div>/g return content.replace(regexExp, '') diff --git a/package.json b/package.json index 5ac9819b..71e3aefb 100644 --- a/package.json +++ b/package.json @@ -32,15 +32,15 @@ "lodash.throttle": "^4.1.1", "memory-cache": "^0.2.0", "next": "^12.0.5", - "notion-client": "4.16.0", - "notion-utils": "4.16.0", + "notion-client": "6.5.0", + "notion-utils": "6.5.0", "preact": "^10.5.15", "qrcode.react": "^1.0.1", "react": "17.0.2", "react-cookies": "^0.1.1", "react-cusdis": "^2.1.3", "react-dom": "17.0.2", - "react-notion-x": "4.16.0", + "react-notion-x": "6.6.2", "smoothscroll-polyfill": "^0.4.4", "typed.js": "^2.0.12", "use-ackee": "^3.0.0" diff --git a/pages/_app.js b/pages/_app.js index d7078c98..d9ae363f 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -7,11 +7,12 @@ import 'react-notion-x/src/styles.css' import '@/styles/notion.css' // 重写部分样式 // used for collection views (optional) -import 'rc-dropdown/assets/index.css' +// import 'rc-dropdown/assets/index.css' // used for code syntax highlighting (optional) import 'prismjs/themes/prism-okaidia.css' // used for rendering equations (optional) -import 'katex/dist/katex.min.css' +import 'react-notion-x/build/third-party/equation.css' + import dynamic from 'next/dynamic' import { GlobalContextProvider } from '@/lib/global' import { DebugPanel } from '@/components/DebugPanel' diff --git a/pages/article/[slug].js b/pages/article/[slug].js index 9abf4b83..aba79897 100644 --- a/pages/article/[slug].js +++ b/pages/article/[slug].js @@ -63,6 +63,7 @@ const Slug = props => { type: 'article', slug: 'article/' + props.post.slug, image: props.post.page_cover, + category: props.post.category?.[0], tags: props.post.tags } diff --git a/themes/example/LayoutSlug.js b/themes/example/LayoutSlug.js index fc7f81e1..70482b5d 100644 --- a/themes/example/LayoutSlug.js +++ b/themes/example/LayoutSlug.js @@ -1,25 +1,10 @@ import { getPageTableOfContents } from 'notion-utils' -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 { - Code, - Collection, - CollectionRow, - Equation, - NotionRenderer -} from 'react-notion-x' import LayoutBase from './LayoutBase' -import { useRef, useEffect } from 'react' import { ArticleLock } from './components/ArticleLock' -import mediumZoom from 'medium-zoom' - -const mapPageUrl = id => { - return 'https://www.notion.so/' + id.replace(/-/g, '') -} +import NotionPage from '@/components/NotionPage' +import Link from 'next/link' +import { useGlobal } from '@/lib/global' +import formatDate from '@/lib/formatDate' export const LayoutSlug = props => { const { post, lock, validPassword } = props @@ -28,24 +13,9 @@ export const LayoutSlug = props => { post.toc = getPageTableOfContents(post, post.blockMap) } - 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('notion-article') - const imgList = container?.getElementsByTagName('img') - if (imgList && zoomRef.current) { - for (let i = 0; i < imgList.length; i++) { - zoomRef.current.attach(imgList[i]) - } - } - }) + const { locale } = useGlobal() + const date = formatDate(post?.date?.start_date || post.createdTime, locale.LOCALE) + return (
@@ -54,39 +24,46 @@ export const LayoutSlug = props => { {lock && } {!lock &&
- {post.blockMap && ( - - )} -
} +
+
+ + + + {post.category} + + + | + + {post.type[0] !== 'Page' && (<> + + + {date} + + + | + + {locale.COMMON.LAST_EDITED_TIME}: {post.lastEditedTime} + + | + + )} + + + +   + + +
+ +
+ + {post.blockMap && } + }
) } - -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 - } -} diff --git a/themes/fukasawa/components/ArticleDetail.js b/themes/fukasawa/components/ArticleDetail.js index 0e2b7187..cbdfa0b7 100644 --- a/themes/fukasawa/components/ArticleDetail.js +++ b/themes/fukasawa/components/ArticleDetail.js @@ -1,16 +1,8 @@ import Comment from '@/components/Comment' +import NotionPage from '@/components/NotionPage' import formatDate from '@/lib/formatDate' import { useGlobal } from '@/lib/global' -import mediumZoom from 'medium-zoom' import Link from 'next/link' -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 ArticleAround from './ArticleAround' /** @@ -18,34 +10,15 @@ import ArticleAround from './ArticleAround' * @param {*} param0 * @returns */ -export default function ArticleDetail ({ post, recommendPosts, prev, next }) { +export default function ArticleDetail({ post, recommendPosts, prev, next }) { const { locale } = useGlobal() const date = formatDate(post?.date?.start_date || post.createdTime, locale.LOCALE) - - 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 (
{post.type && !post.type.includes('Page') && post?.page_cover && ( -
+
{/* eslint-disable-next-line @next/next/no-img-element */} - {post.title} -
+ {post.title} +
)}
- {/* 文章Title */} -
- {post.title} -
+ {/* 文章Title */} +
+ {post.title} +
-
-
- - - - {post.category} +
+
+ + + + {post.category} + + + | + + {post.type[0] !== 'Page' && (<> + + + {date} | + + {locale.COMMON.LAST_EDITED_TIME}: {post.lastEditedTime} + + )} - {post.type[0] !== 'Page' && (<> - - - {date} - - - | - )} - -
- -   - - | -
+
+ +   +
+
-
+
{/* Notion文章主体 */}
- {post.blockMap && ( - - )} + {post.blockMap && }
@@ -116,38 +80,16 @@ export default function ArticleDetail ({ post, recommendPosts, prev, next }) { data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-2708419466378217" - data-ad-slot="3806269138"/> + data-ad-slot="3806269138" />
- + {/* 评论互动 */}
- +
) } - -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 - } -} diff --git a/themes/hexo/LayoutSlug.js b/themes/hexo/LayoutSlug.js index 2b0a63f5..e2fec724 100644 --- a/themes/hexo/LayoutSlug.js +++ b/themes/hexo/LayoutSlug.js @@ -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 &&
- { - drawerRight?.current?.handleSwitchVisible() - }} - /> -
} - - + {post?.toc?.length > 1 &&
+ { + drawerRight?.current?.handleSwitchVisible() + }} + /> +
} + + return ( } + headerSlot={} {...props} showCategory={false} showTag={false} floatSlot={floatSlot} >
- {!lock && } {lock && } + + {!lock &&
+ +
+ {/* Notion文章主体 */} +
+ {post.blockMap && } +
+ +
+ {/* 文章内嵌广告 */} + +
+ + + + +
+ +
+ + {/* 评论互动 */} +
+ +
+
}
diff --git a/themes/hexo/components/ArticleDetail.js b/themes/hexo/components/ArticleDetail.js deleted file mode 100644 index 7913e6c6..00000000 --- a/themes/hexo/components/ArticleDetail.js +++ /dev/null @@ -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 (
-
- - {/* Notion文章主体 */} -
- {post.blockMap && ( - - )} -
- -
- {/* 文章内嵌广告 */} - -
- - - - - -
- -
- - {/* 评论互动 */} -
- -
-
) -} - -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 - } -} diff --git a/themes/hexo/components/BlogPostCard.js b/themes/hexo/components/BlogPostCard.js index cb4fa647..d1ba0023 100644 --- a/themes/hexo/components/BlogPostCard.js +++ b/themes/hexo/components/BlogPostCard.js @@ -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 }) => {
{post.title}
{ {showPreview && (
- +
)} @@ -104,8 +86,4 @@ const BlogPostCard = ({ post, showSummary }) => { ) } -const mapPageUrl = id => { - return 'https://www.notion.so/' + id.replace(/-/g, '') -} - export default BlogPostCard diff --git a/themes/hexo/components/HeaderArticle.js b/themes/hexo/components/HeaderArticle.js index 23ebdaf0..ce9b3484 100644 --- a/themes/hexo/components/HeaderArticle.js +++ b/themes/hexo/components/HeaderArticle.js @@ -3,7 +3,7 @@ import { useGlobal } from '@/lib/global' import formatDate from '@/lib/formatDate' import { useEffect } from 'react' -export default function HeaderArticle ({ post, siteInfo }) { +export default function HeaderArticle({ post, siteInfo }) { const headerImage = post?.page_cover ? `url("${post.page_cover}")` : `url("${siteInfo?.pageCover}")` const { isDarkMode } = useGlobal() @@ -47,52 +47,53 @@ export default function HeaderArticle ({ post, siteInfo }) { } return ( - + +
) } diff --git a/themes/hexo/components/JumpToCommentButton.js b/themes/hexo/components/JumpToCommentButton.js index cc96497c..85d93cf0 100644 --- a/themes/hexo/components/JumpToCommentButton.js +++ b/themes/hexo/components/JumpToCommentButton.js @@ -1,5 +1,6 @@ -import React from 'react' +import React, { useEffect } from 'react' import CONFIG_HEXO from '../config_hexo' +let wrapperTop = 0 /** * 跳转到评论区 @@ -10,16 +11,30 @@ const JumpToCommentButton = () => { if (!CONFIG_HEXO.WIDGET_TO_COMMENT) { return <> } - function navToComment () { - const commentElement = document.getElementById('comment') - if (commentElement) { - commentElement?.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' }) - } + + function updateHeaderHeight() { + setTimeout(() => { + if (window) { + const wrapperElement = document.getElementById('comment') + wrapperTop = wrapperElement?.offsetTop + } + }, 500) + } + function navToComment() { + window.scrollTo({ top: wrapperTop, behavior: 'smooth' }) + // 兼容性不好 + // const commentElement = document.getElementById('comment') + // if (commentElement) { + // commentElement?.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' }) } + useEffect(() => { + updateHeaderHeight() + }) + return (
- -
) + +
) } export default JumpToCommentButton diff --git a/themes/medium/LayoutSlug.js b/themes/medium/LayoutSlug.js index 073e5432..7433a8db 100644 --- a/themes/medium/LayoutSlug.js +++ b/themes/medium/LayoutSlug.js @@ -2,8 +2,7 @@ import { getPageTableOfContents } from 'notion-utils' import LayoutBase from './LayoutBase' import { useGlobal } from '@/lib/global' -import mediumZoom from 'medium-zoom' -import React, { useEffect, useRef } from 'react' +import React from 'react' import Catalog from './components/Catalog' import { ArticleDetail } from './components/ArticleDetail' import { ArticleLock } from './components/ArticleLock' @@ -17,26 +16,6 @@ export const LayoutSlug = props => { } const { locale } = useGlobal() - 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('notion-article') - const imgList = container?.getElementsByTagName('img') - if (imgList && zoomRef.current) { - for (let i = 0; i < imgList.length; i++) { - zoomRef.current.attach(imgList[i]) - } - } - }) - const slotRight = post?.toc && post?.toc?.length > 3 && (
@@ -50,27 +29,9 @@ export const LayoutSlug = props => { slotRight={slotRight} > - {!lock && } + {!lock && } - {lock && } + {lock && } ) } - -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 - } -} diff --git a/themes/medium/components/ArticleDetail.js b/themes/medium/components/ArticleDetail.js index 11add4fc..a0ed321e 100644 --- a/themes/medium/components/ArticleDetail.js +++ b/themes/medium/components/ArticleDetail.js @@ -1,10 +1,3 @@ -import { - Code, - Collection, - CollectionRow, - Equation, - NotionRenderer -} from 'react-notion-x' import Comment from '@/components/Comment' import Image from 'next/image' import Link from 'next/link' @@ -14,18 +7,8 @@ import TagItemMini from './TagItemMini' import CONFIG_MEDIUM from '../config_medium' import formatDate from '@/lib/formatDate' import { useGlobal } from '@/lib/global' - -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 BLOG from '@/blog.config' - -const mapPageUrl = id => { - return 'https://www.notion.so/' + id.replace(/-/g, '') -} +import NotionPage from '@/components/NotionPage' export const ArticleDetail = props => { const { post, prev, next } = props @@ -54,6 +37,9 @@ export const ArticleDetail = props => {
{date}
+
+ {locale.COMMON.LAST_EDITED_TIME}: {post.lastEditedTime} +
  @@ -62,18 +48,7 @@ export const ArticleDetail = props => { {/* Notion文章主体 */}
- {post.blockMap && ( - - )} + {post.blockMap && ()}
@@ -90,10 +65,10 @@ export const ArticleDetail = props => {
- { CONFIG_MEDIUM.POST_DETAIL_CATEGORY && post.category && } -
- { CONFIG_MEDIUM.POST_DETAIL_TAG && post?.tagItems?.map(tag => )} -
+ {CONFIG_MEDIUM.POST_DETAIL_CATEGORY && post.category && } +
+ {CONFIG_MEDIUM.POST_DETAIL_TAG && post?.tagItems?.map(tag => )} +
diff --git a/themes/medium/components/BlogPostCard.js b/themes/medium/components/BlogPostCard.js index 0af31a13..b1ac3072 100644 --- a/themes/medium/components/BlogPostCard.js +++ b/themes/medium/components/BlogPostCard.js @@ -1,8 +1,8 @@ import BLOG from '@/blog.config' +import NotionPage from '@/components/NotionPage' import { useGlobal } from '@/lib/global' import Link from 'next/link' import React from 'react' -import { Code, Collection, Equation, NotionRenderer } from 'react-notion-x' import CONFIG_MEDIUM from '../config_medium' import CategoryItem from './CategoryItem' import TagItemMini from './TagItemMini' @@ -51,16 +51,7 @@ const BlogPostCard = ({ post, showSummary }) => { {showPreview && (
- +
@@ -78,8 +69,4 @@ const BlogPostCard = ({ post, showSummary }) => { ) } -const mapPageUrl = id => { - return 'https://www.notion.so/' + id.replace(/-/g, '') -} - export default BlogPostCard diff --git a/themes/next/components/ArticleDetail.js b/themes/next/components/ArticleDetail.js index 194020dd..ba49b0a6 100644 --- a/themes/next/components/ArticleDetail.js +++ b/themes/next/components/ArticleDetail.js @@ -6,50 +6,23 @@ import ShareBar from './ShareBar' import TagItem from './TagItem' import formatDate from '@/lib/formatDate' import { useGlobal } from '@/lib/global' -import mediumZoom from 'medium-zoom' import Link from 'next/link' import { useRouter } from 'next/router' -import 'prismjs' -import 'prismjs/components/prism-bash' -import 'prismjs/components/prism-c' -import 'prismjs/components/prism-java' -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 ArticleCopyright from './ArticleCopyright' import WordCount from './WordCount' +import NotionPage from '@/components/NotionPage' /** * * @param {*} param0 * @returns */ -export default function ArticleDetail (props) { +export default function ArticleDetail(props) { const { post, recommendPosts, prev, next, showArticleInfo } = props const url = BLOG.LINK + useRouter().asPath const { locale } = useGlobal() const date = formatDate(post?.date?.start_date || post.createdTime, locale.LOCALE) - 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 (
{post.type && !post.type.includes('Page') && post?.page_cover && ( -
- {/* eslint-disable-next-line @next/next/no-img-element */} - {post.title} -
+
+ {/* eslint-disable-next-line @next/next/no-img-element */} + {post.title} +
)} - {/* 文章Title */} -
- {post.title} -
+ {/* 文章Title */} +
+ {post.title} +
-
-
- {post.category && <> - +
+
+ {post.category && <> + {post.category} | - } - {post.type[0] !== 'Page' && (<> - - - {date} - - - | - )} - + } + {post.type[0] !== 'Page' && (<> + + + {date} + + + |
- +   - - | -
-
-
- +
-
+ )} + +
+ +
+ {locale.COMMON.LAST_EDITED_TIME} {post.lastEditedTime} +
+ +
+ +
+
} {/* Notion内容主体 */}
- {post.blockMap && ( - - )} + {post.blockMap && ()}
@@ -129,34 +95,34 @@ export default function ArticleDetail (props) { data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-2708419466378217" - data-ad-slot="3806269138"/> + data-ad-slot="3806269138" />
{showArticleInfo && <> - {/* 版权声明 */} - + {/* 版权声明 */} + - {/* 推荐文章 */} - + {/* 推荐文章 */} + - {/* 标签列表 */} -
- {post.tagItems && ( -
-
- {locale.COMMON.TAGS}: + {/* 标签列表 */} +
+ {post.tagItems && ( +
+
+ {locale.COMMON.TAGS}: +
+ {post.tagItems.map(tag => ( + + ))}
- {post.tagItems.map(tag => ( - - ))} + )} +
+
- )} -
- -
-
+
- + } {/* 评论互动 */} @@ -167,25 +133,3 @@ export default function ArticleDetail (props) {
) } - -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 - } -} diff --git a/themes/next/components/BlogPostCard.js b/themes/next/components/BlogPostCard.js index d51baf68..382a7cf3 100644 --- a/themes/next/components/BlogPostCard.js +++ b/themes/next/components/BlogPostCard.js @@ -3,16 +3,10 @@ import { useGlobal } from '@/lib/global' import Image from 'next/image' import Link from 'next/link' import React from 'react' -import { - Code, - Collection, - CollectionRow, - Equation, - NotionRenderer -} from 'react-notion-x' import Card from './Card' import TagItemMini from './TagItemMini' import CONFIG_NEXT from '../config_next' +import NotionPage from '@/components/NotionPage' const BlogPostCard = ({ post, showSummary }) => { const { locale } = useGlobal() @@ -26,18 +20,16 @@ const BlogPostCard = ({ post, showSummary }) => {
{post.title}
{post.category && ( @@ -87,17 +79,7 @@ const BlogPostCard = ({ post, showSummary }) => { {showPreview && post?.blockMap && (
- +
)} @@ -130,8 +112,4 @@ const BlogPostCard = ({ post, showSummary }) => { ) } -const mapPageUrl = id => { - return 'https://www.notion.so/' + id.replace(/-/g, '') -} - export default BlogPostCard