分页模式加载文章预览

This commit is contained in:
tangly1024
2022-01-07 17:49:51 +08:00
parent c89048178e
commit f84409e97f
21 changed files with 143 additions and 72 deletions

View File

@@ -30,7 +30,7 @@ import WordCount from './WordCount'
* @param {*} param0
* @returns
*/
export default function ArticleDetail ({ post, blockMap, recommendPosts, prev, next }) {
export default function ArticleDetail ({ post, recommendPosts, prev, next }) {
const targetRef = useRef(null)
const drawerRight = useRef(null)
const url = BLOG.link + useRouter().asPath
@@ -125,9 +125,9 @@ export default function ArticleDetail ({ post, blockMap, recommendPosts, prev, n
{/* Notion文章主体 */}
<section id='notion-article' className='px-1'>
{blockMap && (
{post.blockMap && (
<NotionRenderer
recordMap={blockMap}
recordMap={post.blockMap}
mapPageUrl={mapPageUrl}
components={{
equation: Equation,

View File

@@ -3,24 +3,25 @@ import Link from 'next/link'
import React from 'react'
import Image from 'next/image'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faFolder } from '@fortawesome/free-solid-svg-icons'
import { faAngleDoubleRight, faFolder } from '@fortawesome/free-solid-svg-icons'
import TagItemMini from './TagItemMini'
import { Code, Collection, CollectionRow, Equation, NotionRenderer } from 'react-notion-x'
import { useGlobal } from '@/lib/global'
const BlogPostCard = ({ post }) => {
const BlogPostCard = ({ post, showSummary }) => {
const { locale } = useGlobal()
return (
<div key={post.id} className='shadow animate__animated animate__fadeIn flex xl:flex-row flex-col-reverse justify-between md:hover:shadow-xl duration-300
<div key={post.id} className='shadow border animate__animated animate__fadeIn flex flex-col-reverse justify-between md:hover:shadow-xl duration-300
w-full bg-white dark:bg-gray-800 dark:hover:bg-gray-700 dark:border-gray-600'>
<div className='p-8 flex flex-col justify-between w-full'>
<div className='lg:p-8 p-4 flex flex-col justify-between w-full'>
<Link href={`${BLOG.path}/article/${post.slug}`} passHref>
<a className='cursor-pointer text-xl xl:text-2xl leading-tight text-black dark:text-gray-100 hover:text-blue-500 dark:hover:text-blue-400'>
<a className='cursor-pointer font-bold text-3xl text-center leading-tight text-gray-700 dark:text-gray-100 hover:text-blue-500 dark:hover:text-blue-400'>
{post.title}
</a>
</Link>
<p className='my-8 text-gray-700 dark:text-gray-300 text-md font-light leading-7'>{post.summary}</p>
<div className='flex items-center justify-between flex-wrap dark:text-gray-500 text-gray-400 hover:text-blue-500 dark:hover:text-blue-400 '>
<div className='flex mt-2 items-center justify-center flex-wrap dark:text-gray-500 text-gray-400 hover:text-blue-500 dark:hover:text-blue-400 '>
<div>
<Link href={`/category/${post.category}`} passHref>
<a className='cursor-pointer font-light text-sm hover:underline transform'>
@@ -37,11 +38,36 @@ const BlogPostCard = ({ post }) => {
</div>
</div>
{showSummary && <p className='mt-4 text-gray-700 dark:text-gray-300 text-sm font-light leading-7'>
{post.summary}
</p>}
{BLOG.home?.showPreview && post?.blockMap && <div className='max-h-screen overflow-hidden truncate max-w-full'>
<NotionRenderer
recordMap={post.blockMap}
mapPageUrl={mapPageUrl}
components={{
equation: Equation,
code: Code,
collectionRow: CollectionRow,
collection: Collection
}}
/>
</div> }
<div className='border-b-2 w-full border-dashed py-2'></div>
<Link href={`${BLOG.path}/article/${post.slug}`} passHref>
<div className='flex items-center cursor-pointer pt-6 justify-end leading-tight'>
<a className='bg-black p-2 text-white'>{locale.COMMON.ARTICLE_DETAIL}
<FontAwesomeIcon icon={faAngleDoubleRight} /></a>
</div>
</Link>
</div>
{post?.page_cover && (
{BLOG.home?.showPostCover && post?.page_cover && (
<Link href={`${BLOG.path}/article/${post.slug}`} passHref>
<div className='h-60 w-full xl:max-w-xs relative xl:h-full duration-200 cursor-pointer transform overflow-hidden'>
<div className='h-72 w-full relative duration-200 cursor-pointer transform overflow-hidden'>
<Image className='hover:scale-105 transform duration-500' src={post?.page_cover} alt={post.title} layout='fill' objectFit='cover' loading='lazy' />
</div>
</Link>
@@ -50,4 +76,8 @@ const BlogPostCard = ({ post }) => {
)
}
const mapPageUrl = id => {
return 'https://www.notion.so/' + id.replace(/-/g, '')
}
export default BlogPostCard

View File

@@ -18,9 +18,9 @@ const BlogPostListPage = ({ page = 1, posts = [], postCount }) => {
return <BlogPostListEmpty />
} else {
return (
<div id="container" className='mt-10'>
<div id="container">
{/* 文章列表 */}
<div className="flex flex-wrap space-y-8 mx-5 md:mx-0">
<div className="flex flex-wrap lg:space-y-4 space-y-1">
{posts.map(post => (
<BlogPostCard key={post.id} post={post} />
))}

View File

@@ -1,10 +1,9 @@
import BlogPostCard from '@/components/BlogPostCard'
import BLOG from '@/blog.config'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import throttle from 'lodash.throttle'
import BlogPostCard from '@/components/BlogPostCard'
import BlogPostListEmpty from '@/components/BlogPostListEmpty'
import { useGlobal } from '@/lib/global'
import throttle from 'lodash.throttle'
import React, { useCallback, useEffect, useRef, useState } from 'react'
/**
* 博客列表滚动分页
@@ -14,7 +13,7 @@ import { useGlobal } from '@/lib/global'
* @returns {JSX.Element}
* @constructor
*/
const BlogPostListScroll = ({ posts = [], currentSearch, currentCategory, currentTag }) => {
const BlogPostListScroll = ({ posts = [], currentSearch, showSummary = BLOG.home.showSummary }) => {
const postsPerPage = BLOG.postsPerPage
const [page, updatePage] = useState(1)
const postsToShow = getPostByPage(page, posts, postsPerPage)
@@ -53,12 +52,12 @@ const BlogPostListScroll = ({ posts = [], currentSearch, currentCategory, curren
if (!postsToShow || postsToShow.length === 0) {
return <BlogPostListEmpty currentSearch={currentSearch} />
} else {
return <div id='container' className='mt-10' ref={targetRef}>
return <div id='container' ref={targetRef}>
{/* 文章列表 */}
<div className='flex flex-wrap space-y-8 mx-5 md:mx-0'>
<div className='flex flex-wrap space-y-8'>
{postsToShow.map(post => (
<BlogPostCard key={post.id} post={post}/>
<BlogPostCard key={post.id} post={post} showSummary={showSummary}/>
))}
</div>

View File

@@ -4,7 +4,7 @@ import React from 'react'
const Logo = () => {
return <Link href='/' passHref>
<div className='flex flex-col justify-center items-center cursor-pointer bg-gray-800 space-y-3 h-32 font-bold mb-4'>
<div className='flex flex-col justify-center items-center cursor-pointer bg-black space-y-3 h-32 font-bold'>
<div className='font-serif text-xl text-white'> {BLOG.title}</div>
<div className='text-sm text-gray-300 font-light'> {BLOG.description}</div>
</div>

View File

@@ -30,7 +30,9 @@ const SideAreaLeft = ({ title, tags, currentTag, post, postCount, categories, cu
{/* 菜单 */}
<section className='shadow hidden lg:block mb-5 pb-4 bg-white dark:bg-gray-800 hover:shadow-xl duration-200'>
<Logo/>
<div className='pt-2'>
<MenuButtonGroup allowCollapse={true} />
</div>
{BLOG.menu.showSearch && <div className='px-5 pt-2'>
<SearchInput currentTag={currentTag} currentSearch={currentSearch} />
</div>}

View File

@@ -6,7 +6,6 @@ import { faAngleDoubleRight, faTag, faThList } from '@fortawesome/free-solid-svg
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import Link from 'next/link'
import React from 'react'
import Logo from './Logo'
/**
* 侧边栏
@@ -30,7 +29,6 @@ const SideBar = ({ title, tags, currentTag, post, slot, categories, currentCateg
<InfoCard />
</section>
<Logo/>
{/* 分类 */}
{categories && (
<section className='mt-8'>

View File

@@ -48,7 +48,7 @@ const SideBarDrawer = ({ post, currentTag, cRef, tags, slot, categories, current
}
return <div id='sidebar-wrapper' className='hidden'>
<div id='sidebar-drawer' className='-ml-80 bg-white dark:bg-gray-900 flex flex-col duration-300 fixed h-full left-0 overflow-y-scroll scroll-hidden top-0 z-50 shadow-2xl'>
<div id='sidebar-drawer' className='-ml-80 bg-white dark:bg-gray-900 flex flex-col duration-300 fixed h-full left-0 overflow-y-scroll scroll-hidden top-0 z-50'>
<SideBar tags={tags} post={post} slot={slot} categories={categories} currentCategory={currentCategory} />
</div>
{/* 背景蒙版 */}

View File

@@ -36,7 +36,7 @@ const StickyBar = ({ children }) => {
return (
<div id='sticky-bar' className='sticky flex-grow justify-center top-14 md:top-0 duration-500 z-10 pb-16'>
<div className='glassmorphism dark:border-gray-600 px-5 absolute shadow-xl border w-full hidden-scroll'>
<div className='glassmorphism dark:border-gray-600 px-5 absolute shadow-md border w-full hidden-scroll'>
<div id='tag-container' className="md:pl-3 overflow-x-auto">
{ children }
</div>

View File

@@ -3,10 +3,10 @@ import SideBarDrawer from '@/components/SideBarDrawer'
import { useGlobal } from '@/lib/global'
import { faBars, faSearch } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import Link from 'next/link'
import { useCallback, useEffect, useRef } from 'react'
import SearchDrawer from './SearchDrawer'
import throttle from 'lodash.throttle'
import { useCallback, useEffect, useRef } from 'react'
import Logo from './Logo'
import SearchDrawer from './SearchDrawer'
let windowTop = 0
@@ -35,7 +35,7 @@ const TopNav = ({ tags, currentTag, post, slot, categories, currentCategory, aut
// 监听滚动
useEffect(() => {
if (BLOG.autoCollapsedNavBar) {
if (BLOG.topNavType === 'autoCollapse') {
scrollTrigger()
window.addEventListener('scroll', scrollTrigger)
}
@@ -43,30 +43,28 @@ const TopNav = ({ tags, currentTag, post, slot, categories, currentCategory, aut
BLOG.autoCollapsedNavBar && window.removeEventListener('scroll', scrollTrigger)
}
}, [])
return (<div id='top-nav' className='sticky top-0 z-40 block lg:hidden'>
return (<div id='top-nav' className='z-40 block lg:hidden'>
{/* 侧面抽屉 */}
<SideBarDrawer post={post} currentTag={currentTag} cRef={drawer} tags={tags} slot={slot} categories={categories} currentCategory={currentCategory}/>
<SearchDrawer cRef={searchDrawer}/>
{/* 导航栏 */}
<div id='sticky-nav' className='flex animate__animated animate__fadeIn fixed lg:relative w-full top-0 z-20 transform duration-500'>
<div className='w-full flex justify-between items-center p-4 glassmorphism'>
<div id='sticky-nav' className={`${BLOG.topNavType !== 'normal' ? 'fixed' : ''} flex animate__animated animate__fadeIn lg:relative w-full top-0 z-20 transform duration-500`}>
<div className='w-full flex justify-between items-center p-4 bg-black text-white'>
{/* 左侧LOGO 标题 */}
<div className='flex flex-none flex-grow-0'>
<div onClick={() => { drawer.current.handleSwitchSideDrawerVisible() }}
className='w-8 cursor-pointer dark:text-gray-300'>
className='w-8 cursor-pointer'>
<FontAwesomeIcon icon={faBars} size={'lg'}/>
</div>
</div>
<Link href='/' passHref>
<a>
<h1 className='cursor-pointer ml-2 w-full hover:scale-105 duration-200 transform font-serif dark:text-gray-200 whitespace-nowrap overflow-x-hidden'>{ BLOG.title }</h1>
</a>
</Link>
<div className='flex'>
<Logo/>
</div>
{/* 右侧功能 */}
<div className='mr-1 flex flex-nowrap flex-grow justify-end items-center text-sm space-x-4 font-serif dark:text-gray-200'>
<div className='mr-1 flex justify-end items-center text-sm space-x-4 font-serif dark:text-gray-200'>
<div className="cursor-pointer block lg:hidden" onClick={() => { searchDrawer?.current?.show() }}>
<FontAwesomeIcon icon={faSearch} className="mr-2" />{locale.NAV.SEARCH}
</div>