48670ff0c8
* optimize useMessageOperations * chore: update dependencies and refactor React imports - Added @ant-design/v5-patch-for-react-19 and rc-virtual-list to package.json. - Updated React and ReactDOM types to version 19 in package.json and yarn.lock. - Refactored ReactDOM usage to createRoot in main.tsx for better compatibility with React 18+. - Changed useContext to use in SyntaxHighlighterProvider and ThemeProvider components. - Adjusted flex-direction in Messages components to column for improved layout. - Removed unused state in CodeBlock component. * refactor(Messages): enhance scrolling behavior and introduce scroll utilities - Added createScrollHandler and scrollToBottom utilities for improved scroll management. - Updated Messages component to utilize new scroll utilities for better user experience. - Refactored scroll handling logic to ensure smooth scrolling when new messages are added. - Changed containerRef type to HTMLElement for better type safety. * refactor(Messages): streamline message handling and introduce useTopicMessages hook - Removed direct message selection from useMessageOperations and created a new useTopicMessages hook for better separation of concerns. - Updated Messages component to utilize the new useTopicMessages hook for fetching messages. - Enhanced message display logic with computeDisplayMessages function for improved message rendering. - Refactored scrolling behavior to maintain a smooth user experience during message updates. * refactor(Message Operations): introduce useTopicLoading hook for improved loading state management - Removed loading state from useMessageOperations and created a new useTopicLoading hook for better separation of concerns. - Updated components to utilize the new useTopicLoading hook for fetching loading states related to topics. - Enhanced code organization and readability by streamlining message operations and loading state handling. * refactor(Messages): replace updateMessage with updateMessageThunk for improved async handling - Updated useMessageOperations and MessageAnchorLine components to utilize updateMessageThunk for message updates. - Enhanced error handling and database synchronization in the new thunk implementation. - Streamlined message update logic to improve code clarity and maintainability. * refactor(SyntaxHighlighterProvider, MessageTools, AddMcpServerPopup): update styles and improve type safety - Changed import statements to use TypeScript's type imports for better clarity and type safety. - Updated MessageTools and AddMcpServerPopup components to replace bodyStyle with styles prop for consistent styling approach. - Enhanced overall code organization and maintainability by adhering to TypeScript best practices. * refactor(Messages): update layout and remove unnecessary prop - Removed the hasChildren prop from the Messages component for cleaner code. - Adjusted flex-direction in the mini chat Messages component to column-reverse for improved layout consistency. * refactor: enhance type safety and component return types - Updated functional components to return React.ReactElement instead of JSX.Element for better type consistency. - Changed import statements to use TypeScript's type imports for improved clarity. - Initialized useRef hooks with null for better type safety in various components. - Adjusted props types to use HTMLAttributes for more accurate type definitions. * chore: update package dependencies - Removed outdated dependencies: @agentic/exa, @agentic/searxng, @agentic/tavily, and rc-virtual-list. - Added back @ant-design/v5-patch-for-react-19 and rc-virtual-list with specified versions for improved compatibility. * fix(useMessageOperations): ensure message retrieval from store when updating content
97 lines
3.4 KiB
TypeScript
97 lines
3.4 KiB
TypeScript
import { useTheme } from '@renderer/context/ThemeProvider'
|
|
import { useMermaid } from '@renderer/hooks/useMermaid'
|
|
import { useSettings } from '@renderer/hooks/useSettings'
|
|
import { type CodeStyleVarious, ThemeMode } from '@renderer/types'
|
|
import type React from 'react'
|
|
import { createContext, type PropsWithChildren, use, useCallback, useEffect, useMemo, useState } from 'react'
|
|
import type { BundledLanguage, BundledTheme, HighlighterGeneric } from 'shiki'
|
|
import { bundledLanguages, bundledThemes, createHighlighter } from 'shiki'
|
|
|
|
interface SyntaxHighlighterContextType {
|
|
codeToHtml: (code: string, language: string) => Promise<string>
|
|
}
|
|
|
|
const SyntaxHighlighterContext = createContext<SyntaxHighlighterContextType | undefined>(undefined)
|
|
|
|
export const SyntaxHighlighterProvider: React.FC<PropsWithChildren> = ({ children }) => {
|
|
const { theme } = useTheme()
|
|
const [highlighter, setHighlighter] = useState<HighlighterGeneric<BundledLanguage, BundledTheme> | null>(null)
|
|
const { codeStyle } = useSettings()
|
|
useMermaid()
|
|
|
|
const highlighterTheme = useMemo(() => {
|
|
if (!codeStyle || codeStyle === 'auto') {
|
|
return theme === ThemeMode.light ? 'one-light' : 'material-theme-darker'
|
|
}
|
|
|
|
return codeStyle
|
|
}, [theme, codeStyle])
|
|
|
|
useEffect(() => {
|
|
const initHighlighter = async () => {
|
|
const commonLanguages = ['javascript', 'typescript', 'python', 'java', 'markdown']
|
|
|
|
const hl = await createHighlighter({
|
|
themes: [highlighterTheme],
|
|
langs: commonLanguages
|
|
})
|
|
|
|
setHighlighter(hl)
|
|
|
|
// Load all themes and languages
|
|
// hl.loadTheme(...(Object.keys(bundledThemes) as BundledTheme[]))
|
|
// hl.loadLanguage(...(Object.keys(bundledLanguages) as BundledLanguage[]))
|
|
}
|
|
|
|
initHighlighter()
|
|
}, [highlighterTheme])
|
|
|
|
const codeToHtml = useCallback(
|
|
async (_code: string, language: string) => {
|
|
{
|
|
if (!highlighter) return ''
|
|
|
|
const languageMap: Record<string, string> = {
|
|
vab: 'vb'
|
|
}
|
|
|
|
const mappedLanguage = languageMap[language] || language
|
|
|
|
const code = _code?.trimEnd() ?? ''
|
|
const escapedCode = code?.replace(/[<>]/g, (char) => ({ '<': '<', '>': '>' })[char]!)
|
|
|
|
try {
|
|
if (!highlighter.getLoadedLanguages().includes(mappedLanguage as BundledLanguage)) {
|
|
if (mappedLanguage in bundledLanguages || mappedLanguage === 'text') {
|
|
await highlighter.loadLanguage(mappedLanguage as BundledLanguage)
|
|
} else {
|
|
return `<pre style="padding: 10px"><code>${escapedCode}</code></pre>`
|
|
}
|
|
}
|
|
|
|
return highlighter.codeToHtml(code, {
|
|
lang: mappedLanguage,
|
|
theme: highlighterTheme
|
|
})
|
|
} catch (error) {
|
|
console.warn(`Error highlighting code for language '${mappedLanguage}':`, error)
|
|
return `<pre style="padding: 10px"><code>${escapedCode}</code></pre>`
|
|
}
|
|
}
|
|
},
|
|
[highlighter, highlighterTheme]
|
|
)
|
|
|
|
return <SyntaxHighlighterContext.Provider value={{ codeToHtml }}>{children}</SyntaxHighlighterContext.Provider>
|
|
}
|
|
|
|
export const useSyntaxHighlighter = () => {
|
|
const context = use(SyntaxHighlighterContext)
|
|
if (!context) {
|
|
throw new Error('useSyntaxHighlighter must be used within a SyntaxHighlighterProvider')
|
|
}
|
|
return context
|
|
}
|
|
|
|
export const codeThemes = ['auto', ...Object.keys(bundledThemes)] as CodeStyleVarious[]
|