diff --git a/web/src/components/MemoContent/CodeBlock.tsx b/web/src/components/MemoContent/CodeBlock.tsx index 3165b010..4c550019 100644 --- a/web/src/components/MemoContent/CodeBlock.tsx +++ b/web/src/components/MemoContent/CodeBlock.tsx @@ -1,7 +1,11 @@ +import { Checkbox } from "@mui/joy"; import classNames from "classnames"; import copy from "copy-to-clipboard"; import hljs from "highlight.js"; +import { useCallback, useMemo, useState } from "react"; import toast from "react-hot-toast"; +import useResponsiveWidth from "@/hooks/useResponsiveWidth"; +import { useTranslate } from "@/utils/i18n"; import Icon from "../Icon"; import MermaidBlock from "./MermaidBlock"; import { BaseProps } from "./types"; @@ -18,7 +22,8 @@ interface Props extends BaseProps { } const CodeBlock: React.FC = ({ language, content }: Props) => { - const formatedLanguage = (language || "").toLowerCase() || "text"; + const formatedLanguage = useMemo(() => (language || "").toLowerCase() || "text", [language]); + // Users can set Markdown code blocks as `__html` to render HTML directly. if (formatedLanguage === SpecialLanguage.HTML) { return
; @@ -26,37 +31,57 @@ const CodeBlock: React.FC = ({ language, content }: Props) => { return ; } - let highlightedCode = content; - try { - const lang = hljs.getLanguage(formatedLanguage); - if (lang) { - const temp = hljs.highlight(content, { - language: formatedLanguage, - }).value; - highlightedCode = temp; - } - } catch (error) { - // Skip error and use default highlighted code. - } + const { md } = useResponsiveWidth(); + const t = useTranslate(); - const handleCopyButtonClick = () => { + const [wrap, setWrap] = useState(true); + const handleWrapChange = useCallback(() => setWrap(!wrap), [setWrap, wrap]); + + const highlightedCode: string = useMemo(() => { + try { + const lang = hljs.getLanguage(formatedLanguage); + if (lang) { + return hljs.highlight(content, { + language: formatedLanguage, + }).value; + } + } catch (error) { + // Skip error and use default highlighted code. + } + + return content; + }, [formatedLanguage, content]); + + const handleCopyButtonClick = useCallback(() => { copy(content); toast.success("Copied to clipboard!"); - }; + }, [content]); return ( -
+
{formatedLanguage} - + {md && }
-
-        
-      
+
+
+          
+        
+
+ {!md && ( +
+
+ +
+ +
+ )}
); }; diff --git a/web/src/locales/en.json b/web/src/locales/en.json index c5cf9350..fc80f145 100644 --- a/web/src/locales/en.json +++ b/web/src/locales/en.json @@ -105,7 +105,8 @@ "self": "Comments", "no-comment": "No comment" }, - "show-more": "Show more" + "show-more": "Show more", + "wrapping": "Wrapping" }, "reference": { "add-references": "Add references", diff --git a/web/src/locales/ru.json b/web/src/locales/ru.json index 44e364a5..2bb59b6c 100644 --- a/web/src/locales/ru.json +++ b/web/src/locales/ru.json @@ -122,7 +122,8 @@ "private": "Видно только вам", "protected": "Видно только пользователям", "public": "Видно всем" - } + }, + "wrapping": "Перенос" }, "message": { "change-memo-created-time": "Изменить время создания записи",