mirror of
https://github.com/usememos/memos.git
synced 2025-12-17 14:19:17 +08:00
fix(web): make MermaidBlock reactive to system theme changes and improve code quality
- Add system theme listener to detect OS theme changes in real-time - Refactor to eliminate duplicate theme preference extraction - Simplify getMermaidTheme function from switch statement to ternary - Move render guard outside async function for better readability - Update comments to be more concise and focused The component now properly re-renders Mermaid diagrams when the OS theme changes while using "system" theme preference. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
fb736c20d3
commit
fa3e0fc7f9
1 changed files with 25 additions and 31 deletions
|
|
@ -3,7 +3,7 @@ import { observer } from "mobx-react-lite";
|
|||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { instanceStore, userStore } from "@/store";
|
||||
import { resolveTheme } from "@/utils/theme";
|
||||
import { resolveTheme, setupSystemThemeListener } from "@/utils/theme";
|
||||
|
||||
interface MermaidBlockProps {
|
||||
children?: React.ReactNode;
|
||||
|
|
@ -12,54 +12,49 @@ interface MermaidBlockProps {
|
|||
|
||||
/**
|
||||
* Maps app theme to Mermaid theme
|
||||
* @param appTheme - The resolved app theme
|
||||
* @returns Mermaid theme name
|
||||
*/
|
||||
const getMermaidTheme = (appTheme: string): "default" | "dark" => {
|
||||
switch (appTheme) {
|
||||
case "default-dark":
|
||||
return "dark";
|
||||
case "default":
|
||||
case "paper":
|
||||
case "whitewall":
|
||||
default:
|
||||
return "default";
|
||||
}
|
||||
return appTheme === "default-dark" ? "dark" : "default";
|
||||
};
|
||||
|
||||
export const MermaidBlock = observer(({ children, className }: MermaidBlockProps) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [svg, setSvg] = useState<string>("");
|
||||
const [error, setError] = useState<string>("");
|
||||
const [systemThemeChange, setSystemThemeChange] = useState(0);
|
||||
|
||||
// Extract the code element and its content
|
||||
// Extract Mermaid code content from children
|
||||
const codeElement = children as React.ReactElement;
|
||||
const codeContent = String(codeElement?.props?.children || "").replace(/\n$/, "");
|
||||
|
||||
// Get current theme from store (reactive via MobX observer)
|
||||
// This will automatically trigger re-render when theme changes
|
||||
const currentTheme = useMemo(() => {
|
||||
const userTheme = userStore.state.userGeneralSetting?.theme;
|
||||
const instanceTheme = instanceStore.state.theme;
|
||||
const theme = userTheme || instanceTheme;
|
||||
return resolveTheme(theme);
|
||||
}, [userStore.state.userGeneralSetting?.theme, instanceStore.state.theme]);
|
||||
// Get theme preference (reactive via MobX observer)
|
||||
const themePreference = userStore.state.userGeneralSetting?.theme || instanceStore.state.theme;
|
||||
|
||||
// Render diagram when content or theme changes
|
||||
// Resolve theme to actual value (handles "system" theme + system theme changes)
|
||||
const currentTheme = useMemo(() => resolveTheme(themePreference), [themePreference, systemThemeChange]);
|
||||
|
||||
// Listen for OS theme changes when using "system" theme preference
|
||||
useEffect(() => {
|
||||
if (themePreference !== "system") {
|
||||
return;
|
||||
}
|
||||
|
||||
return setupSystemThemeListener(() => {
|
||||
setSystemThemeChange((prev) => prev + 1);
|
||||
});
|
||||
}, [themePreference]);
|
||||
|
||||
// Render Mermaid diagram when content or theme changes
|
||||
useEffect(() => {
|
||||
if (!codeContent || !containerRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
const renderDiagram = async () => {
|
||||
if (!codeContent || !containerRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Generate a unique ID for this diagram
|
||||
const id = `mermaid-${Math.random().toString(36).substring(7)}`;
|
||||
|
||||
// Get the appropriate Mermaid theme for current app theme
|
||||
const mermaidTheme = getMermaidTheme(currentTheme);
|
||||
|
||||
// Initialize mermaid with current theme
|
||||
mermaid.initialize({
|
||||
startOnLoad: false,
|
||||
theme: mermaidTheme,
|
||||
|
|
@ -67,7 +62,6 @@ export const MermaidBlock = observer(({ children, className }: MermaidBlockProps
|
|||
fontFamily: "inherit",
|
||||
});
|
||||
|
||||
// Render the mermaid diagram
|
||||
const { svg: renderedSvg } = await mermaid.render(id, codeContent);
|
||||
setSvg(renderedSvg);
|
||||
setError("");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue