From 8a8513367bff24b135e0d7c058adfc46edfc1cda Mon Sep 17 00:00:00 2001 From: Xuezhou Dai Date: Tue, 18 Apr 2023 22:44:51 +0800 Subject: [PATCH] fix: prose layout (#374) --- src/components/common/PageContent.tsx | 21 +++++++++- src/components/site/PostToc.tsx | 4 +- src/components/site/SitePage.tsx | 6 ++- src/components/ui/Image.tsx | 2 +- src/components/ui/Mermaid.tsx | 2 +- src/css/code.css | 2 +- src/markdown/index.ts | 56 +++++++++++++-------------- src/pages/_site/[site]/[page].tsx | 15 +------ 8 files changed, 59 insertions(+), 49 deletions(-) diff --git a/src/components/common/PageContent.tsx b/src/components/common/PageContent.tsx index 6c1fcc05..3aa4853c 100644 --- a/src/components/common/PageContent.tsx +++ b/src/components/common/PageContent.tsx @@ -2,7 +2,8 @@ import { cn } from "~/lib/utils" import { useCodeCopy } from "~/hooks/useCodeCopy" import { renderPageContent } from "~/markdown" import { PostToc } from "~/components/site/PostToc" -import { MutableRefObject, useMemo } from "react" +import { MutableRefObject, useEffect, useMemo } from "react" +import { scroller } from "react-scroll" export const PageContent: React.FC<{ content?: string @@ -34,6 +35,24 @@ export const PageContent: React.FC<{ } }, [content, parsedContent]) + useEffect(() => { + const hashChangeHandler = () => { + const hash = decodeURIComponent(location.hash.slice(1)) + if (hash) { + scroller.scrollTo(`user-content-${decodeURIComponent(hash)}`, { + smooth: true, + offset: -20, + duration: 500, + }) + } + } + + window.addEventListener("hashchange", hashChangeHandler) + return () => { + window.removeEventListener("hashchange", hashChangeHandler) + } + }, []) + return (
{child.type === "paragraph" && child.children?.[0]?.url && ( {page?.preview && ( -
+
{t( "This address is in local editing preview mode and cannot be viewed by the public.", )} @@ -61,7 +61,9 @@ export const SitePage: React.FC<{ {page?.title} )} - {page?.tags?.includes("post") && } + {page?.tags?.includes("post") && !page?.preview && ( + + )}
= ({ if (isMobileLayout !== undefined) { if (isMobileLayout) { const clickHandler = () => { - window.open(getSrc(), "_blank") + window.open(toGateway(getSrc()), "_blank") } $image.addEventListener("click", clickHandler) return () => { diff --git a/src/components/ui/Mermaid.tsx b/src/components/ui/Mermaid.tsx index bfb51cf5..fe84b716 100644 --- a/src/components/ui/Mermaid.tsx +++ b/src/components/ui/Mermaid.tsx @@ -49,7 +49,7 @@ export const Mermaid: FC<{ setLoading(false) }) } - }, [props.children]) + }, [props.children, isDark]) return loading ? (
diff --git a/src/css/code.css b/src/css/code.css index 0ebf3fb8..25ad463e 100644 --- a/src/css/code.css +++ b/src/css/code.css @@ -8,7 +8,7 @@ pre { } :not(pre) > code { - @apply inline-flex items-center font-mono break-all leading-snug px-1; + @apply inline font-mono break-all leading-snug p-1; background-color: var(--code-bg); color: var(--code-fg); } diff --git a/src/markdown/index.ts b/src/markdown/index.ts index d28df573..17d56cb9 100644 --- a/src/markdown/index.ts +++ b/src/markdown/index.ts @@ -112,6 +112,34 @@ export const renderPageContent = ( .use(rehypeRaw) .use(rehypeImage, { env }) .use(rehypeAudio) + .use(rehypeSlug) + .use(rehypeAutolinkHeadings, { + properties: { + className: ["xlog-anchor"], + ariaHidden: true, + tabIndex: -1, + }, + content(node) { + return [ + { + type: "element", + tagName: "span", + properties: { + className: ["i-mingcute:link-line"], + }, + children: [], + }, + { + type: "element", + tagName: "anchor", + properties: { + name: node.properties?.id, + }, + children: [], + }, + ] + }, + }) .use(rehypeSanitize, sanitizeScheme) .use(rehypePrism, { ignoreMissing: true, @@ -121,7 +149,6 @@ export const renderPageContent = ( .use(rehypeExternalLink) .use(rehypeWrapCode) .use(rehypeInferDescriptionMeta) - .use(rehypeSlug) .use(rehypeRewrite, { selector: "p, li", rewrite: (node: any) => { @@ -155,33 +182,6 @@ export const renderPageContent = ( } }, }) - .use(rehypeAutolinkHeadings, { - properties: { - className: ["xlog-anchor"], - ariaHidden: true, - tabIndex: -1, - }, - content(node) { - return [ - { - type: "element", - tagName: "span", - properties: { - className: ["i-mingcute:link-line"], - }, - children: [], - }, - { - type: "element", - tagName: "anchor", - properties: { - name: node.properties?.id, - }, - children: [], - }, - ] - }, - }) .use(html ? () => (tree: any) => {} : rehypeReact, { createElement: createElement, components: { diff --git a/src/pages/_site/[site]/[page].tsx b/src/pages/_site/[site]/[page].tsx index 267af2ec..b09ab056 100644 --- a/src/pages/_site/[site]/[page].tsx +++ b/src/pages/_site/[site]/[page].tsx @@ -1,8 +1,6 @@ import { QueryClient } from "@tanstack/react-query" import { GetServerSideProps } from "next" -import { useRouter } from "next/router" -import { ReactElement, useEffect } from "react" -import { scroller } from "react-scroll" +import { ReactElement } from "react" import { SiteLayout } from "~/components/site/SiteLayout" import { getServerSideProps as getLayoutServerSideProps } from "~/components/site/SiteLayout.server" import { SitePage } from "~/components/site/SitePage" @@ -48,17 +46,6 @@ function SitePagePage({ }) const site = useGetSite(domainOrSubdomain) - const { asPath } = useRouter() - useEffect(() => { - const [, hash] = asPath.split("#") - if (hash) { - scroller.scrollTo(decodeURIComponent(hash), { - smooth: true, - offset: -20, - }) - } - }, []) - return }