| 
									
										
										
										
											2024-08-16 10:41:36 +08:00
										 |  |  | import { DrawerTOC } from "@/components/reader-page/DrawerTOC"; | 
					
						
							| 
									
										
										
										
											2024-09-28 00:18:55 +08:00
										 |  |  | import { MorePostLinks } from "@/components/reader-page/MorePostLinks"; | 
					
						
							| 
									
										
										
										
											2024-08-16 10:41:36 +08:00
										 |  |  | import { PostComments } from "@/components/reader-page/PostComments"; | 
					
						
							|  |  |  | import { PostCover } from "@/components/reader-page/PostCover"; | 
					
						
							| 
									
										
										
										
											2024-09-28 00:18:55 +08:00
										 |  |  | import { PostRender } from "@/components/reader-page/PostRender"; | 
					
						
							| 
									
										
										
										
											2024-08-16 10:41:36 +08:00
										 |  |  | import { ShareButtons } from "@/components/reader-page/ShareButtons"; | 
					
						
							| 
									
										
										
										
											2024-01-15 11:44:48 +08:00
										 |  |  | import { Separator } from "@/components/ui/separator"; | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  | import { Toaster } from "@/components/ui/toaster"; | 
					
						
							|  |  |  | import { Footer } from "@/components/utils/Footer"; | 
					
						
							| 
									
										
										
										
											2024-08-16 14:12:30 +08:00
										 |  |  | import { ContentContainer, Page } from "@/components/utils/Layout"; | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  | import { NavBar } from "@/components/utils/NavBar"; | 
					
						
							|  |  |  | import { SEO } from "@/components/utils/SEO"; | 
					
						
							|  |  |  | import { Config } from "@/data/config"; | 
					
						
							|  |  |  | import { getPostFileContent, sortedPosts } from "@/lib/post-process"; | 
					
						
							| 
									
										
										
										
											2024-04-03 22:08:27 +08:00
										 |  |  | import { makeTOCTree } from "@/lib/toc"; | 
					
						
							| 
									
										
										
										
											2024-09-28 00:18:55 +08:00
										 |  |  | import type { TPostFrontmatter, TPostListItem, TPostTOCItem } from "@/types/docs.type"; | 
					
						
							| 
									
										
										
										
											2024-08-14 12:57:22 +08:00
										 |  |  | import type { GetStaticPaths, GetStaticProps } from "next"; | 
					
						
							|  |  |  | import { MDXRemote, type MDXRemoteSerializeResult } from "next-mdx-remote"; | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  | import { serialize } from "next-mdx-remote/serialize"; | 
					
						
							|  |  |  | import { renderToString } from "react-dom/server"; | 
					
						
							|  |  |  | import rehypeAutolinkHeadings from "rehype-autolink-headings"; | 
					
						
							| 
									
										
										
										
											2024-04-03 22:08:27 +08:00
										 |  |  | import rehypeHighlight from "rehype-highlight"; | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  | import rehypeKatex from "rehype-katex"; | 
					
						
							|  |  |  | import rehypePresetMinify from "rehype-preset-minify"; | 
					
						
							| 
									
										
										
										
											2023-12-30 14:45:55 +08:00
										 |  |  | import rehypeRaw from "rehype-raw"; | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  | import rehypeSlug from "rehype-slug"; | 
					
						
							|  |  |  | import externalLinks from "remark-external-links"; | 
					
						
							|  |  |  | import remarkGfm from "remark-gfm"; | 
					
						
							|  |  |  | import remarkMath from "remark-math"; | 
					
						
							| 
									
										
										
										
											2024-08-16 17:56:55 +08:00
										 |  |  | import { titleCase } from "title-case"; | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | type ReaderPageProps = { | 
					
						
							| 
									
										
										
										
											2024-01-04 13:28:16 +08:00
										 |  |  |   compiledSource: MDXRemoteSerializeResult; | 
					
						
							| 
									
										
										
										
											2024-09-28 00:18:55 +08:00
										 |  |  |   tocList: TPostTOCItem[]; | 
					
						
							| 
									
										
										
										
											2024-09-26 16:48:47 +08:00
										 |  |  |   frontMatter: TPostFrontmatter; | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |   postId: string; | 
					
						
							|  |  |  |   nextPostListItem: TPostListItem | null; | 
					
						
							|  |  |  |   prevPostListItem: TPostListItem | null; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const ReaderPage = (props: ReaderPageProps) => { | 
					
						
							| 
									
										
										
										
											2024-01-04 13:28:16 +08:00
										 |  |  |   // Only the TOC length reaches 3 can be displayed.
 | 
					
						
							|  |  |  |   // In order to avoid large blank spaces that ruin the visual perception
 | 
					
						
							| 
									
										
										
										
											2024-04-03 22:08:27 +08:00
										 |  |  |   const isTOCLongEnough = props.tocList.length > 2; | 
					
						
							| 
									
										
										
										
											2024-08-16 17:56:55 +08:00
										 |  |  |   // const handleLeftSwipe = useSwipeable({
 | 
					
						
							|  |  |  |   //   onSwipedLeft: () => isTOCLongEnough && setIsTOCOpen(true),
 | 
					
						
							|  |  |  |   //   delta: 150,
 | 
					
						
							|  |  |  |   // });
 | 
					
						
							| 
									
										
										
										
											2024-01-04 13:28:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |   return ( | 
					
						
							|  |  |  |     <Page> | 
					
						
							|  |  |  |       <SEO | 
					
						
							| 
									
										
										
										
											2024-08-16 17:56:55 +08:00
										 |  |  |         coverURL={props.frontMatter.coverURL} | 
					
						
							| 
									
										
										
										
											2024-04-03 22:08:27 +08:00
										 |  |  |         description={props.frontMatter.summary} | 
					
						
							| 
									
										
										
										
											2024-08-16 17:56:55 +08:00
										 |  |  |         title={`${titleCase(props.frontMatter.title)} - ${Config.SiteTitle}`} | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |       /> | 
					
						
							|  |  |  |       <Toaster /> | 
					
						
							| 
									
										
										
										
											2024-01-09 16:48:48 +08:00
										 |  |  |       <NavBar /> | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |       <ContentContainer> | 
					
						
							| 
									
										
										
										
											2024-09-28 00:18:55 +08:00
										 |  |  |         <div className="mx-auto flex flex-col justify-center py-5" style={{ width: "min(50rem,100%)" }}> | 
					
						
							|  |  |  |           {props.frontMatter.coverURL && <PostCover coverURL={props.frontMatter.coverURL} />} | 
					
						
							|  |  |  |           <PostRender | 
					
						
							|  |  |  |             compiledSource={props.compiledSource} | 
					
						
							|  |  |  |             tocList={props.tocList} | 
					
						
							|  |  |  |             frontMatter={props.frontMatter} | 
					
						
							|  |  |  |             postId={props.postId} | 
					
						
							|  |  |  |             nextPostListItem={props.nextPostListItem} | 
					
						
							|  |  |  |             prevPostListItem={props.prevPostListItem} | 
					
						
							|  |  |  |           /> | 
					
						
							|  |  |  |           <Separator /> | 
					
						
							|  |  |  |           <ShareButtons | 
					
						
							|  |  |  |             allowShare={props.frontMatter.allowShare} | 
					
						
							|  |  |  |             postId={props.postId} | 
					
						
							|  |  |  |             quote={props.frontMatter.summary} | 
					
						
							|  |  |  |             subtitle={props.frontMatter.subtitle} | 
					
						
							|  |  |  |             title={props.frontMatter.title} | 
					
						
							|  |  |  |           /> | 
					
						
							|  |  |  |           <Separator /> | 
					
						
							|  |  |  |           <MorePostLinks prevPostListItem={props.prevPostListItem} nextPostListItem={props.nextPostListItem} /> | 
					
						
							|  |  |  |           {Config.Giscus?.enabled && <PostComments postId={props.postId} />} | 
					
						
							|  |  |  |           {isTOCLongEnough && <DrawerTOC data={props.tocList} />} | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |         </div> | 
					
						
							|  |  |  |       </ContentContainer> | 
					
						
							|  |  |  |       <Footer /> | 
					
						
							|  |  |  |     </Page> | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const getStaticPaths: GetStaticPaths<{ id: string }> = async () => { | 
					
						
							|  |  |  |   const allPaths = sortedPosts.allPostList.map((item) => ({ | 
					
						
							|  |  |  |     params: { id: item.id }, | 
					
						
							|  |  |  |   })); | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     paths: allPaths, | 
					
						
							|  |  |  |     fallback: false, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const getStaticProps: GetStaticProps<ReaderPageProps> = async (context) => { | 
					
						
							|  |  |  |   const postId = context.params?.id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (postId == null || Array.isArray(postId)) { | 
					
						
							|  |  |  |     return { notFound: true }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const source = getPostFileContent(postId); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (source == null) { | 
					
						
							|  |  |  |     return { notFound: true }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const mdxSource = await serialize(source, { | 
					
						
							|  |  |  |     parseFrontmatter: true, | 
					
						
							|  |  |  |     mdxOptions: { | 
					
						
							| 
									
										
										
										
											2024-04-03 22:08:27 +08:00
										 |  |  |       remarkPlugins: [externalLinks, remarkMath, remarkGfm], | 
					
						
							|  |  |  |       rehypePlugins: [ | 
					
						
							|  |  |  |         rehypeRaw, | 
					
						
							| 
									
										
										
										
											2024-08-16 17:56:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-03 22:08:27 +08:00
										 |  |  |         rehypeKatex as any, | 
					
						
							|  |  |  |         rehypeAutolinkHeadings, | 
					
						
							|  |  |  |         rehypeSlug, | 
					
						
							|  |  |  |         rehypePresetMinify.plugins, | 
					
						
							|  |  |  |         () => rehypeHighlight({ detect: true }), | 
					
						
							|  |  |  |       ], | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |       format: "md", | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-03 22:08:27 +08:00
										 |  |  |   const tocList = makeTOCTree(renderToString(<MDXRemote {...mdxSource} />)); | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const postIndexInAllPosts = sortedPosts.allPostList.findIndex((item) => item.id === postId); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-26 16:48:47 +08:00
										 |  |  |   const frontMatter: TPostFrontmatter = sortedPosts.allPostList[postIndexInAllPosts].frontMatter; | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const nextPostListItem = | 
					
						
							|  |  |  |     postIndexInAllPosts !== sortedPosts.allPostList.length - 1 | 
					
						
							|  |  |  |       ? sortedPosts.allPostList[postIndexInAllPosts + 1] | 
					
						
							|  |  |  |       : null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const prevPostListItem = postIndexInAllPosts !== 0 ? sortedPosts.allPostList[postIndexInAllPosts - 1] : null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     props: { | 
					
						
							| 
									
										
										
										
											2024-01-04 13:28:16 +08:00
										 |  |  |       compiledSource: mdxSource, | 
					
						
							| 
									
										
										
										
											2023-12-25 17:21:39 +08:00
										 |  |  |       tocList: tocList, | 
					
						
							|  |  |  |       frontMatter: frontMatter, | 
					
						
							|  |  |  |       postId: postId, | 
					
						
							|  |  |  |       nextPostListItem: nextPostListItem, | 
					
						
							|  |  |  |       prevPostListItem: prevPostListItem, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default ReaderPage; |