diff --git a/src/renderer/src/pages/home/Inputbar/AttachmentButton.tsx b/src/renderer/src/pages/home/Inputbar/AttachmentButton.tsx index 64e26488..5f130d58 100644 --- a/src/renderer/src/pages/home/Inputbar/AttachmentButton.tsx +++ b/src/renderer/src/pages/home/Inputbar/AttachmentButton.tsx @@ -3,7 +3,7 @@ import { isVisionModel } from '@renderer/config/models' import { FileType, Model } from '@renderer/types' import { documentExts, imageExts, textExts } from '@shared/config/constant' import { Tooltip } from 'antd' -import { FC, useCallback, useImperativeHandle } from 'react' +import { FC, useCallback, useImperativeHandle, useMemo } from 'react' import { useTranslation } from 'react-i18next' export interface AttachmentButtonRef { @@ -21,9 +21,11 @@ interface Props { const AttachmentButton: FC = ({ ref, model, files, setFiles, ToolbarButton, disabled }) => { const { t } = useTranslation() - const extensions = isVisionModel(model) - ? [...imageExts, ...documentExts, ...textExts] - : [...documentExts, ...textExts] + + const extensions = useMemo( + () => (isVisionModel(model) ? [...imageExts, ...documentExts, ...textExts] : [...documentExts, ...textExts]), + [model] + ) const onSelectFile = useCallback(async () => { const _files = await window.api.file.select({ @@ -39,7 +41,7 @@ const AttachmentButton: FC = ({ ref, model, files, setFiles, ToolbarButto if (_files) { setFiles([...files, ..._files]) } - }, [files, setFiles]) + }, [extensions, files, setFiles]) const openQuickPanel = useCallback(() => { onSelectFile() diff --git a/src/renderer/src/pages/home/Markdown/Markdown.tsx b/src/renderer/src/pages/home/Markdown/Markdown.tsx index 9f33760b..e21a8447 100644 --- a/src/renderer/src/pages/home/Markdown/Markdown.tsx +++ b/src/renderer/src/pages/home/Markdown/Markdown.tsx @@ -5,7 +5,9 @@ import 'katex/dist/contrib/mhchem' import MarkdownShadowDOMRenderer from '@renderer/components/MarkdownShadowDOMRenderer' import { useSettings } from '@renderer/hooks/useSettings' import type { Message } from '@renderer/types' +import { parseJSON } from '@renderer/utils' import { escapeBrackets, removeSvgEmptyLines, withGeminiGrounding } from '@renderer/utils/formats' +import { findCitationInChildren } from '@renderer/utils/markdown' import { isEmpty } from 'lodash' import { type FC, useMemo } from 'react' import { useTranslation } from 'react-i18next' @@ -51,44 +53,13 @@ const Markdown: FC = ({ message }) => { const components = useMemo(() => { const baseComponents = { - a: (props: any) => { - // 更彻底的查找方法,递归搜索所有子元素 - const findCitationInChildren = (children) => { - if (!children) return null - - // 直接搜索子元素 - for (const child of Array.isArray(children) ? children : [children]) { - if (typeof child === 'object' && child?.props?.['data-citation']) { - return child.props['data-citation'] - } - - // 递归查找更深层次 - if (typeof child === 'object' && child?.props?.children) { - const found = findCitationInChildren(child.props.children) - if (found) return found - } - } - - return null - } - - // 然后在组件中使用 - const citationData = findCitationInChildren(props.children) - if (citationData) { - try { - return - } catch (e) { - console.error('Failed to parse citation data', e) - } - } - return - }, + a: (props: any) => , code: CodeBlock, img: ImagePreview, pre: (props: any) =>
     } as Partial
     return baseComponents
-  }, [messageContent])
+  }, [])
 
   if (message.role === 'user' && !renderInputMessageAsMarkdown) {
     return 

{messageContent}

diff --git a/src/renderer/src/pages/home/Tabs/TopicsTab.tsx b/src/renderer/src/pages/home/Tabs/TopicsTab.tsx index b259890d..8ff853e1 100644 --- a/src/renderer/src/pages/home/Tabs/TopicsTab.tsx +++ b/src/renderer/src/pages/home/Tabs/TopicsTab.tsx @@ -367,7 +367,27 @@ const Topics: FC = ({ assistant: _assistant, activeTopic, setActiveTopic return menus }, - [assistant, assistants, onClearMessages, onDeleteTopic, onPinTopic, onMoveTopic, t, updateTopic, exportMenuOptions] + [ + activeTopic.id, + assistant, + assistants, + exportMenuOptions.docx, + exportMenuOptions.image, + exportMenuOptions.joplin, + exportMenuOptions.markdown, + exportMenuOptions.markdown_reason, + exportMenuOptions.notion, + exportMenuOptions.obsidian, + exportMenuOptions.siyuan, + exportMenuOptions.yuque, + onClearMessages, + onDeleteTopic, + onMoveTopic, + onPinTopic, + setActiveTopic, + t, + updateTopic + ] ) return ( diff --git a/src/renderer/src/utils/markdown.ts b/src/renderer/src/utils/markdown.ts new file mode 100644 index 00000000..1eccd0ab --- /dev/null +++ b/src/renderer/src/utils/markdown.ts @@ -0,0 +1,19 @@ +// 更彻底的查找方法,递归搜索所有子元素 +export const findCitationInChildren = (children) => { + if (!children) return null + + // 直接搜索子元素 + for (const child of Array.isArray(children) ? children : [children]) { + if (typeof child === 'object' && child?.props?.['data-citation']) { + return child.props['data-citation'] + } + + // 递归查找更深层次 + if (typeof child === 'object' && child?.props?.children) { + const found = findCitationInChildren(child.props.children) + if (found) return found + } + } + + return null +}