mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-14 07:26:52 +00:00
feature: 新增数字分页插件
This commit is contained in:
@@ -20,6 +20,7 @@ const BLOG = {
|
||||
darkBackground: '#111827', // use hex value, don't forget '#'
|
||||
path: '', // leave this empty unless you want to deploy in a folder
|
||||
since: 2020, // if leave this empty, current year will be used.
|
||||
postListStyle: 'page', // ['page','scroll] 文章列表样式:页码分页、单页滚动加载
|
||||
postsPerPage: 6, // post counts per page
|
||||
sortByDate: false,
|
||||
autoCollapsedNavBar: true, // the automatically collapsed navigation bar
|
||||
|
||||
@@ -51,7 +51,7 @@ export default function ArticleDetail ({ post, blockMap, recommendPosts, prev, n
|
||||
const attachZoomRef = attachZoom
|
||||
|
||||
return (<>
|
||||
<div id="article-wrapper" ref={targetRef} className="shadow md:hover:shadow-2xl duration-300 overflow-x-auto flex-grow mx-auto w-screen md:w-full ">
|
||||
<div id="container" ref={targetRef} className="shadow md:hover:shadow-2xl duration-300 overflow-x-auto flex-grow mx-auto w-screen md:w-full ">
|
||||
<article itemScope itemType="https://schema.org/Movie"
|
||||
className="subpixel-antialiased py-10 px-5 lg:pt-24 md:px-24 dark:border-gray-700 bg-white dark:bg-gray-800"
|
||||
>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import BlogPostCard from '@/components/BlogPostCard'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import PaginationNumber from './PaginationNumber'
|
||||
import BLOG from '@/blog.config'
|
||||
|
||||
import { useRouter } from 'next/router'
|
||||
@@ -29,7 +29,7 @@ const BlogPostListPage = ({ page = 1, posts = [], tags }) => {
|
||||
}
|
||||
|
||||
// 处理分页
|
||||
const totalPages = Math.ceil(filteredBlogPosts.length / BLOG.postsPerPage)
|
||||
const totalPage = Math.ceil(filteredBlogPosts.length / BLOG.postsPerPage)
|
||||
const postsToShow = filteredBlogPosts.slice(
|
||||
BLOG.postsPerPage * (page - 1),
|
||||
BLOG.postsPerPage * page
|
||||
@@ -43,28 +43,18 @@ const BlogPostListPage = ({ page = 1, posts = [], tags }) => {
|
||||
if (!postsToShow || postsToShow.length === 0) {
|
||||
return <BlogPostListEmpty />
|
||||
} else {
|
||||
return <div id='post-list-wrapper' className='pt-16 md:pt-28 px-2 md:px-20'>
|
||||
{(!page || page === 1) && (<div className='py-5' />)}
|
||||
|
||||
{(page && page !== 1) && (
|
||||
<div className='pb-5'>
|
||||
<div className='dark:text-gray-200 flex justify-between py-1'>
|
||||
{page && page !== 1 && (<span>页 {page} / {totalPages}</span>)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
return (
|
||||
<div id="container" className='mt-10'>
|
||||
{/* 文章列表 */}
|
||||
<div className='flex flex-wrap'>
|
||||
<div className="flex flex-wrap space-y-8 mx-5 md:mx-0">
|
||||
{postsToShow.map(post => (
|
||||
<BlogPostCard key={post.id} post={post} tags={tags} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Pagination page={page} showNext={showNext} />
|
||||
<PaginationNumber page={page} showNext={showNext} totalPage={totalPage} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ const BlogPostListScroll = ({ posts = [], tags, currentSearch, currentCategory,
|
||||
if (!postsToShow || postsToShow.length === 0) {
|
||||
return <BlogPostListEmpty currentSearch={currentSearch} />
|
||||
} else {
|
||||
return <div id='post-list-wrapper' className='mt-10' ref={targetRef}>
|
||||
return <div id='container' className='mt-10' ref={targetRef}>
|
||||
|
||||
{/* 文章列表 */}
|
||||
<div className='flex flex-wrap space-y-8 mx-5 md:mx-0'>
|
||||
|
||||
95
components/PaginationNumber.js
Normal file
95
components/PaginationNumber.js
Normal file
@@ -0,0 +1,95 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { faAngleLeft, faAngleRight } from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
/**
|
||||
* 数字翻页插件
|
||||
* @param page 当前页码
|
||||
* @param showNext 是否有下一页
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const PaginationNumber = ({ page, showNext, totalPage }) => {
|
||||
const router = useRouter()
|
||||
const currentPage = +page
|
||||
const pages = generatePages(page, currentPage, totalPage)
|
||||
|
||||
return (
|
||||
<div className='my-5 flex justify-center items-end font-medium text-black hover:shadow-xl duration-500 bg-white dark:bg-gray-700 dark:text-gray-300 py-3 shadow space-x-2'>
|
||||
|
||||
{/* 上一页 */}
|
||||
<Link
|
||||
href={ {
|
||||
pathname: (currentPage - 1 === 1 ? `${BLOG.path || '/'}` : `/page/${currentPage - 1}`), query: router.query.s ? { s: router.query.s } : {}
|
||||
} } passHref >
|
||||
<div
|
||||
rel='prev'
|
||||
className={`${currentPage === 1 ? 'invisible' : 'block'} border-white dark:border-gray-700 hover:border-gray-400 dark:hover:border-gray-400 w-6 text-center cursor-pointer duration-200 hover:font-bold`}
|
||||
>
|
||||
<FontAwesomeIcon icon={faAngleLeft}/>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
{pages}
|
||||
|
||||
{/* 下一页 */}
|
||||
<Link href={ { pathname: `/page/${currentPage + 1}`, query: router.query.s ? { s: router.query.s } : {} } } passHref>
|
||||
<div
|
||||
rel='next'
|
||||
className={`${+showNext ? 'block' : 'invisible'} border-t-2 border-white dark:border-gray-700 hover:border-gray-400 dark:hover:border-gray-400 w-6 text-center cursor-pointer duration-500 hover:font-bold`}
|
||||
>
|
||||
<FontAwesomeIcon icon={faAngleRight}/>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function getPageElement (page, currentPage) {
|
||||
console.log(page, currentPage)
|
||||
return <Link href={`/page/${page}`} key={page} passHref>
|
||||
<div className={(page + '' === currentPage ? 'font-bold bg-gray-500 dark:bg-gray-400 text-white ' : 'border-t-2 duration-500 border-white hover:border-gray-400 ') +
|
||||
' border-white dark:border-gray-700 dark:hover:border-gray-400 cursor-pointer w-6 text-center font-light hover:font-bold'}>
|
||||
{page}
|
||||
</div>
|
||||
</Link>
|
||||
}
|
||||
function generatePages (page, currentPage, totalPage) {
|
||||
const pages = []
|
||||
const startPage = 1 // 分组开始页码
|
||||
const groupCount = 5 // 页码分组
|
||||
if (totalPage <= 10) {
|
||||
for (let i = 1; i <= totalPage; i++) {
|
||||
pages.push(getPageElement(i, page))
|
||||
}
|
||||
} else {
|
||||
pages.push(getPageElement(1, page))
|
||||
|
||||
let pageLength = 0
|
||||
if (groupCount + startPage > totalPage) {
|
||||
pageLength = totalPage
|
||||
} else {
|
||||
pageLength = groupCount + startPage
|
||||
}
|
||||
|
||||
if (currentPage >= groupCount) {
|
||||
pages.push(<div key={-1}>... </div>)
|
||||
}
|
||||
|
||||
for (let i = startPage; i < pageLength; i++) {
|
||||
if (i <= totalPage - 1 && i > 1) {
|
||||
pages.push(getPageElement(i, page))
|
||||
}
|
||||
}
|
||||
|
||||
if (totalPage - startPage >= groupCount + 1) {
|
||||
pages.push(<div key={-2}>... </div>)
|
||||
}
|
||||
|
||||
pages.push(getPageElement(totalPage, page))
|
||||
}
|
||||
return pages
|
||||
}
|
||||
export default PaginationNumber
|
||||
@@ -4,13 +4,13 @@ import { useRouter } from 'next/router'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
|
||||
/**
|
||||
* 翻页插件
|
||||
* 简易翻页插件
|
||||
* @param page 当前页码
|
||||
* @param showNext 是否有下一页
|
||||
* @returns {JSX.Element}
|
||||
* @constructor
|
||||
*/
|
||||
const Pagination = ({ page, showNext }) => {
|
||||
const PaginationSimple = ({ page, showNext }) => {
|
||||
const { locale } = useGlobal()
|
||||
const router = useRouter()
|
||||
const currentPage = +page
|
||||
@@ -39,4 +39,4 @@ const Pagination = ({ page, showNext }) => {
|
||||
)
|
||||
}
|
||||
|
||||
export default Pagination
|
||||
export default PaginationSimple
|
||||
@@ -16,12 +16,12 @@ export default function Custom404 () {
|
||||
// 延时3秒如果加载失败就返回首页
|
||||
setTimeout(() => {
|
||||
if (window) {
|
||||
const article = document.getElementById('article-wrapper')
|
||||
const article = document.getElementById('container')
|
||||
if (!article) {
|
||||
router.push('/')
|
||||
}
|
||||
}
|
||||
}, 3000)
|
||||
}, 30000000)
|
||||
})
|
||||
|
||||
return <BaseLayout meta={{ title: `${BLOG.title} | 页面找不到啦` }}>
|
||||
|
||||
@@ -4,6 +4,7 @@ import BaseLayout from '@/layouts/BaseLayout'
|
||||
import BlogPostListScroll from '@/components/BlogPostListScroll'
|
||||
import { getNotionPageData } from '@/lib/notion/getNotionData'
|
||||
import Header from '@/components/Header'
|
||||
import BlogPostListPage from '@/components/BlogPostListPage'
|
||||
|
||||
export async function getStaticProps () {
|
||||
const from = 'index'
|
||||
@@ -37,7 +38,11 @@ const Index = ({ allPosts, tags, meta, categories }) => {
|
||||
totalPosts={allPosts}
|
||||
categories={categories}
|
||||
>
|
||||
<BlogPostListScroll posts={allPosts} tags={tags} />
|
||||
{BLOG.postListStyle !== 'page'
|
||||
? (<BlogPostListScroll posts={allPosts} tags={tags} />)
|
||||
: (<BlogPostListPage posts={allPosts} tags={tags} />)
|
||||
}
|
||||
|
||||
</BaseLayout>
|
||||
)
|
||||
}
|
||||
|
||||
65
pages/page/[page].js
Normal file
65
pages/page/[page].js
Normal file
@@ -0,0 +1,65 @@
|
||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
|
||||
import BLOG from '@/blog.config'
|
||||
import BaseLayout from '@/layouts/BaseLayout'
|
||||
import { getNotionPageData } from '@/lib/notion/getNotionData'
|
||||
import Header from '@/components/Header'
|
||||
import Custom404 from '../404'
|
||||
import BlogPostListPage from '@/components/BlogPostListPage'
|
||||
|
||||
const Page = ({ page, allPosts, tags, meta, categories }) => {
|
||||
if (!meta || BLOG.postListStyle !== 'page') {
|
||||
return <Custom404/>
|
||||
}
|
||||
|
||||
return (
|
||||
<BaseLayout
|
||||
headerSlot={BLOG.home.showHomeBanner && <Header />}
|
||||
meta={meta}
|
||||
tags={tags}
|
||||
totalPosts={allPosts}
|
||||
categories={categories}
|
||||
>
|
||||
<BlogPostListPage page={page} posts={allPosts} tags={tags} />
|
||||
</BaseLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getStaticPaths () {
|
||||
const from = 'page'
|
||||
const notionPageData = await getNotionPageData({ from })
|
||||
const allPosts = await getAllPosts({ notionPageData, from })
|
||||
const totalPages = Math.ceil(allPosts / BLOG.postsPerPage)
|
||||
return {
|
||||
// remove first page, we 're not gonna handle that.
|
||||
paths: Array.from({ length: totalPages - 1 }, (_, i) => ({
|
||||
params: { page: '' + (i + 2) }
|
||||
})),
|
||||
fallback: true
|
||||
}
|
||||
}
|
||||
|
||||
export async function getStaticProps ({ params: { page } }) {
|
||||
const from = 'page'
|
||||
const notionPageData = await getNotionPageData({ from })
|
||||
const allPosts = await getAllPosts({ notionPageData, from })
|
||||
const categories = await getAllCategories(allPosts)
|
||||
const tagOptions = notionPageData.tagOptions
|
||||
const tags = await getAllTags({ allPosts, tagOptions })
|
||||
const meta = {
|
||||
title: `${BLOG.title}`,
|
||||
description: BLOG.description,
|
||||
type: 'website'
|
||||
}
|
||||
return {
|
||||
props: {
|
||||
page,
|
||||
allPosts,
|
||||
tags,
|
||||
categories,
|
||||
meta
|
||||
},
|
||||
revalidate: 1
|
||||
}
|
||||
}
|
||||
|
||||
export default Page
|
||||
Reference in New Issue
Block a user