diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json
index bde091b0..929b1bee 100644
--- a/src/renderer/src/i18n/locales/en-us.json
+++ b/src/renderer/src/i18n/locales/en-us.json
@@ -113,6 +113,7 @@
"settings.set_as_default": "Apply to default assistant",
"settings.max": "Max",
"settings.show_line_numbers": "Show Line Numbers in Code",
+ "settings.code_collapsible": "Code block collapsible",
"suggestions.title": "Suggested Questions",
"add.assistant.title": "Add Assistant",
"message.new.context": "New Context",
diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json
index 114daee7..e5365ac4 100644
--- a/src/renderer/src/i18n/locales/ru-ru.json
+++ b/src/renderer/src/i18n/locales/ru-ru.json
@@ -113,6 +113,7 @@
"settings.set_as_default": "Применить к ассистенту по умолчанию",
"settings.max": "Максимум",
"settings.show_line_numbers": "Показать номера строк в коде",
+ "settings.code_collapsible": "Блок кода свернут",
"suggestions.title": "Предложенные вопросы",
"add.assistant.title": "Добавить ассистента",
"message.new.context": "Новый контекст",
diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json
index 86093ce2..f659903d 100644
--- a/src/renderer/src/i18n/locales/zh-cn.json
+++ b/src/renderer/src/i18n/locales/zh-cn.json
@@ -113,6 +113,7 @@
"settings.set_as_default": "应用到默认助手",
"settings.max": "不限",
"settings.show_line_numbers": "代码显示行号",
+ "settings.code_collapsible": "代码块可折叠",
"suggestions.title": "建议的问题",
"add.assistant.title": "添加助手",
"message.new.context": "清除上下文",
diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json
index d8c4486a..251ba9d9 100644
--- a/src/renderer/src/i18n/locales/zh-tw.json
+++ b/src/renderer/src/i18n/locales/zh-tw.json
@@ -113,6 +113,7 @@
"settings.set_as_default": "設為預設助手",
"settings.max": "最大",
"settings.show_line_numbers": "代码顯示行號",
+ "settings.code_collapsible": "代码块可折叠",
"suggestions.title": "建議的問題",
"add.assistant.title": "添加助手",
"message.new.context": "新上下文",
diff --git a/src/renderer/src/pages/home/Markdown/CodeBlock.tsx b/src/renderer/src/pages/home/Markdown/CodeBlock.tsx
index f35ebdb6..48984bcf 100644
--- a/src/renderer/src/pages/home/Markdown/CodeBlock.tsx
+++ b/src/renderer/src/pages/home/Markdown/CodeBlock.tsx
@@ -2,7 +2,7 @@ import { CheckOutlined, DownOutlined, RightOutlined } from '@ant-design/icons'
import CopyIcon from '@renderer/components/Icons/CopyIcon'
import { useSyntaxHighlighter } from '@renderer/context/SyntaxHighlighterProvider'
import { useSettings } from '@renderer/hooks/useSettings'
-import React, { memo, useEffect, useState } from 'react'
+import React, { memo, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@@ -16,10 +16,10 @@ interface CodeBlockProps {
}
const CollapseIcon: React.FC<{ expanded: boolean; onClick: () => void }> = ({ expanded, onClick }) => {
- return expanded ? (
-
- ) : (
-
+ return (
+
+ {expanded ? : }
+
)
}
@@ -31,28 +31,22 @@ const ExpandButton: React.FC<{
if (!showButton) return null
return (
-
- {isExpanded ? '收起' : '展开'}
-
+
+ {isExpanded ? '收起' : '展开'}
+
)
}
const CodeBlock: React.FC = ({ children, className }) => {
const match = /language-(\w+)/.exec(className || '')
const showFooterCopyButton = children && children.length > 500
- const { codeShowLineNumbers, fontSize } = useSettings()
+ const { codeShowLineNumbers, fontSize, codeCollapsible } = useSettings()
const language = match?.[1] ?? 'text'
const [html, setHtml] = useState('')
const { codeToHtml } = useSyntaxHighlighter()
- const [isExpanded, setIsExpanded] = useState(false)
+ const [isExpanded, setIsExpanded] = useState(!codeCollapsible)
+ const [shouldShowExpandButton, setShouldShowExpandButton] = useState(false)
+ const codeContentRef = useRef(null)
useEffect(() => {
const loadHighlightedCode = async () => {
@@ -62,6 +56,24 @@ const CodeBlock: React.FC = ({ children, className }) => {
loadHighlightedCode()
}, [children, language, codeToHtml])
+ useEffect(() => {
+ if (codeContentRef.current) {
+ setShouldShowExpandButton(codeContentRef.current.scrollHeight > 350)
+ }
+ }, [html])
+
+ useEffect(() => {
+ if (!codeCollapsible) {
+ setIsExpanded(true)
+ setShouldShowExpandButton(false)
+ } else {
+ setIsExpanded(!codeCollapsible)
+ if (codeContentRef.current) {
+ setShouldShowExpandButton(codeContentRef.current.scrollHeight > 350)
+ }
+ }
+ }, [codeCollapsible])
+
if (language === 'mermaid') {
return
}
@@ -70,12 +82,13 @@ const CodeBlock: React.FC = ({ children, className }) => {
- setIsExpanded(!isExpanded)} />
+ {codeCollapsible && setIsExpanded(!isExpanded)} />}
{'<' + match[1].toUpperCase() + '>'}
= ({ children, className }) => {
borderTopLeftRadius: 0,
borderTopRightRadius: 0,
marginTop: 0,
- fontSize,
- maxHeight: isExpanded ? 'none' : '300px',
- overflow: 'hidden',
+ fontSize: fontSize - 1,
+ maxHeight: codeCollapsible && !isExpanded ? '350px' : 'none',
+ overflow: codeCollapsible && !isExpanded ? 'auto' : 'visible',
position: 'relative'
}}
/>
- setIsExpanded(!isExpanded)}
- showButton={!isExpanded || showFooterCopyButton}
- />
+ {codeCollapsible && (
+ setIsExpanded(!isExpanded)}
+ showButton={shouldShowExpandButton}
+ />
+ )}
{showFooterCopyButton && (
@@ -189,4 +204,45 @@ const CodeFooter = styled.div`
}
`
+const ExpandButtonWrapper = styled.div`
+ position: relative;
+ cursor: pointer;
+ height: 30px;
+ margin-top: -30px;
+
+ .button-text {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ text-align: center;
+ padding: 8px;
+ color: var(--color-text-3);
+ z-index: 1;
+ transition: color 0.2s;
+ font-size: 12px;
+ }
+
+ &:hover .button-text {
+ color: var(--color-text-1);
+ }
+`
+
+const CollapseIconWrapper = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 20px;
+ height: 20px;
+ border-radius: 4px;
+ cursor: pointer;
+ color: var(--color-text-3);
+ transition: all 0.2s ease;
+
+ &:hover {
+ background-color: var(--color-background-soft);
+ color: var(--color-text-1);
+ }
+`
+
export default memo(CodeBlock)
diff --git a/src/renderer/src/pages/home/Tabs/Settings.tsx b/src/renderer/src/pages/home/Tabs/Settings.tsx
index 3fb8e04c..fd828dae 100644
--- a/src/renderer/src/pages/home/Tabs/Settings.tsx
+++ b/src/renderer/src/pages/home/Tabs/Settings.tsx
@@ -6,6 +6,7 @@ import { SettingDivider, SettingRow, SettingRowTitle, SettingSubtitle } from '@r
import { useAppDispatch } from '@renderer/store'
import {
setClickAssistantToShowTopic,
+ setCodeCollapsible,
setCodeShowLineNumbers,
setCodeStyle,
setFontSize,
@@ -39,6 +40,7 @@ const SettingsTab: FC = () => {
pasteLongTextAsFile,
renderInputMessageAsMarkdown,
codeShowLineNumbers,
+ codeCollapsible,
mathEngine,
topicPosition,
showTopicTime,
@@ -81,6 +83,11 @@ const SettingsTab: FC = () => {
/>
+
+ {t('chat.settings.code_collapsible')}
+ dispatch(setCodeCollapsible(checked))} />
+
+
{t('message.message.style')}