feat: add React Developer Tools extension support and optimize CodeBlock component
This commit is contained in:
parent
32e1f428e7
commit
750247aef8
@ -1,7 +1,7 @@
|
||||
import { electronApp, optimizer } from '@electron-toolkit/utils'
|
||||
import { replaceDevtoolsFont } from '@main/utils/windowUtil'
|
||||
import { app, ipcMain } from 'electron'
|
||||
import installExtension, { REDUX_DEVTOOLS } from 'electron-devtools-installer'
|
||||
import installExtension, { REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS } from 'electron-devtools-installer'
|
||||
|
||||
import { registerIpc } from './ipc'
|
||||
import { configManager } from './services/ConfigManager'
|
||||
@ -48,7 +48,7 @@ if (!app.requestSingleInstanceLock()) {
|
||||
replaceDevtoolsFont(mainWindow)
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
installExtension(REDUX_DEVTOOLS)
|
||||
installExtension([REDUX_DEVTOOLS, REACT_DEVELOPER_TOOLS])
|
||||
.then((name) => console.log(`Added Extension: ${name}`))
|
||||
.catch((err) => console.log('An error occurred: ', err))
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import {
|
||||
} from '@renderer/store/assistants'
|
||||
import { setDefaultModel, setTopicNamingModel, setTranslateModel } from '@renderer/store/llm'
|
||||
import { Assistant, AssistantSettings, Model, Topic } from '@renderer/types'
|
||||
import { useCallback } from 'react'
|
||||
|
||||
import { TopicManager } from './useTopic'
|
||||
|
||||
@ -69,7 +70,10 @@ export function useAssistant(id: string) {
|
||||
updateTopic: (topic: Topic) => dispatch(updateTopic({ assistantId: assistant.id, topic })),
|
||||
updateTopics: (topics: Topic[]) => dispatch(updateTopics({ assistantId: assistant.id, topics })),
|
||||
removeAllTopics: () => dispatch(removeAllTopics({ assistantId: assistant.id })),
|
||||
setModel: (model: Model) => dispatch(setModel({ assistantId: assistant.id, model })),
|
||||
setModel: useCallback(
|
||||
(model: Model) => dispatch(setModel({ assistantId: assistant.id, model })),
|
||||
[dispatch, assistant.id]
|
||||
),
|
||||
updateAssistant: (assistant: Assistant) => dispatch(updateAssistant(assistant)),
|
||||
updateAssistantSettings: (settings: Partial<AssistantSettings>) => {
|
||||
dispatch(updateAssistantSettings({ assistantId: assistant.id, settings }))
|
||||
|
||||
@ -37,12 +37,17 @@ const CodeBlock: React.FC<CodeBlockProps> = ({ children, className }) => {
|
||||
|
||||
const showDownloadButton = ['csv', 'json', 'txt', 'md'].includes(language)
|
||||
|
||||
const shouldShowExpandButtonRef = useRef(false)
|
||||
|
||||
useEffect(() => {
|
||||
const loadHighlightedCode = async () => {
|
||||
const highlightedHtml = await codeToHtml(children, language)
|
||||
if (codeContentRef.current) {
|
||||
codeContentRef.current.innerHTML = highlightedHtml
|
||||
setShouldShowExpandButton(codeContentRef.current.scrollHeight > 350)
|
||||
const isShowExpandButton = codeContentRef.current.scrollHeight > 350
|
||||
if (shouldShowExpandButtonRef.current === isShowExpandButton) return
|
||||
shouldShowExpandButtonRef.current = isShowExpandButton
|
||||
setShouldShowExpandButton(shouldShowExpandButtonRef.current)
|
||||
}
|
||||
}
|
||||
loadHighlightedCode()
|
||||
@ -98,15 +103,13 @@ const CodeBlock: React.FC<CodeBlockProps> = ({ children, className }) => {
|
||||
)}
|
||||
<CodeLanguage>{'<' + language.toUpperCase() + '>'}</CodeLanguage>
|
||||
</div>
|
||||
|
||||
</CodeHeader>
|
||||
<StickyWrapper>
|
||||
<HStack
|
||||
position="absolute"
|
||||
gap={12}
|
||||
alignItems="center"
|
||||
style={{ bottom: '0.2rem', right: '1rem', height: "27px" }}
|
||||
>
|
||||
style={{ bottom: '0.2rem', right: '1rem', height: '27px' }}>
|
||||
{showDownloadButton && <DownloadButton language={language} data={children} />}
|
||||
{codeWrappable && <UnwrapButton unwrapped={isUnwrapped} onClick={() => setIsUnwrapped(!isUnwrapped)} />}
|
||||
<CopyButton text={children} />
|
||||
|
||||
@ -7,7 +7,7 @@ import { useSettings } from '@renderer/hooks/useSettings'
|
||||
import type { Message } from '@renderer/types'
|
||||
import { escapeBrackets, removeSvgEmptyLines, withGeminiGrounding } from '@renderer/utils/formats'
|
||||
import { isEmpty } from 'lodash'
|
||||
import { type FC, useCallback, useMemo } from 'react'
|
||||
import { type FC, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import ReactMarkdown, { type Components } from 'react-markdown'
|
||||
import rehypeKatex from 'rehype-katex'
|
||||
@ -37,6 +37,8 @@ interface Props {
|
||||
>
|
||||
}
|
||||
|
||||
const remarkPlugins = [remarkMath, remarkGfm, remarkCjkFriendly]
|
||||
const disallowedElements = ['iframe']
|
||||
const Markdown: FC<Props> = ({ message, citationsData }) => {
|
||||
const { t } = useTranslation()
|
||||
const { renderInputMessageAsMarkdown, mathEngine } = useSettings()
|
||||
@ -55,7 +57,7 @@ const Markdown: FC<Props> = ({ message, citationsData }) => {
|
||||
return hasElements ? [rehypeRaw, rehypeMath] : [rehypeMath]
|
||||
}, [messageContent, rehypeMath])
|
||||
|
||||
const components = useCallback(() => {
|
||||
const components = useMemo(() => {
|
||||
const baseComponents = {
|
||||
a: (props: any) => {
|
||||
if (props.href && citationsData?.has(props.href)) {
|
||||
@ -65,15 +67,11 @@ const Markdown: FC<Props> = ({ message, citationsData }) => {
|
||||
},
|
||||
code: CodeBlock,
|
||||
img: ImagePreview,
|
||||
pre: (props: any) => <pre style={{ overflow: 'visible' }} {...props} />
|
||||
pre: (props: any) => <pre style={{ overflow: 'visible' }} {...props} />,
|
||||
style: MarkdownShadowDOMRenderer as any
|
||||
} as Partial<Components>
|
||||
|
||||
if (messageContent.includes('<style>')) {
|
||||
baseComponents.style = MarkdownShadowDOMRenderer as any
|
||||
}
|
||||
|
||||
return baseComponents
|
||||
}, [messageContent, citationsData])
|
||||
}, [citationsData])
|
||||
|
||||
if (message.role === 'user' && !renderInputMessageAsMarkdown) {
|
||||
return <p style={{ marginBottom: 5, whiteSpace: 'pre-wrap' }}>{messageContent}</p>
|
||||
@ -82,10 +80,10 @@ const Markdown: FC<Props> = ({ message, citationsData }) => {
|
||||
return (
|
||||
<ReactMarkdown
|
||||
rehypePlugins={rehypePlugins}
|
||||
remarkPlugins={[remarkMath, remarkGfm, remarkCjkFriendly]}
|
||||
remarkPlugins={remarkPlugins}
|
||||
className="markdown"
|
||||
components={components()}
|
||||
disallowedElements={['iframe']}
|
||||
components={components}
|
||||
disallowedElements={disallowedElements}
|
||||
remarkRehypeOptions={{
|
||||
footnoteLabel: t('common.footnotes'),
|
||||
footnoteLabelTagName: 'h4',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user