From 2a8cb58a82a5a4238fa36520f6fd112d9a3faaaf Mon Sep 17 00:00:00 2001 From: q <787025321@qq.com> Date: Thu, 7 Aug 2025 15:29:06 +0800 Subject: [PATCH] feat: add copy page functions --- i18n/en/code.json | 24 ++++ i18n/zh/code.json | 24 ++++ src/components/CopyPageButton/index.tsx | 117 ++++++++++++++++++ .../CopyPageButton/styles.module.scss | 18 +++ src/css/markdown.scss | 1 - src/theme/DocItem/Content/index.tsx | 48 +++++++ src/theme/DocItem/Content/styles.module.css | 15 +++ .../DocRoot/Layout/Main/styles.module.css | 1 - static/icons/copied.svg | 1 + static/icons/copy.svg | 1 + static/icons/down.svg | 1 + static/icons/markdown.svg | 1 + 12 files changed, 250 insertions(+), 2 deletions(-) create mode 100644 src/components/CopyPageButton/index.tsx create mode 100644 src/components/CopyPageButton/styles.module.scss create mode 100644 src/theme/DocItem/Content/index.tsx create mode 100644 src/theme/DocItem/Content/styles.module.css create mode 100644 static/icons/copied.svg create mode 100644 static/icons/copy.svg create mode 100644 static/icons/down.svg create mode 100644 static/icons/markdown.svg diff --git a/i18n/en/code.json b/i18n/en/code.json index de4dd2f009..cbf0cef42d 100644 --- a/i18n/en/code.json +++ b/i18n/en/code.json @@ -780,5 +780,29 @@ "Enterprise Features & Licensing": { "message": "Enterprise Features & Licensing", "description": "Enterprise Features & Licensing" + }, + "Copy Page": { + "message": "Copy Page", + "description": "Copy Page" + }, + "Copy page as Markdown for LLMs": { + "message": "Copy page as Markdown for LLMs", + "description": "Copy page as Markdown for LLMs" + }, + "View as Markdown": { + "message": "View as Markdown", + "description": "View as Markdown" + }, + "View this page as plain text": { + "message": "View this page as plain text", + "description": "View this page as plain text" + }, + "Failed to copy markdown": { + "message": "Failed to copy markdown", + "description": "Failed to copy markdown" + }, + "Copying...": { + "message": "Copying...", + "description": "Copying..." } } diff --git a/i18n/zh/code.json b/i18n/zh/code.json index ff69649140..784e0e3318 100644 --- a/i18n/zh/code.json +++ b/i18n/zh/code.json @@ -804,5 +804,29 @@ "Enterprise Features & Licensing": { "message": "企业功能与许可", "description": "Enterprise Features & Licensing" + }, + "Copy Page": { + "message": "复制页面", + "description": "Copy Page" + }, + "Copy page as Markdown for LLMs": { + "message": "复制为 Markdown 格式,供大语言模型使用", + "description": "Copy page as Markdown for LLMs" + }, + "View as Markdown": { + "message": "查看 Markdown 格式", + "description": "View as Markdown" + }, + "View this page as plain text": { + "message": "查看纯文本", + "description": "View this page as plain text" + }, + "Failed to copy markdown": { + "message": "无法复制 Markdown", + "description": "Failed to copy markdown" + }, + "Copying...": { + "message": "正在复制...", + "description": "Copying..." } } diff --git a/src/components/CopyPageButton/index.tsx b/src/components/CopyPageButton/index.tsx new file mode 100644 index 0000000000..ef8805d75f --- /dev/null +++ b/src/components/CopyPageButton/index.tsx @@ -0,0 +1,117 @@ +import React, { useState, useMemo, useCallback } from "react"; +import { Button, Dropdown, Flex, Spin } from "antd"; +import styles from "./styles.module.scss"; +import DownArrow from "@site/static/icons/down.svg"; +import MarkdownSvg from "@site/static/icons/markdown.svg"; +import CopySvg from "@site/static/icons/copy.svg"; +import CopiedSvg from "@site/static/icons/copied.svg"; +import { useDoc } from "@docusaurus/plugin-content-docs/client"; +import axios from "axios"; +import $t from "@site/src/utils/tools"; +// mark +// import TurndownService from "turndown"; +// const turndownService = new TurndownService(); +// const getPageContentAsHtml = (): string | null => { +// const contentElement = document.querySelector("article"); +// return contentElement ? contentElement.innerHTML : null; +// }; + +// const convertHtmlToMarkdown = (html: string): string => { +// return turndownService.turndown(html); +// }; +const CopyDropdownButton: React.FC = () => { + const [loading, setLoading] = useState(false); + const [isCopied, setIsCopied] = useState(false); + const { metadata } = useDoc(); + const sourceUrl = useMemo(() => { + return ( + metadata?.source?.replace( + "@site", + "https://raw.githubusercontent.com/databendlabs/databend-docs/refs/heads/main" + ) || "" + ); + }, [metadata]); + const handleCopy = useCallback((url: string) => { + if (!url) return; + setLoading(true); + axios + .get(url) + .then((response) => { + setIsCopied(true); + if (response.status === 200) { + navigator.clipboard.writeText(response.data); + } else { + alert($t("Failed to copy markdown")); + } + }) + .finally(() => { + setLoading(false); + setTimeout(() => { + setIsCopied(false); + }, 3000); + }); + }, []); + const menu = useMemo(() => { + const items = [ + { + key: "copy", + icon: , + label: $t("Copy Page"), + description: $t("Copy page as Markdown for LLMs"), + }, + { + key: "markdown", + icon: , + label: $t("View as Markdown"), + description: $t("View this page as plain text"), + }, + ]; + + return { + items: items.map(({ key, icon, label, description }) => ({ + key, + label: ( +
+
{label}
+
{description}
+
+ ), + icon: