From 71cc59f0d18545dc95a9c8733989f96b52512a48 Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Thu, 16 Dec 2021 11:09:10 +0800 Subject: [PATCH] =?UTF-8?q?feature:=20=E6=A0=B7=E5=BC=8F=E8=B0=83=E6=95=B4?= =?UTF-8?q?=EF=BC=9B=20=E9=A1=B6=E9=83=A8=E8=8F=9C=E5=8D=95=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/ArticleDetail.js | 192 +++++++++++++++++++++++++++++ components/BlogAround.js | 3 + components/BlogPostListEmpty.js | 2 +- components/ContactButton.js | 2 +- components/FloatDarkModeButton.js | 28 +++++ components/InfoCard.js | 2 +- components/JumpToTopButton.js | 10 +- components/MenuButtonGroup.js | 4 +- components/RecommendPosts.js | 40 +----- components/SearchInput.js | 2 +- components/SideBar.js | 11 +- components/Toc.js | 2 +- components/TocDrawer.js | 6 +- components/TocDrawerButton.js | 11 +- components/TopNav.js | 43 +++++-- layouts/BaseLayout.js | 7 +- pages/404.js | 2 +- pages/about.js | 70 +++++++++++ pages/article/[slug].js | 195 +++++++++--------------------- 19 files changed, 417 insertions(+), 215 deletions(-) create mode 100644 components/ArticleDetail.js create mode 100644 components/FloatDarkModeButton.js create mode 100644 pages/about.js diff --git a/components/ArticleDetail.js b/components/ArticleDetail.js new file mode 100644 index 00000000..cbcc3713 --- /dev/null +++ b/components/ArticleDetail.js @@ -0,0 +1,192 @@ +import BLOG from '@/blog.config' + +import { useRouter } from 'next/router' +import Progress from '@/components/Progress' +import TagItem from '@/components/TagItem' +import formatDate from '@/lib/formatDate' +import { Code, Collection, CollectionRow, Equation, NotionRenderer } from 'react-notion-x' +import ShareBar from '@/components/ShareBar' +import Comment from '@/components/Comment' +import Link from 'next/link' +import Image from 'next/image' + +import 'prismjs' +import 'prismjs/components/prism-bash' +import 'prismjs/components/prism-markup' +import 'prismjs/components/prism-python' +import 'prismjs/components/prism-javascript' +import 'prismjs/components/prism-typescript' +import RecommendPosts from '@/components/RecommendPosts' +import TocDrawer from '@/components/TocDrawer' +import TocDrawerButton from '@/components/TocDrawerButton' +import { useGlobal } from '@/lib/global' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faEye, faFolderOpen } from '@fortawesome/free-solid-svg-icons' +import BlogAround from '@/components/BlogAround' +import { useRef } from 'react' + +const mapPageUrl = id => { + return 'https://www.notion.so/' + id.replace(/-/g, '') +} + +/** + * + * @param {*} param0 + * @returns + */ +export default function ArticleDetail ({ post, blockMap, recommendPosts, prev, next }) { + const targetRef = useRef(null) + const drawerRight = useRef(null) + const url = BLOG.link + useRouter().asPath + const { locale } = useGlobal() + const date = formatDate(post?.date?.start_date || post.createdTime, BLOG.lang) + return ( + <> + + +
+
+
+ {post.type && !post.type.includes('Page') && ( + <> +
+ 1 + ? post.page_cover + : BLOG.defaultImgCover + } + loading="eager" + objectFit="cover" + layout="fill" + alt={post.title} + /> +
+ + )} + {/* 文章Title */} +

+ {' '} + {post.title} +

+
+
+ + + + {post.category} + + + {post.type[0] !== 'Page' && ( + + + {date} + + + )} + +
+ +   + +
+
+ +
+ {post.summary} +
+ + {/* Notion文章主体 */} + {blockMap && ( + + )} + + {/* 推荐文章 */} + + + {/* 版权声明 */} +
+
版权声明
+
    +
  • + 本文作者:{' '} + + {BLOG.author} + +
  • +
  • + 本文链接:{' '} + + {url} + +
  • +
  • + 本博客所有文章除特别声明外,均采用 BY-NC-SA + 许可协议。转载请注明出处! +
  • +
+
+ + {/* 标签列表 */} +
+ {post.tagItems && ( +
+
+ {locale.COMMON.TAGS}: +
+ {post.tagItems.map(tag => ( + + ))} +
+ )} +
+ +
+
+ + +
+ + {/* 评论互动 */} +
+ +
+
+
+ + {/* 悬浮目录按钮 */} +
+ { + drawerRight.current.handleSwitchVisible() + }} + /> + {/* 目录侧边栏 */} + +
+ + ) +} diff --git a/components/BlogAround.js b/components/BlogAround.js index 7021575f..01edc213 100644 --- a/components/BlogAround.js +++ b/components/BlogAround.js @@ -8,6 +8,9 @@ import { faAngleDoubleLeft, faAngleDoubleRight } from '@fortawesome/free-solid-s * @returns */ export default function BlogAround ({ prev, next }) { + if (!prev || !next) { + return <> + } return
diff --git a/components/BlogPostListEmpty.js b/components/BlogPostListEmpty.js index 79f88837..acb4e688 100644 --- a/components/BlogPostListEmpty.js +++ b/components/BlogPostListEmpty.js @@ -6,7 +6,7 @@ */ const BlogPostListEmpty = ({ currentSearch }) => { return
-
+

没有找到文章 {(currentSearch &&

{currentSearch}
)}

diff --git a/components/ContactButton.js b/components/ContactButton.js index 705cb19d..753244f8 100644 --- a/components/ContactButton.js +++ b/components/ContactButton.js @@ -10,7 +10,7 @@ import { faInfo } from '@fortawesome/free-solid-svg-icons' */ const ContactButton = () => { return ( - +
diff --git a/components/FloatDarkModeButton.js b/components/FloatDarkModeButton.js new file mode 100644 index 00000000..b36b404b --- /dev/null +++ b/components/FloatDarkModeButton.js @@ -0,0 +1,28 @@ +import { useEffect, useState } from 'react' +import DarkModeButton from './DarkModeButton' + +let windowTop = 0 +export default function FloatDarkModeButton () { + const [show, switchShow] = useState(false) + const scrollListener = () => { + const scrollY = window.pageYOffset + const shouldShow = scrollY > 100 && scrollY < windowTop + windowTop = scrollY + if (shouldShow !== show) { + switchShow(shouldShow) + } + } + useEffect(() => { + document.addEventListener('scroll', scrollListener) + return () => document.removeEventListener('scroll', scrollListener) + }) + + return ( +
+ +
+ ) +} diff --git a/components/InfoCard.js b/components/InfoCard.js index 57c391cd..95cfc4d6 100644 --- a/components/InfoCard.js +++ b/components/InfoCard.js @@ -5,7 +5,7 @@ import Router from 'next/router' const InfoCard = () => { return <> -
{ Router.push('/') }}> +
{ Router.push('/') }}>
{BLOG.title} { return () => document.removeEventListener('scroll', scrollListener) }, [show]) - return (
+ return (
window.scrollTo({ top: 0, behavior: 'smooth' })} - className={(show ? '' : 'hidden') + ' animate__fadeInRight rounded-full glassmorphism p-2 cursor-pointer animate__animated animate__faster shadow-card'}> + className={(show ? '' : 'hidden') + ' animate__fadeInRight animate__animated animate__faster shadow-card rounded-full glassmorphism p-2 cursor-pointer '}>
-
- -
+
+ +
{showPercent && (
{percent}
)}
diff --git a/components/MenuButtonGroup.js b/components/MenuButtonGroup.js index e10e9a6d..78effe4a 100644 --- a/components/MenuButtonGroup.js +++ b/components/MenuButtonGroup.js @@ -12,7 +12,7 @@ const MenuButtonGroup = ({ allowCollapse = false }) => { const links = [ { id: 0, icon: faHome, name: locale.NAV.INDEX, to: '/' || '/', show: true }, { id: 1, icon: faArchive, name: locale.NAV.ARCHIVE, to: '/archive', show: BLOG.showArchive }, - { id: 2, icon: faInfoCircle, name: locale.NAV.ABOUT, to: '/article/about', show: BLOG.showAbout } + { id: 2, icon: faInfoCircle, name: locale.NAV.ABOUT, to: '/about', show: BLOG.showAbout } // { id: 7, icon: 'faGithub', name: 'Github', to: 'https://github.com/tangly1024', show: true }, // { id: 5, icon: 'faWeibo', name: '微博', to: 'https://weibo.com/tangly1024', show: true }, // { id: 4, icon: 'faEnvelope', name: locale.NAV.MAIL, to: 'mailto:tlyong1992@hotmail.com', show: true } @@ -28,7 +28,7 @@ const MenuButtonGroup = ({ allowCollapse = false }) => { if (link.show) { const selected = (router.pathname === link.to) || (router.asPath === link.to) return -
diff --git a/components/RecommendPosts.js b/components/RecommendPosts.js index b20bd754..8ed1ec0b 100644 --- a/components/RecommendPosts.js +++ b/components/RecommendPosts.js @@ -3,49 +3,19 @@ import Link from 'next/link' import { useGlobal } from '@/lib/global' /** - * 洗牌乱序:从数组的最后位置开始,从前面随机一个位置,对两个数进行交换,直到循环完毕 - * @param arr - * @returns {*} + * 展示文章推荐 */ -function shuffleSort (arr) { - let i = arr.length - 1 - while (i > 0) { - const rIndex = Math.floor(Math.random() * i) - const temp = arr[rIndex] - arr[rIndex] = arr[i] - arr[i] = temp - i-- +const RecommendPosts = ({ recommendPosts }) => { + if (!recommendPosts) { + return <> } - return arr -} - -const RecommendPosts = ({ currentPost, totalPosts }) => { - let filteredPosts = totalPosts - // 筛选同标签 - if (currentPost.tags && currentPost.tags.length) { - const currentTag = currentPost.tags[0] - filteredPosts = totalPosts.filter( - post => - post && - post.tags && - post.tags.includes(currentTag) && - post.slug !== currentPost.slug - ) - } - shuffleSort(filteredPosts) - - // 筛选前5个 - if (filteredPosts.length > 5) { - filteredPosts = filteredPosts.slice(0, 5) - } - const { locale } = useGlobal() return (
{locale.COMMON.RELATE_POSTS}