Skip to content

Commit 1feba5b

Browse files
committed
文章详情页
1 parent 8216bee commit 1feba5b

11 files changed

+252
-106
lines changed

pages/page/[page].js

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export async function getStaticProps ({ params: { page } }) {
3636
description: BLOG.description,
3737
type: 'website'
3838
}
39+
3940
// 处理分页
4041
const postsToShow = allPosts.slice(
4142
BLOG.postsPerPage * (page - 1),

themes/Fukasawa/LayoutPage.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import LayoutBase from './LayoutBase'
44
export const LayoutPage = (props) => {
55
return <LayoutBase {...props}>
66

7-
<BlogListPage posts={props.posts} postCount={props.postCount}/>
7+
<BlogListPage page={props.page} posts={props.posts} postCount={props.postCount}/>
88

99
</LayoutBase>
1010
}

themes/Fukasawa/LayoutSlug.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
1+
import BLOG from '@/blog.config'
12
import 'prismjs'
23
import 'prismjs/components/prism-bash'
34
import 'prismjs/components/prism-javascript'
45
import 'prismjs/components/prism-markup'
56
import 'prismjs/components/prism-python'
67
import 'prismjs/components/prism-typescript'
8+
import ArticleDetail from './components/ArticleDetail'
79
import LayoutBase from './LayoutBase'
810

911
export const LayoutSlug = (props) => {
10-
return <LayoutBase {...props}>
11-
首页
12-
</LayoutBase>
12+
const { post } = props
13+
const meta = {
14+
title: `${post.title} | ${BLOG.title}`,
15+
description: post.summary,
16+
type: 'article',
17+
tags: post.tags
18+
}
19+
20+
return (
21+
<LayoutBase meta={meta} {...props} >
22+
<ArticleDetail {...props} />
23+
</LayoutBase>
24+
)
1325
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import Link from 'next/link'
2+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3+
import { faAngleDoubleLeft, faAngleDoubleRight } from '@fortawesome/free-solid-svg-icons'
4+
5+
/**
6+
* 上一篇,下一篇文章
7+
* @param {prev,next} param0
8+
* @returns
9+
*/
10+
export default function ArticleAround ({ prev, next }) {
11+
if (!prev || !next) {
12+
return <></>
13+
}
14+
return <section className='text-gray-800 h-28 flex items-center justify-between space-x-5 my-4'>
15+
<Link href={`/article/${prev.slug}`} passHref>
16+
<a className='text-sm cursor-pointer justify-center items-center flex w-full h-full bg-gray-400 bg-opacity-50 hover:bg-gray-700 hover:text-white duration-300'>
17+
<FontAwesomeIcon icon={faAngleDoubleLeft} className='mr-1' />{prev.title}
18+
</a>
19+
</Link>
20+
<Link href={`/article/${next.slug}`} passHref>
21+
<a className='text-sm cursor-pointer justify-center items-center flex w-full h-full bg-gray-400 bg-opacity-50 hover:bg-gray-700 hover:text-white duration-300'>{next.title}
22+
<FontAwesomeIcon icon={faAngleDoubleRight} className='ml-1 my-1' />
23+
</a>
24+
</Link>
25+
</section>
26+
}
+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import Comment from '@/components/Comment'
2+
import formatDate from '@/lib/formatDate'
3+
import { useGlobal } from '@/lib/global'
4+
import { faEye, faFolderOpen } from '@fortawesome/free-solid-svg-icons'
5+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
6+
import mediumZoom from 'medium-zoom'
7+
import Link from 'next/link'
8+
import 'prismjs'
9+
import 'prismjs/components/prism-bash'
10+
import 'prismjs/components/prism-javascript'
11+
import 'prismjs/components/prism-markup'
12+
import 'prismjs/components/prism-python'
13+
import 'prismjs/components/prism-typescript'
14+
import { useEffect, useRef } from 'react'
15+
import { Code, Collection, CollectionRow, Equation, NotionRenderer } from 'react-notion-x'
16+
import ArticleAround from './ArticleArount'
17+
18+
/**
19+
*
20+
* @param {*} param0
21+
* @returns
22+
*/
23+
export default function ArticleDetail ({ post, recommendPosts, prev, next }) {
24+
const { locale } = useGlobal()
25+
const date = formatDate(post?.date?.start_date || post.createdTime, locale.LOCALE)
26+
27+
const zoom = typeof window !== 'undefined' && mediumZoom({
28+
container: '.notion-viewport',
29+
background: 'rgba(0, 0, 0, 0.2)',
30+
margin: getMediumZoomMargin()
31+
})
32+
const zoomRef = useRef(zoom ? zoom.clone() : null)
33+
34+
useEffect(() => {
35+
// 将所有container下的所有图片添加medium-zoom
36+
const container = document.getElementById('container')
37+
const imgList = container.getElementsByTagName('img')
38+
if (imgList && zoomRef.current) {
39+
for (let i = 0; i < imgList.length; i++) {
40+
(zoomRef.current).attach(imgList[i])
41+
}
42+
}
43+
})
44+
45+
return (<div id="container" className=" max-w-4xl overflow-x-auto flex-grow mx-auto w-screen md:w-full ">
46+
<article itemScope itemType="https://schema.org/Movie"
47+
className="subpixel-antialiased py-10 px-5 lg:pt-24 md:px-24 dark:border-gray-700 bg-white dark:bg-gray-800"
48+
>
49+
50+
<header className='animate__slideInDown animate__animated'>
51+
{post.type && !post.type.includes('Page') && post?.page_cover && (
52+
<div className="w-full relative md:flex-shrink-0 overflow-hidden">
53+
<img alt={post.title} src={post?.page_cover} className='object-center w-full' />
54+
</div>
55+
)}
56+
57+
{/* 文章Title */}
58+
<div className="font-bold text-3xl text-black dark:text-white font-serif pt-10">
59+
{post.title}
60+
</div>
61+
62+
<section className="flex-wrap flex mt-2 text-gray-400 dark:text-gray-400 font-light leading-8">
63+
<div>
64+
<Link href={`/category/${post.category}`} passHref>
65+
<a className="cursor-pointer text-md mr-2 hover:text-black dark:hover:text-white border-b dark:border-gray-500 border-dashed">
66+
<FontAwesomeIcon icon={faFolderOpen} className="mr-1" />
67+
{post.category}
68+
</a>
69+
</Link>
70+
<span className='mr-2'>|</span>
71+
72+
{post.type[0] !== 'Page' && (<>
73+
<Link
74+
href={`/archive#${post?.date?.start_date?.substr(0, 7)}`}
75+
passHref
76+
>
77+
<a className="pl-1 mr-2 cursor-pointer hover:text-gray-700 dark:hover:text-gray-200 border-b dark:border-gray-500 border-dashed">
78+
{date}
79+
</a>
80+
</Link>
81+
<span className='mr-2'>|</span>
82+
</>)}
83+
84+
<div className="hidden busuanzi_container_page_pv font-light mr-2">
85+
<FontAwesomeIcon icon={faEye} className='mr-1'/>
86+
&nbsp;
87+
<span className="mr-2 busuanzi_value_page_pv"/>
88+
<span className='mr-2'>|</span>
89+
</div>
90+
</div>
91+
92+
</section>
93+
94+
</header>
95+
96+
{/* Notion文章主体 */}
97+
<section id='notion-article' className='px-1'>
98+
{post.blockMap && (
99+
<NotionRenderer
100+
recordMap={post.blockMap}
101+
mapPageUrl={mapPageUrl}
102+
components={{
103+
equation: Equation,
104+
code: Code,
105+
collectionRow: CollectionRow,
106+
collection: Collection
107+
}}
108+
/>
109+
)}
110+
</section>
111+
112+
<section className="px-1 py-2 my-1 text-sm font-light overflow-auto text-gray-600 dark:text-gray-400">
113+
{/* 文章内嵌广告 */}
114+
<ins className="adsbygoogle"
115+
style={{ display: 'block', textAlign: 'center' }}
116+
data-adtest="on"
117+
data-ad-layout="in-article"
118+
data-ad-format="fluid"
119+
data-ad-client="ca-pub-2708419466378217"
120+
data-ad-slot="3806269138"/>
121+
</section>
122+
123+
</article>
124+
125+
<ArticleAround prev={prev} next={next}/>
126+
127+
{/* 评论互动 */}
128+
<div className="duration-200 shadow px-12 w-screen md:w-full overflow-x-auto dark:border-gray-700 bg-white dark:bg-gray-800">
129+
<div className='text-2xl mt-8 mx-8'>发表评论</div>
130+
<Comment frontMatter={post} />
131+
</div>
132+
</div>)
133+
}
134+
135+
const mapPageUrl = id => {
136+
return 'https://www.notion.so/' + id.replace(/-/g, '')
137+
}
138+
139+
function getMediumZoomMargin () {
140+
const width = window.innerWidth
141+
142+
if (width < 500) {
143+
return 8
144+
} else if (width < 800) {
145+
return 20
146+
} else if (width < 1280) {
147+
return 30
148+
} else if (width < 1600) {
149+
return 40
150+
} else if (width < 1920) {
151+
return 48
152+
} else {
153+
return 72
154+
}
155+
}

themes/Fukasawa/components/BlogListPage.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import BlogCard from './BlogCard'
2-
import PaginationNumber from './PaginationNumber'
31
import BLOG from '@/blog.config'
2+
import BlogCard from './BlogCard'
43
import BlogPostListEmpty from './BlogListEmpty'
4+
import PaginationSimple from './PaginationSimple'
55

66
/**
77
* 文章列表分页表格
@@ -13,21 +13,21 @@ import BlogPostListEmpty from './BlogListEmpty'
1313
*/
1414
const BlogListPage = ({ page = 1, posts = [], postCount }) => {
1515
const totalPage = Math.ceil(postCount / BLOG.postsPerPage)
16-
16+
const showNext = page < totalPage
1717
if (!posts || posts.length === 0) {
1818
return <BlogPostListEmpty />
1919
} else {
2020
return (
2121
<div id="container">
2222
{/* 文章列表 */}
23-
<div className="grid 2xl:grid-cols-3 lg:grid-cols-2 md:grid-cols-1 ">
23+
<div style={{ columnCount: 3 }}>
2424
{posts.map(post => (
25-
<div key={post.id} className='justify-center flex'>
25+
<div key={post.id} className='justify-center flex' style={{ breakInside: 'avoid' }}>
2626
<BlogCard key={post.id} post={post} />
2727
</div>
2828
))}
2929
</div>
30-
<PaginationNumber page={page} totalPage={totalPage} />
30+
<PaginationSimple page={page} showNext={showNext} />
3131
</div>
3232
)
3333
}

themes/Fukasawa/components/Card.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const Card = ({ children, headerSlot, className }) => {
22
return <div className={className}>
33
<>{headerSlot}</>
4-
<section className="shadow px-2 py-4 bg-white dark:bg-gray-800 hover:shadow-xl duration-200">
4+
<section className="shadow mb-4 p-2 bg-white dark:bg-gray-800 hover:shadow-lg duration-200">
55
{children}
66
</section>
77
</div>

themes/Fukasawa/components/GroupCategory.js

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import Link from 'next/link'
44
import React from 'react'
55

66
function GroupCategory ({ currentCategory, categories }) {
7+
if (!categories) {
8+
return <></>
9+
}
10+
711
return <>
812
<div id='category-list' className='dark:border-gray-600 flex flex-wrap'>
913
{Object.keys(categories).map(category => {

themes/Fukasawa/components/PaginationNumber.js

-94
This file was deleted.

0 commit comments

Comments
 (0)