[update] upgrade the reader page

This commit is contained in:
PrinOrange
2024-08-16 17:56:55 +08:00
parent c1e6424db0
commit bc4861f664
8 changed files with 102 additions and 101 deletions

View File

@@ -10,6 +10,7 @@
"micromessenger", "micromessenger",
"nextjs", "nextjs",
"prin", "prin",
"quora",
"readerpage", "readerpage",
"rehype", "rehype",
"Swipeable", "Swipeable",

View File

@@ -20,6 +20,7 @@
"noForEach": "off" "noForEach": "off"
}, },
"correctness": { "correctness": {
"noUnusedImports": "error",
"useExhaustiveDependencies": "off" "useExhaustiveDependencies": "off"
}, },
"suspicious": { "suspicious": {

View File

@@ -1,6 +1,6 @@
const H2 = (props: JSX.IntrinsicElements["h2"]) => { const H2 = (props: JSX.IntrinsicElements["h2"]) => {
return ( return (
<h2 className={"caption-font scroll-mt-20"} id={props.id}> <h2 className={"caption-font mt-6 mb-2 scroll-mt-20"} id={props.id}>
{props.children} {props.children}
</h2> </h2>
); );

View File

@@ -1,7 +1,7 @@
import { Config } from "@/data/config"; import { Config } from "@/data/config";
import Link from "next/link"; import Link from "next/link";
import { FaQuora, FaWeibo } from "react-icons/fa";
import { FiGithub, FiInstagram, FiMail, FiTwitter } from "react-icons/fi"; import { FiGithub, FiInstagram, FiMail, FiTwitter } from "react-icons/fi";
import { FaWeibo } from "react-icons/fa";
import { import {
TbBrandBilibili, TbBrandBilibili,
TbBrandFacebook, TbBrandFacebook,
@@ -95,6 +95,16 @@ export const SocialIcons = () => {
<TbBrandFacebook className="hover:text-blue-500" /> <TbBrandFacebook className="hover:text-blue-500" />
</Link> </Link>
)} )}
{Config.SocialLinks.quora && (
<Link
className="flex w-1/5 basis-0 justify-center p-2"
href={`https://quora.com/profile/${Config.SocialLinks.quora}`}
target="_blank"
title="Quora"
>
<FaQuora className="hover:text-red-500" />
</Link>
)}
{Config.SocialLinks.linkedin && ( {Config.SocialLinks.linkedin && (
<Link <Link
className="flex w-1/5 basis-0 justify-center p-2" className="flex w-1/5 basis-0 justify-center p-2"

View File

@@ -31,6 +31,7 @@ export const Config: TConfig = {
bilibili: "123456", // Bilibili Number ID bilibili: "123456", // Bilibili Number ID
weibo: "123456", // Weibo UID weibo: "123456", // Weibo UID
telegram: "example", // Telegram ID telegram: "example", // Telegram ID
quora: "example", //Quora ID
mastodon: "https://mas.to/@example", // Mastodon link mastodon: "https://mas.to/@example", // Mastodon link
email: "me@example.com", // Email address, required. email: "me@example.com", // Email address, required.
}, },

View File

@@ -1,10 +1,8 @@
import { MDXComponentsSet } from "@/components/mdx"; import { MDXComponentsSet } from "@/components/mdx";
import { BottomCard } from "@/components/reader-page/BottomCard";
import { DrawerTOC } from "@/components/reader-page/DrawerTOC"; import { DrawerTOC } from "@/components/reader-page/DrawerTOC";
import { PostComments } from "@/components/reader-page/PostComments"; import { PostComments } from "@/components/reader-page/PostComments";
import { PostCover } from "@/components/reader-page/PostCover"; import { PostCover } from "@/components/reader-page/PostCover";
import { ShareButtons } from "@/components/reader-page/ShareButtons"; import { ShareButtons } from "@/components/reader-page/ShareButtons";
import { TOC } from "@/components/reader-page/TOC";
import { Separator } from "@/components/ui/separator"; import { Separator } from "@/components/ui/separator";
import { Toaster } from "@/components/ui/toaster"; import { Toaster } from "@/components/ui/toaster";
import { Footer } from "@/components/utils/Footer"; import { Footer } from "@/components/utils/Footer";
@@ -15,7 +13,6 @@ import { Config } from "@/data/config";
import { normalizeDate } from "@/lib/date"; import { normalizeDate } from "@/lib/date";
import { getPostFileContent, sortedPosts } from "@/lib/post-process"; import { getPostFileContent, sortedPosts } from "@/lib/post-process";
import { makeTOCTree } from "@/lib/toc"; import { makeTOCTree } from "@/lib/toc";
import useDrawerTOCState from "@/stores/useDrawerTOCState";
import type { TFrontmatter } from "@/types/frontmatter.type"; import type { TFrontmatter } from "@/types/frontmatter.type";
import type { TPostListItem } from "@/types/post-list"; import type { TPostListItem } from "@/types/post-list";
import type { TTOCItem } from "@/types/toc.type"; import type { TTOCItem } from "@/types/toc.type";
@@ -25,7 +22,6 @@ import { MDXRemote, type MDXRemoteSerializeResult } from "next-mdx-remote";
import { serialize } from "next-mdx-remote/serialize"; import { serialize } from "next-mdx-remote/serialize";
import Link from "next/link"; import Link from "next/link";
import { renderToString } from "react-dom/server"; import { renderToString } from "react-dom/server";
import { useSwipeable } from "react-swipeable";
import rehypeAutolinkHeadings from "rehype-autolink-headings"; import rehypeAutolinkHeadings from "rehype-autolink-headings";
import rehypeHighlight from "rehype-highlight"; import rehypeHighlight from "rehype-highlight";
import rehypeKatex from "rehype-katex"; import rehypeKatex from "rehype-katex";
@@ -35,6 +31,7 @@ import rehypeSlug from "rehype-slug";
import externalLinks from "remark-external-links"; import externalLinks from "remark-external-links";
import remarkGfm from "remark-gfm"; import remarkGfm from "remark-gfm";
import remarkMath from "remark-math"; import remarkMath from "remark-math";
import { titleCase } from "title-case";
type ReaderPageProps = { type ReaderPageProps = {
compiledSource: MDXRemoteSerializeResult; compiledSource: MDXRemoteSerializeResult;
@@ -47,51 +44,49 @@ type ReaderPageProps = {
const ReaderPage = (props: ReaderPageProps) => { const ReaderPage = (props: ReaderPageProps) => {
const compiledSource = props.compiledSource; const compiledSource = props.compiledSource;
const setIsTOCOpen = useDrawerTOCState((state) => state.changeDrawerTOCOpen); // const setIsTOCOpen = useDrawerTOCState((state) => state.changeDrawerTOCOpen);
// Only the TOC length reaches 3 can be displayed. // Only the TOC length reaches 3 can be displayed.
// In order to avoid large blank spaces that ruin the visual perception // In order to avoid large blank spaces that ruin the visual perception
const isTOCLongEnough = props.tocList.length > 2; const isTOCLongEnough = props.tocList.length > 2;
const handleRightSwipe = useSwipeable({ // const handleLeftSwipe = useSwipeable({
onSwipedRight: () => { // onSwipedLeft: () => isTOCLongEnough && setIsTOCOpen(true),
isTOCLongEnough && setIsTOCOpen(true); // delta: 150,
}, // });
delta: 150,
});
return ( return (
<Page> <Page>
<SEO <SEO
coverURL={props.frontMatter.coverURL ?? Config.AvatarURL} coverURL={props.frontMatter.coverURL}
description={props.frontMatter.summary} description={props.frontMatter.summary}
title={`${props.frontMatter.title} - ${Config.SiteTitle}`} title={`${titleCase(props.frontMatter.title)} - ${Config.SiteTitle}`}
/> />
<Toaster /> <Toaster />
<NavBar /> <NavBar />
<ContentContainer> <ContentContainer>
<div <div className="flex justify-center py-5">
className={`py-1 ${isTOCLongEnough ? "justify-between" : "justify-center"} space-x-5 lg:flex`} <div className="typesetting" style={{ width: "min(50rem,100%)" }}>
style={{ borderRadius: "5px" }}
>
<div className={`${isTOCLongEnough ? "lg:w-2/3" : "lg:w-5/6"} py-5`}>
<div className="typesetting">
{props.frontMatter.coverURL && <PostCover coverURL={props.frontMatter.coverURL} />} {props.frontMatter.coverURL && <PostCover coverURL={props.frontMatter.coverURL} />}
<div className="border-black border-b-2 pb-1 dark:border-gray-300"> <div className="border-black border-b-2 pb-1 dark:border-gray-300">
<div <div
className={ className={
"caption-font my-2 flex justify-center whitespace-normal break-words font-bold text-3xl text-black capitalize dark:text-white" "caption-font my-2 flex justify-center whitespace-normal break-words font-bold text-3xl text-black dark:text-white"
} }
> >
{props.frontMatter?.title} {props.frontMatter?.title}
</div> </div>
{props.frontMatter?.subtitle && ( {props.frontMatter?.subtitle && (
<div className={"caption-font my-1 flex justify-center font-bold text-xl capitalize"}> <div className={"my-1 flex justify-center font-bold text-xl content-font"}>
{props.frontMatter.subtitle} {props.frontMatter.subtitle}
</div> </div>
)} )}
<div className="my-1 flex justify-center text-sm italic">{normalizeDate(props.frontMatter?.time)}</div> <div className="my-1 flex justify-center text-sm italic">{normalizeDate(props.frontMatter?.time)}</div>
{props.frontMatter?.summary && ( {props.frontMatter?.summary && (
<p className={"my-4 indent-8 text-gray-800 content-font dark:text-gray-300"}> <p
className={
"my-4 border-gray-400 border-l-4 bg-gray-100 py-5 pr-2 pl-5 text-[16px] text-gray-800 content-font dark:border-gray-600 dark:bg-gray-900 dark:text-gray-300"
}
>
{props.frontMatter?.summary} {props.frontMatter?.summary}
</p> </p>
)} )}
@@ -110,10 +105,8 @@ const ReaderPage = (props: ReaderPageProps) => {
)} )}
</div> </div>
<div <div
className={`text-wrap border-gray-500 content-font ${ className={`text-wrap border-gray-500 content-font ${!props.frontMatter.allowShare ? "select-none" : ""}`}
!props.frontMatter.allowShare ? "select-none" : "" // {...handleLeftSwipe}
}`}
{...handleRightSwipe}
> >
{compiledSource && ( {compiledSource && (
<MDXRemote <MDXRemote
@@ -125,9 +118,8 @@ const ReaderPage = (props: ReaderPageProps) => {
/> />
)} )}
</div> </div>
</div>
<Separator /> <Separator />
<BottomCard /> {/* <BottomCard /> */}
<Separator /> <Separator />
<ShareButtons <ShareButtons
allowShare={props.frontMatter.allowShare} allowShare={props.frontMatter.allowShare}
@@ -161,19 +153,8 @@ const ReaderPage = (props: ReaderPageProps) => {
</ul> </ul>
{Config.Giscus?.enabled && <PostComments postId={props.postId} />} {Config.Giscus?.enabled && <PostComments postId={props.postId} />}
</div> </div>
{isTOCLongEnough && (
<div className="hidden py-5 md:w-1/3 lg:block">
<div className="sticky top-[5em]">
<TOC data={props.tocList} />
</div> </div>
</div> {isTOCLongEnough && <DrawerTOC data={props.tocList} />}
)}
</div>
{isTOCLongEnough && (
<div className="lg:hidden">
<DrawerTOC data={props.tocList} />
</div>
)}
</ContentContainer> </ContentContainer>
<Footer /> <Footer />
</Page> </Page>
@@ -209,6 +190,7 @@ export const getStaticProps: GetStaticProps<ReaderPageProps> = async (context) =
remarkPlugins: [externalLinks, remarkMath, remarkGfm], remarkPlugins: [externalLinks, remarkMath, remarkGfm],
rehypePlugins: [ rehypePlugins: [
rehypeRaw, rehypeRaw,
rehypeKatex as any, rehypeKatex as any,
rehypeAutolinkHeadings, rehypeAutolinkHeadings,
rehypeSlug, rehypeSlug,

View File

@@ -5,21 +5,22 @@
overflow-x-hidden overflow-x-hidden
break-words break-words
px-0 px-0
dark:prose-invert dark:prose-invert
prose-headings:scroll-mt-20 prose-headings:scroll-mt-20
prose-a:text-sky-800 prose-a:text-sky-800
prose-a:decoration-dashed prose-a:decoration-dashed
prose-a:underline-offset-[5px] prose-a:underline-offset-[5px]
prose-figure:mx-auto prose-figure:mx-auto
prose-strong:font-semibold
prose-code:mx-1 prose-code:mx-1
prose-code:overflow-hidden prose-code:overflow-hidden
prose-code:rounded-md prose-code:rounded-md
prose-code:bg-gray-100 prose-code:bg-gray-100
prose-code:px-2 prose-code:px-2
@@ -27,36 +28,40 @@
prose-code:text-sky-700 prose-code:text-sky-700
prose-code:before:content-[''] prose-code:before:content-['']
prose-code:after:content-[''] prose-code:after:content-['']
prose-li:my-0
prose-li:marker:text-black prose-li:marker:text-black
prose-table:mb-5 prose-table:mb-5
prose-table:mt-0 prose-table:mt-0
prose-table:border-2 prose-table:border-2
prose-table:border-gray-400 prose-table:border-gray-400
prose-tr:border-2
prose-tr:border-gray-400
prose-tr:border-2
prose-tr:border-gray-400
prose-tr:p-2 prose-tr:p-2
prose-th:border-2 prose-th:border-2
prose-th:border-gray-400 prose-th:border-gray-400
prose-th:bg-gray-100 prose-th:bg-gray-100
prose-th:p-2 prose-th:p-2
prose-td:border-2 prose-td:border-2
prose-td:border-gray-400
prose-td:p-2 prose-td:border-gray-400
prose-td:p-2
prose-img:mx-auto
prose-hr:my-6
prose-hr:border-gray-300
prose-img:mx-auto
dark:prose-a:text-sky-500 dark:prose-a:text-sky-500
prose-code:dark:bg-gray-800 prose-code:dark:bg-gray-800
dark:prose-code:text-sky-500 dark:prose-code:text-sky-500
dark:prose-li:marker:text-gray-100 dark:prose-li:marker:text-gray-100
dark:prose-table:border-gray-700 dark:prose-table:border-gray-700
dark:prose-tr:border-gray-700 dark:prose-tr:border-gray-700
dark:prose-th:border-gray-700 dark:prose-th:border-gray-700
dark:prose-th:bg-gray-900 dark:prose-th:bg-gray-900
dark:prose-td:border-gray-700; dark:prose-td:border-gray-700
prose-hr:dark:border-gray-600;
} }

View File

@@ -14,6 +14,7 @@ export type TConfig = {
twitter?: string; twitter?: string;
bilibili?: string; bilibili?: string;
weibo?: string; weibo?: string;
quora?: string;
reddit?: string; reddit?: string;
facebook?: string; facebook?: string;
instagram?: string; instagram?: string;