diff --git a/src/renderer/src/assets/styles/markdown.scss b/src/renderer/src/assets/styles/markdown.scss index aed4919e85..40c0255468 100644 --- a/src/renderer/src/assets/styles/markdown.scss +++ b/src/renderer/src/assets/styles/markdown.scss @@ -321,6 +321,7 @@ mjx-container { .cm-lineWrapping * { word-wrap: break-word; + white-space: pre-wrap; } } } diff --git a/src/renderer/src/assets/styles/scrollbar.scss b/src/renderer/src/assets/styles/scrollbar.scss index f25039f556..8e73054c38 100644 --- a/src/renderer/src/assets/styles/scrollbar.scss +++ b/src/renderer/src/assets/styles/scrollbar.scss @@ -18,7 +18,8 @@ body[theme-mode='light'] { height: 6px; } -::-webkit-scrollbar-track { +::-webkit-scrollbar-track, +::-webkit-scrollbar-corner { background: transparent; } @@ -30,7 +31,7 @@ body[theme-mode='light'] { } } -pre::-webkit-scrollbar-thumb { +pre:not(.shiki)::-webkit-scrollbar-thumb { border-radius: 0; background: rgba(0, 0, 0, 0.08); &:hover { diff --git a/src/renderer/src/components/CodeBlockView/CodePreview.tsx b/src/renderer/src/components/CodeBlockView/CodePreview.tsx index d17a146112..992af4f510 100644 --- a/src/renderer/src/components/CodeBlockView/CodePreview.tsx +++ b/src/renderer/src/components/CodeBlockView/CodePreview.tsx @@ -1,4 +1,4 @@ -import { TOOL_SPECS, useCodeToolbar } from '@renderer/components/CodeToolbar' +import { CodeTool, TOOL_SPECS, useCodeTool } from '@renderer/components/CodeToolbar' import { useCodeStyle } from '@renderer/context/CodeStyleProvider' import { useSettings } from '@renderer/hooks/useSettings' import { uuid } from '@renderer/utils' @@ -12,6 +12,7 @@ import styled from 'styled-components' interface CodePreviewProps { children: string language: string + setTools?: (value: React.SetStateAction) => void } /** @@ -20,7 +21,7 @@ interface CodePreviewProps { * - 通过 shiki tokenizer 处理流式响应 * - 为了正确执行语法高亮,必须保证流式响应都依次到达 tokenizer,不能跳过 */ -const CodePreview = ({ children, language }: CodePreviewProps) => { +const CodePreview = ({ children, language, setTools }: CodePreviewProps) => { const { codeShowLineNumbers, fontSize, codeCollapsible, codeWrappable } = useSettings() const { activeShikiTheme, highlightCodeChunk, cleanupTokenizers } = useCodeStyle() const [isExpanded, setIsExpanded] = useState(!codeCollapsible) @@ -35,7 +36,7 @@ const CodePreview = ({ children, language }: CodePreviewProps) => { const { t } = useTranslation() - const { registerTool, removeTool } = useCodeToolbar() + const { registerTool, removeTool } = useCodeTool(setTools) // 展开/折叠工具 useEffect(() => { @@ -171,14 +172,13 @@ const CodePreview = ({ children, language }: CodePreviewProps) => { ref={codeContentRef} $lineNumbers={codeShowLineNumbers} $wrap={codeWrappable && !isUnwrapped} + $fadeIn={hasHighlightedCode} style={{ fontSize: fontSize - 1, maxHeight: codeCollapsible && !isExpanded ? '350px' : 'none' }}> {hasHighlightedCode ? ( -
- -
+ ) : ( {children} )} @@ -229,26 +229,22 @@ const ShikiTokensRenderer: React.FC<{ language: string; tokenLines: ThemedToken[ const ContentContainer = styled.div<{ $lineNumbers: boolean $wrap: boolean + $fadeIn: boolean }>` + display: block; position: relative; overflow: auto; - display: flex; - flex-direction: column; border: 0.5px solid transparent; border-radius: 5px; margin-top: 0; - ::-webkit-scrollbar-thumb { - border-radius: 10px; - } - .shiki { + display: inline-block; + min-width: 100%; padding: 1em; code { - display: flex; - flex-direction: column; - width: 100%; + display: block; .line { display: block; @@ -256,7 +252,7 @@ const ContentContainer = styled.div<{ padding-left: ${(props) => (props.$lineNumbers ? '2rem' : '0')}; * { - word-wrap: ${(props) => (props.$wrap ? 'break-word' : undefined)}; + overflow-wrap: ${(props) => (props.$wrap ? 'break-word' : 'normal')}; white-space: ${(props) => (props.$wrap ? 'pre-wrap' : 'pre')}; } } @@ -292,18 +288,15 @@ const ContentContainer = styled.div<{ } } - .fade-in-effect { - animation: contentFadeIn 0.3s ease-in-out forwards; - } + animation: ${(props) => (props.$fadeIn ? 'contentFadeIn 0.3s ease-in-out forwards' : 'none')}; ` const CodePlaceholder = styled.div` + display: block; opacity: 0.1; - flex-direction: column; white-space: pre-wrap; word-break: break-all; overflow-x: hidden; - display: block; min-height: 1.3rem; ` diff --git a/src/renderer/src/components/CodeBlockView/MermaidPreview.tsx b/src/renderer/src/components/CodeBlockView/MermaidPreview.tsx index f02261c466..cf00802f6a 100644 --- a/src/renderer/src/components/CodeBlockView/MermaidPreview.tsx +++ b/src/renderer/src/components/CodeBlockView/MermaidPreview.tsx @@ -1,5 +1,5 @@ import { nanoid } from '@reduxjs/toolkit' -import { usePreviewToolHandlers, usePreviewTools } from '@renderer/components/CodeToolbar' +import { CodeTool, usePreviewToolHandlers, usePreviewTools } from '@renderer/components/CodeToolbar' import { useMermaid } from '@renderer/hooks/useMermaid' import { Flex } from 'antd' import React, { memo, startTransition, useCallback, useEffect, useRef, useState } from 'react' @@ -7,9 +7,10 @@ import styled from 'styled-components' interface Props { children: string + setTools?: (value: React.SetStateAction) => void } -const MermaidPreview: React.FC = ({ children }) => { +const MermaidPreview: React.FC = ({ children, setTools }) => { const { mermaid, isLoading, error: mermaidError } = useMermaid() const mermaidRef = useRef(null) const [error, setError] = useState(null) @@ -25,6 +26,7 @@ const MermaidPreview: React.FC = ({ children }) => { // 使用工具栏 usePreviewTools({ + setTools, handleZoom, handleCopyImage, handleDownload diff --git a/src/renderer/src/components/CodeBlockView/PlantUmlPreview.tsx b/src/renderer/src/components/CodeBlockView/PlantUmlPreview.tsx index 9af10a5aa7..35ef90e12e 100644 --- a/src/renderer/src/components/CodeBlockView/PlantUmlPreview.tsx +++ b/src/renderer/src/components/CodeBlockView/PlantUmlPreview.tsx @@ -1,5 +1,5 @@ import { LoadingOutlined } from '@ant-design/icons' -import { usePreviewToolHandlers, usePreviewTools } from '@renderer/components/CodeToolbar' +import { CodeTool, usePreviewToolHandlers, usePreviewTools } from '@renderer/components/CodeToolbar' import { Spin } from 'antd' import pako from 'pako' import React, { memo, useCallback, useRef, useState } from 'react' @@ -134,9 +134,10 @@ const PlantUMLServerImage: React.FC = ({ format, diagr interface PlantUMLProps { children: string + setTools?: (value: React.SetStateAction) => void } -const PlantUmlPreview: React.FC = ({ children }) => { +const PlantUmlPreview: React.FC = ({ children, setTools }) => { const { t } = useTranslation() const containerRef = useRef(null) @@ -165,6 +166,7 @@ const PlantUmlPreview: React.FC = ({ children }) => { // 使用工具栏 usePreviewTools({ + setTools, handleZoom, handleCopyImage, handleDownload: customDownload diff --git a/src/renderer/src/components/CodeBlockView/SvgPreview.tsx b/src/renderer/src/components/CodeBlockView/SvgPreview.tsx index 1e1f20b60e..f7b23b4faf 100644 --- a/src/renderer/src/components/CodeBlockView/SvgPreview.tsx +++ b/src/renderer/src/components/CodeBlockView/SvgPreview.tsx @@ -1,12 +1,13 @@ -import { usePreviewToolHandlers, usePreviewTools } from '@renderer/components/CodeToolbar' +import { CodeTool, usePreviewToolHandlers, usePreviewTools } from '@renderer/components/CodeToolbar' import { memo, useRef } from 'react' import styled from 'styled-components' interface Props { children: string + setTools?: (value: React.SetStateAction) => void } -const SvgPreview: React.FC = ({ children }) => { +const SvgPreview: React.FC = ({ children, setTools }) => { const svgContainerRef = useRef(null) // 使用通用图像工具 @@ -17,6 +18,7 @@ const SvgPreview: React.FC = ({ children }) => { // 使用工具栏 usePreviewTools({ + setTools, handleCopyImage, handleDownload }) diff --git a/src/renderer/src/components/CodeBlockView/index.tsx b/src/renderer/src/components/CodeBlockView/index.tsx index 19b8796d09..60a826a1a2 100644 --- a/src/renderer/src/components/CodeBlockView/index.tsx +++ b/src/renderer/src/components/CodeBlockView/index.tsx @@ -1,6 +1,6 @@ import { LoadingOutlined } from '@ant-design/icons' import CodeEditor from '@renderer/components/CodeEditor' -import { CodeToolbar, CodeToolContext, TOOL_SPECS, useCodeToolbar } from '@renderer/components/CodeToolbar' +import { CodeTool, CodeToolbar, TOOL_SPECS, useCodeTool } from '@renderer/components/CodeToolbar' import { useSettings } from '@renderer/hooks/useSettings' import { pyodideService } from '@renderer/services/PyodideService' import { extractTitle } from '@renderer/utils/formats' @@ -49,6 +49,9 @@ const CodeBlockView: React.FC = ({ children, language, onSave }) => { const [isRunning, setIsRunning] = useState(false) const [output, setOutput] = useState('') + const [tools, setTools] = useState([]) + const { registerTool, removeTool } = useCodeTool(setTools) + const isExecutable = useMemo(() => { return codeExecution.enabled && language === 'python' }, [codeExecution.enabled, language]) @@ -59,33 +62,17 @@ const CodeBlockView: React.FC = ({ children, language, onSave }) => { return hasSpecialView && viewMode === 'special' }, [hasSpecialView, viewMode]) - const { updateContext, registerTool, removeTool } = useCodeToolbar() + const handleCopySource = useCallback(() => { + navigator.clipboard.writeText(children) + window.message.success({ content: t('code_block.copy.success'), key: 'copy-code' }) + }, [children, t]) - useEffect(() => { - updateContext({ - code: children, - language - }) - }, [children, language, updateContext]) - - const handleCopySource = useCallback( - (ctx?: CodeToolContext) => { - if (!ctx) return - navigator.clipboard.writeText(ctx.code) - window.message.success({ content: t('code_block.copy.success'), key: 'copy-code' }) - }, - [t] - ) - - const handleDownloadSource = useCallback((ctx?: CodeToolContext) => { - if (!ctx) return - - const { code, language } = ctx + const handleDownloadSource = useCallback(() => { let fileName = '' // 尝试提取标题 - if (language === 'html' && code.includes('')) { - const title = extractTitle(code) + if (language === 'html' && children.includes('')) { + const title = extractTitle(children) if (title) { fileName = `${title}.html` } @@ -96,31 +83,26 @@ const CodeBlockView: React.FC = ({ children, language, onSave }) => { fileName = `${dayjs().format('YYYYMMDDHHmm')}.${language}` } - window.api.file.save(fileName, code) - }, []) + window.api.file.save(fileName, children) + }, [children, language]) - const handleRunScript = useCallback( - (ctx?: CodeToolContext) => { - if (!ctx) return + const handleRunScript = useCallback(() => { + setIsRunning(true) + setOutput('') - setIsRunning(true) - setOutput('') - - pyodideService - .runScript(ctx.code, {}, codeExecution.timeoutMinutes * 60000) - .then((formattedOutput) => { - setOutput(formattedOutput) - }) - .catch((error) => { - console.error('Unexpected error:', error) - setOutput(`Unexpected error: ${error.message || 'Unknown error'}`) - }) - .finally(() => { - setIsRunning(false) - }) - }, - [codeExecution.timeoutMinutes] - ) + pyodideService + .runScript(children, {}, codeExecution.timeoutMinutes * 60000) + .then((formattedOutput) => { + setOutput(formattedOutput) + }) + .catch((error) => { + console.error('Unexpected error:', error) + setOutput(`Unexpected error: ${error.message || 'Unknown error'}`) + }) + .finally(() => { + setIsRunning(false) + }) + }, [children, codeExecution.timeoutMinutes]) useEffect(() => { // 复制按钮 @@ -191,7 +173,7 @@ const CodeBlockView: React.FC = ({ children, language, onSave }) => { ...TOOL_SPECS.run, icon: isRunning ? : , tooltip: t('code_block.run'), - onClick: (ctx) => !isRunning && handleRunScript(ctx) + onClick: () => !isRunning && handleRunScript() }) return () => isExecutable && removeTool(TOOL_SPECS.run.id) @@ -200,20 +182,32 @@ const CodeBlockView: React.FC = ({ children, language, onSave }) => { // 源代码视图组件 const sourceView = useMemo(() => { if (codeEditor.enabled) { - return + return ( + + ) } else { - return {children} + return ( + + {children} + + ) } - }, [children, codeEditor.enabled, language, onSave]) + }, [children, codeEditor.enabled, language, onSave, setTools]) // 特殊视图组件映射 const specialView = useMemo(() => { if (language === 'mermaid') { - return {children} + return {children} } else if (language === 'plantuml' && isValidPlantUML(children)) { - return {children} + return {children} } else if (language === 'svg') { - return {children} + return {children} } return null }, [children, language]) @@ -246,7 +240,7 @@ const CodeBlockView: React.FC = ({ children, language, onSave }) => { return ( {renderHeader} - + {renderContent} {renderArtifacts} {isExecutable && output && {output}} @@ -255,10 +249,11 @@ const CodeBlockView: React.FC = ({ children, language, onSave }) => { } const CodeBlockWrapper = styled.div<{ $isInSpecialView: boolean }>` + /* FIXME: 在 bubble style 中撑开一些宽度*/ + min-width: min(calc(60vw - var(--sidebar-width)), 700px); position: relative; .code-toolbar { - margin-top: ${(props) => (props.$isInSpecialView ? '20px' : '0')}; background-color: ${(props) => (props.$isInSpecialView ? 'transparent' : 'var(--color-background-mute)')}; border-radius: ${(props) => (props.$isInSpecialView ? '0' : '4px')}; opacity: 0; @@ -279,13 +274,13 @@ const CodeBlockWrapper = styled.div<{ $isInSpecialView: boolean }>` const CodeHeader = styled.div<{ $isInSpecialView: boolean }>` display: flex; align-items: center; - justify-content: space-between; color: var(--color-text); font-size: 14px; font-weight: bold; padding: 0 10px; border-top-left-radius: 8px; border-top-right-radius: 8px; + margin-top: ${(props) => (props.$isInSpecialView ? '6px' : '0')}; height: ${(props) => (props.$isInSpecialView ? '16px' : '34px')}; ` diff --git a/src/renderer/src/components/CodeEditor/index.tsx b/src/renderer/src/components/CodeEditor/index.tsx index 6000e91b49..956a66b0f1 100644 --- a/src/renderer/src/components/CodeEditor/index.tsx +++ b/src/renderer/src/components/CodeEditor/index.tsx @@ -1,4 +1,4 @@ -import { TOOL_SPECS, useCodeToolbar } from '@renderer/components/CodeToolbar' +import { CodeTool, TOOL_SPECS, useCodeTool } from '@renderer/components/CodeToolbar' import { useCodeStyle } from '@renderer/context/CodeStyleProvider' import { useSettings } from '@renderer/hooks/useSettings' import CodeMirror, { Annotation, BasicSetupOptions, EditorView, Extension, keymap } from '@uiw/react-codemirror' @@ -25,6 +25,7 @@ interface Props { language: string onSave?: (newContent: string) => void onChange?: (newContent: string) => void + setTools?: (value: React.SetStateAction) => void minHeight?: string maxHeight?: string /** 用于覆写编辑器的某些设置 */ @@ -52,6 +53,7 @@ const CodeEditor = ({ language, onSave, onChange, + setTools, minHeight, maxHeight, options, @@ -88,7 +90,7 @@ const CodeEditor = ({ const langExtensions = useLanguageExtensions(language, options?.lint) - const { registerTool, removeTool } = useCodeToolbar() + const { registerTool, removeTool } = useCodeTool(setTools) // 展开/折叠工具 useEffect(() => { diff --git a/src/renderer/src/components/CodeToolbar/context.tsx b/src/renderer/src/components/CodeToolbar/context.tsx deleted file mode 100644 index 32be179d85..0000000000 --- a/src/renderer/src/components/CodeToolbar/context.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import React, { createContext, use, useCallback, useMemo, useState } from 'react' - -import { CodeTool, CodeToolContext } from './types' - -// 定义上下文默认值 -const defaultContext: CodeToolContext = { - code: '', - language: '' -} - -export interface CodeToolbarContextType { - tools: CodeTool[] - context: CodeToolContext - registerTool: (tool: CodeTool) => void - removeTool: (id: string) => void - updateContext: (newContext: Partial) => void -} - -const defaultCodeToolbarContext: CodeToolbarContextType = { - tools: [], - context: defaultContext, - registerTool: () => {}, - removeTool: () => {}, - updateContext: () => {} -} - -const CodeToolbarContext = createContext(defaultCodeToolbarContext) - -export const CodeToolbarProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { - const [tools, setTools] = useState([]) - const [context, setContext] = useState(defaultContext) - - // 注册工具,如果已存在同ID工具则替换 - const registerTool = useCallback((tool: CodeTool) => { - setTools((prev) => { - const filtered = prev.filter((t) => t.id !== tool.id) - return [...filtered, tool].sort((a, b) => b.order - a.order) - }) - }, []) - - // 移除工具 - const removeTool = useCallback((id: string) => { - setTools((prev) => prev.filter((tool) => tool.id !== id)) - }, []) - - // 更新上下文 - const updateContext = useCallback((newContext: Partial) => { - setContext((prev) => ({ ...prev, ...newContext })) - }, []) - - const value: CodeToolbarContextType = useMemo( - () => ({ - tools, - context, - registerTool, - removeTool, - updateContext - }), - [tools, context, registerTool, removeTool, updateContext] - ) - - return {children} -} - -export const useCodeToolbar = () => { - const context = use(CodeToolbarContext) - if (!context) { - throw new Error('useCodeToolbar must be used within a CodeToolbarProvider') - } - return context -} diff --git a/src/renderer/src/components/CodeToolbar/hook.ts b/src/renderer/src/components/CodeToolbar/hook.ts new file mode 100644 index 0000000000..5b5d6b338f --- /dev/null +++ b/src/renderer/src/components/CodeToolbar/hook.ts @@ -0,0 +1,26 @@ +import { useCallback } from 'react' + +import { CodeTool } from './types' + +export const useCodeTool = (setTools?: (value: React.SetStateAction) => void) => { + // 注册工具,如果已存在同ID工具则替换 + const registerTool = useCallback( + (tool: CodeTool) => { + setTools?.((prev) => { + const filtered = prev.filter((t) => t.id !== tool.id) + return [...filtered, tool].sort((a, b) => b.order - a.order) + }) + }, + [setTools] + ) + + // 移除工具 + const removeTool = useCallback( + (id: string) => { + setTools?.((prev) => prev.filter((tool) => tool.id !== id)) + }, + [setTools] + ) + + return { registerTool, removeTool } +} diff --git a/src/renderer/src/components/CodeToolbar/index.ts b/src/renderer/src/components/CodeToolbar/index.ts index 63d28e27f8..96434b97e9 100644 --- a/src/renderer/src/components/CodeToolbar/index.ts +++ b/src/renderer/src/components/CodeToolbar/index.ts @@ -1,5 +1,5 @@ export * from './constants' -export * from './context' +export * from './hook' export * from './toolbar' export * from './types' export * from './usePreviewTools' diff --git a/src/renderer/src/components/CodeToolbar/toolbar.tsx b/src/renderer/src/components/CodeToolbar/toolbar.tsx index 9a2f282bc3..cd615afcb4 100644 --- a/src/renderer/src/components/CodeToolbar/toolbar.tsx +++ b/src/renderer/src/components/CodeToolbar/toolbar.tsx @@ -5,7 +5,6 @@ import React, { memo, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' -import { useCodeToolbar } from './context' import { CodeTool } from './types' interface CodeToolButtonProps { @@ -13,22 +12,19 @@ interface CodeToolButtonProps { } const CodeToolButton: React.FC = memo(({ tool }) => { - const { context } = useCodeToolbar() - return ( - - tool.onClick(context)}>{tool.icon} + + tool.onClick()}>{tool.icon} ) }) -export const CodeToolbar: React.FC = memo(() => { - const { tools, context } = useCodeToolbar() +export const CodeToolbar: React.FC<{ tools: CodeTool[] }> = memo(({ tools }) => { const [showQuickTools, setShowQuickTools] = useState(false) const { t } = useTranslation() // 根据条件显示工具 - const visibleTools = tools.filter((tool) => !tool.visible || tool.visible(context)) + const visibleTools = tools.filter((tool) => !tool.visible || tool.visible()) // 按类型分组 const coreTools = visibleTools.filter((tool) => tool.type === 'core') diff --git a/src/renderer/src/components/CodeToolbar/types.ts b/src/renderer/src/components/CodeToolbar/types.ts index 83db869371..d1181650fe 100644 --- a/src/renderer/src/components/CodeToolbar/types.ts +++ b/src/renderer/src/components/CodeToolbar/types.ts @@ -20,16 +20,6 @@ export interface CodeToolSpec { export interface CodeTool extends CodeToolSpec { icon: React.ReactNode tooltip: string - visible?: (ctx?: CodeToolContext) => boolean - onClick: (ctx?: CodeToolContext) => void -} - -/** - * 工具上下文接口 - * @param code 代码内容 - * @param language 语言类型 - */ -export interface CodeToolContext { - code: string - language: string + visible?: () => boolean + onClick: () => void } diff --git a/src/renderer/src/components/CodeToolbar/usePreviewTools.tsx b/src/renderer/src/components/CodeToolbar/usePreviewTools.tsx index d1af8f49f2..f5ce914e44 100644 --- a/src/renderer/src/components/CodeToolbar/usePreviewTools.tsx +++ b/src/renderer/src/components/CodeToolbar/usePreviewTools.tsx @@ -5,7 +5,8 @@ import { useTranslation } from 'react-i18next' import { DownloadPngIcon, DownloadSvgIcon } from '../Icons/DownloadIcons' import { TOOL_SPECS } from './constants' -import { useCodeToolbar } from './context' +import { useCodeTool } from './hook' +import { CodeTool } from './types' // 预编译正则表达式用于查询位置 const TRANSFORM_REGEX = /translate\((-?\d+\.?\d*)px,\s*(-?\d+\.?\d*)px\)/ @@ -272,6 +273,7 @@ export const usePreviewToolHandlers = ( } export interface PreviewToolsOptions { + setTools?: (value: React.SetStateAction) => void handleZoom?: (delta: number) => void handleCopyImage?: () => Promise handleDownload?: (format: 'svg' | 'png') => void @@ -280,9 +282,9 @@ export interface PreviewToolsOptions { /** * 提供预览组件通用工具栏功能的自定义Hook */ -export const usePreviewTools = ({ handleZoom, handleCopyImage, handleDownload }: PreviewToolsOptions) => { +export const usePreviewTools = ({ setTools, handleZoom, handleCopyImage, handleDownload }: PreviewToolsOptions) => { const { t } = useTranslation() - const { registerTool, removeTool } = useCodeToolbar() + const { registerTool, removeTool } = useCodeTool(setTools) useEffect(() => { // 根据提供的功能有选择性地注册工具 diff --git a/src/renderer/src/pages/home/Markdown/CodeBlock.tsx b/src/renderer/src/pages/home/Markdown/CodeBlock.tsx index 2de19fe6c3..5692d50bf7 100644 --- a/src/renderer/src/pages/home/Markdown/CodeBlock.tsx +++ b/src/renderer/src/pages/home/Markdown/CodeBlock.tsx @@ -1,5 +1,4 @@ import CodeBlockView from '@renderer/components/CodeBlockView' -import { CodeToolbarProvider } from '@renderer/components/CodeToolbar' import React, { memo, useCallback } from 'react' interface Props { @@ -24,11 +23,9 @@ const CodeBlock: React.FC = ({ children, className, id, onSave }) => { ) return match ? ( - - - {children} - - + + {children} + ) : ( {children} diff --git a/src/renderer/src/pages/settings/MCPSettings/AddMcpServerModal.tsx b/src/renderer/src/pages/settings/MCPSettings/AddMcpServerModal.tsx index 33ec2f8868..c2202d3140 100644 --- a/src/renderer/src/pages/settings/MCPSettings/AddMcpServerModal.tsx +++ b/src/renderer/src/pages/settings/MCPSettings/AddMcpServerModal.tsx @@ -1,6 +1,5 @@ import { nanoid } from '@reduxjs/toolkit' import CodeEditor from '@renderer/components/CodeEditor' -import { CodeToolbarProvider } from '@renderer/components/CodeToolbar' import { useAppDispatch } from '@renderer/store' import { setMCPServerActive } from '@renderer/store/mcp' import { MCPServer } from '@renderer/types' @@ -157,25 +156,23 @@ const AddMcpServerModal: FC = ({ visible, onClose, onSuc name="serverConfig" label={t('settings.mcp.addServer.importFrom.tooltip')} rules={[{ required: true, message: t('settings.mcp.addServer.importFrom.placeholder') }]}> - - - + diff --git a/src/renderer/src/pages/settings/MCPSettings/EditMcpJsonPopup.tsx b/src/renderer/src/pages/settings/MCPSettings/EditMcpJsonPopup.tsx index 497b74639e..77ad41fb54 100644 --- a/src/renderer/src/pages/settings/MCPSettings/EditMcpJsonPopup.tsx +++ b/src/renderer/src/pages/settings/MCPSettings/EditMcpJsonPopup.tsx @@ -1,5 +1,4 @@ import CodeEditor from '@renderer/components/CodeEditor' -import { CodeToolbarProvider } from '@renderer/components/CodeToolbar' import { TopView } from '@renderer/components/TopView' import { useAppDispatch, useAppSelector } from '@renderer/store' import { setMCPServers } from '@renderer/store/mcp' @@ -121,23 +120,21 @@ const PopupContainer: React.FC = ({ resolve }) => { {jsonConfig && (
- - setJsonConfig(value)} - maxHeight="60vh" - options={{ - lint: true, - collapsible: true, - wrappable: true, - lineNumbers: true, - foldGutter: true, - highlightActiveLine: true, - keymap: true - }} - /> - + setJsonConfig(value)} + maxHeight="60vh" + options={{ + lint: true, + collapsible: true, + wrappable: true, + lineNumbers: true, + foldGutter: true, + highlightActiveLine: true, + keymap: true + }} + />
)} {t('settings.mcp.jsonModeHint')}