Add an interactive method for right-swiping to pop up the TOC to the reader page.
This commit is contained in:
13
.vscode/settings.json
vendored
13
.vscode/settings.json
vendored
@@ -1,15 +1,16 @@
|
|||||||
{
|
{
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
|
"alipay",
|
||||||
"frontmatter",
|
"frontmatter",
|
||||||
|
"giscus",
|
||||||
|
"github",
|
||||||
"micromessenger",
|
"micromessenger",
|
||||||
|
"nextjs",
|
||||||
|
"prin",
|
||||||
"readerpage",
|
"readerpage",
|
||||||
"rehype",
|
"rehype",
|
||||||
"wechat",
|
"Swipeable",
|
||||||
"alipay",
|
|
||||||
"vercel",
|
"vercel",
|
||||||
"github",
|
"wechat"
|
||||||
"giscus",
|
|
||||||
"nextjs",
|
|
||||||
"prin"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet";
|
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet";
|
||||||
|
import useDrawerTOCState from "@/stores/useDrawerTOCState";
|
||||||
import { TTOCItem } from "@/types/toc.type";
|
import { TTOCItem } from "@/types/toc.type";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useState } from "react";
|
|
||||||
import { FaHeading } from "react-icons/fa";
|
import { FaHeading } from "react-icons/fa";
|
||||||
|
|
||||||
export const DrawerTOC = (props: { data: TTOCItem[] }) => {
|
export const DrawerTOC = (props: { data: TTOCItem[] }) => {
|
||||||
const [isTOCOpen, setIsTOCOpen] = useState(false);
|
const isTOCOpen = useDrawerTOCState((state) => state.isOpen);
|
||||||
|
const setIsTOCOpen = useDrawerTOCState((state) => state.changeDrawerTOCOpen);
|
||||||
return (
|
return (
|
||||||
<Sheet open={isTOCOpen} onOpenChange={setIsTOCOpen}>
|
<Sheet open={isTOCOpen} onOpenChange={setIsTOCOpen}>
|
||||||
<SheetTrigger
|
<SheetTrigger
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ 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 { getTOCTree } from "@/lib/toc";
|
import { getTOCTree } from "@/lib/toc";
|
||||||
|
import useDrawerTOCState from "@/stores/useDrawerTOCState";
|
||||||
import { fontFangZhengXiaoBiaoSongCN, fontSourceSerifScreenCN } from "@/styles/font";
|
import { fontFangZhengXiaoBiaoSongCN, fontSourceSerifScreenCN } from "@/styles/font";
|
||||||
import { TFrontmatter } from "@/types/frontmatter.type";
|
import { TFrontmatter } from "@/types/frontmatter.type";
|
||||||
import { TPostListItem } from "@/types/post-list";
|
import { TPostListItem } from "@/types/post-list";
|
||||||
@@ -24,6 +25,7 @@ import { MDXRemote, 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 rehypeKatex from "rehype-katex";
|
import rehypeKatex from "rehype-katex";
|
||||||
import rehypePresetMinify from "rehype-preset-minify";
|
import rehypePresetMinify from "rehype-preset-minify";
|
||||||
@@ -45,7 +47,12 @@ type ReaderPageProps = {
|
|||||||
|
|
||||||
const ReaderPage = (props: ReaderPageProps) => {
|
const ReaderPage = (props: ReaderPageProps) => {
|
||||||
const source = props.source;
|
const source = props.source;
|
||||||
|
const setIsTOCOpen = useDrawerTOCState((state) => state.changeDrawerTOCOpen);
|
||||||
|
const handleRightSwipe = useSwipeable({
|
||||||
|
onSwipedRight: () => {
|
||||||
|
setIsTOCOpen(true);
|
||||||
|
},
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
<SEO
|
<SEO
|
||||||
@@ -91,6 +98,7 @@ const ReaderPage = (props: ReaderPageProps) => {
|
|||||||
className={`typesetting ${fontSourceSerifScreenCN.className} mt-0 mb-10 ${
|
className={`typesetting ${fontSourceSerifScreenCN.className} mt-0 mb-10 ${
|
||||||
!props.frontMatter.allowShare && "select-none"
|
!props.frontMatter.allowShare && "select-none"
|
||||||
}`}
|
}`}
|
||||||
|
{...handleRightSwipe}
|
||||||
>
|
>
|
||||||
{source && (
|
{source && (
|
||||||
<MDXRemote
|
<MDXRemote
|
||||||
|
|||||||
16
stores/useDrawerTOCState.ts
Normal file
16
stores/useDrawerTOCState.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { create } from "zustand";
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
isOpen: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Action = {
|
||||||
|
changeDrawerTOCOpen: (open: State["isOpen"]) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useDrawerTOCState = create<State & Action>((set) => ({
|
||||||
|
isOpen: false,
|
||||||
|
changeDrawerTOCOpen: (open) => set({ isOpen: open }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export default useDrawerTOCState;
|
||||||
Reference in New Issue
Block a user