feat: add mermaid library and theme initialization

This commit is contained in:
kangfenmao 2024-11-09 14:46:35 +08:00
parent 68fa2bad15
commit af1fd90118
3 changed files with 55 additions and 32 deletions

View File

@ -1,7 +1,7 @@
import { useTheme } from '@renderer/context/ThemeProvider' import { useTheme } from '@renderer/context/ThemeProvider'
import { useMermaid } from '@renderer/hooks/useMermaid'
import { useSettings } from '@renderer/hooks/useSettings' import { useSettings } from '@renderer/hooks/useSettings'
import { CodeStyleVarious, ThemeMode } from '@renderer/types' import { CodeStyleVarious, ThemeMode } from '@renderer/types'
import { loadScript } from '@renderer/utils'
import React, { createContext, PropsWithChildren, useContext, useEffect, useMemo, useState } from 'react' import React, { createContext, PropsWithChildren, useContext, useEffect, useMemo, useState } from 'react'
import { import {
BundledLanguage, BundledLanguage,
@ -22,6 +22,7 @@ export const SyntaxHighlighterProvider: React.FC<PropsWithChildren> = ({ childre
const { theme } = useTheme() const { theme } = useTheme()
const [highlighter, setHighlighter] = useState<HighlighterGeneric<BundledLanguage, BundledTheme> | null>(null) const [highlighter, setHighlighter] = useState<HighlighterGeneric<BundledLanguage, BundledTheme> | null>(null)
const { codeStyle } = useSettings() const { codeStyle } = useSettings()
useMermaid()
const highlighterTheme = useMemo(() => { const highlighterTheme = useMemo(() => {
if (!codeStyle || codeStyle === 'auto') { if (!codeStyle || codeStyle === 'auto') {
@ -31,21 +32,6 @@ export const SyntaxHighlighterProvider: React.FC<PropsWithChildren> = ({ childre
return codeStyle return codeStyle
}, [theme, codeStyle]) }, [theme, codeStyle])
useEffect(() => {
const initMermaid = async () => {
if (!window.mermaid) {
await loadScript('https://unpkg.com/mermaid@11.4.0/dist/mermaid.min.js')
window.mermaid.initialize({
startOnLoad: false,
theme: theme === ThemeMode.dark ? 'dark' : 'default'
})
window.mermaid.contentLoaded()
}
}
initMermaid()
}, [theme])
useEffect(() => { useEffect(() => {
const initHighlighter = async () => { const initHighlighter = async () => {
const commonLanguages = ['javascript', 'typescript', 'python', 'java', 'markdown'] const commonLanguages = ['javascript', 'typescript', 'python', 'java', 'markdown']
@ -57,13 +43,9 @@ export const SyntaxHighlighterProvider: React.FC<PropsWithChildren> = ({ childre
setHighlighter(hl) setHighlighter(hl)
window.requestIdleCallback( // Load all themes and languages
() => { // hl.loadTheme(...(Object.keys(bundledThemes) as BundledTheme[]))
hl.loadTheme(...(Object.keys(bundledThemes) as BundledTheme[])) // hl.loadLanguage(...(Object.keys(bundledLanguages) as BundledLanguage[]))
hl.loadLanguage(...(Object.keys(bundledLanguages) as BundledLanguage[]))
},
{ timeout: 2000 }
)
} }
initHighlighter() initHighlighter()

View File

@ -0,0 +1,50 @@
import { useTheme } from '@renderer/context/ThemeProvider'
import { ThemeMode } from '@renderer/types'
import { loadScript, runAsyncFunction } from '@renderer/utils'
import { useEffect } from 'react'
import { useRuntime } from './useRuntime'
export const useMermaid = () => {
const { theme } = useTheme()
const { generating } = useRuntime()
useEffect(() => {
runAsyncFunction(async () => {
if (!window.mermaid) {
await loadScript('https://unpkg.com/mermaid@11.4.0/dist/mermaid.min.js')
window.mermaid.initialize({
startOnLoad: true,
theme: theme === ThemeMode.dark ? 'dark' : 'default'
})
window.mermaid.contentLoaded()
}
})
}, [])
useEffect(() => {
if (window.mermaid) {
window.mermaid.initialize({
startOnLoad: true,
theme: theme === ThemeMode.dark ? 'dark' : 'default'
})
window.mermaid.contentLoaded()
}
}, [theme])
useEffect(() => {
if (!window.mermaid || generating) return
const renderMermaid = () => {
const mermaidElements = document.querySelectorAll('.mermaid')
mermaidElements.forEach((element) => {
if (!element.querySelector('svg')) {
element.removeAttribute('data-processed')
}
})
window.mermaid.contentLoaded()
}
setTimeout(renderMermaid, 100)
}, [generating])
}

View File

@ -26,15 +26,6 @@ const runtimeSlice = createSlice({
}, },
setGenerating: (state, action: PayloadAction<boolean>) => { setGenerating: (state, action: PayloadAction<boolean>) => {
state.generating = action.payload state.generating = action.payload
if (!state.generating) {
const mermaidElements = document.querySelectorAll('.mermaid')
for (const element of mermaidElements) {
if (!element.querySelector('svg')) {
element.removeAttribute('data-processed')
}
}
setTimeout(() => window.mermaid.contentLoaded(), 100)
}
}, },
setMinappShow: (state, action: PayloadAction<boolean>) => { setMinappShow: (state, action: PayloadAction<boolean>) => {
state.minappShow = action.payload state.minappShow = action.payload