mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-03 02:59:07 +08:00
refactor(MessageEditor): improve editor style (#8387)
This commit is contained in:
parent
e688b2959c
commit
eebed6d399
@ -15,7 +15,7 @@ import { getFilesFromDropEvent, isSendMessageKeyPressed } from '@renderer/utils/
|
|||||||
import { createFileBlock, createImageBlock } from '@renderer/utils/messageUtils/create'
|
import { createFileBlock, createImageBlock } from '@renderer/utils/messageUtils/create'
|
||||||
import { findAllBlocks } from '@renderer/utils/messageUtils/find'
|
import { findAllBlocks } from '@renderer/utils/messageUtils/find'
|
||||||
import { documentExts, imageExts, textExts } from '@shared/config/constant'
|
import { documentExts, imageExts, textExts } from '@shared/config/constant'
|
||||||
import { Tooltip } from 'antd'
|
import { Space, Tooltip } from 'antd'
|
||||||
import TextArea, { TextAreaRef } from 'antd/es/input/TextArea'
|
import TextArea, { TextAreaRef } from 'antd/es/input/TextArea'
|
||||||
import { Save, Send, X } from 'lucide-react'
|
import { Save, Send, X } from 'lucide-react'
|
||||||
import { FC, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { FC, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
@ -96,22 +96,13 @@ const MessageBlockEditor: FC<Props> = ({ message, topicId, onSave, onResend, onC
|
|||||||
}
|
}
|
||||||
}, [couldAddImageFile, couldAddTextFile])
|
}, [couldAddImageFile, couldAddTextFile])
|
||||||
|
|
||||||
const resizeTextArea = useCallback(() => {
|
|
||||||
const textArea = textareaRef.current?.resizableTextArea?.textArea
|
|
||||||
if (textArea) {
|
|
||||||
textArea.style.height = 'auto'
|
|
||||||
textArea.style.height = textArea?.scrollHeight > 400 ? '400px' : `${textArea?.scrollHeight}px`
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
resizeTextArea()
|
|
||||||
if (textareaRef.current) {
|
if (textareaRef.current) {
|
||||||
textareaRef.current.focus({ cursor: 'end' })
|
textareaRef.current.focus({ cursor: 'end' })
|
||||||
}
|
}
|
||||||
}, 0)
|
}, 0)
|
||||||
}, [resizeTextArea])
|
}, [])
|
||||||
|
|
||||||
const onPaste = useCallback(
|
const onPaste = useCallback(
|
||||||
async (event: ClipboardEvent) => {
|
async (event: ClipboardEvent) => {
|
||||||
@ -123,11 +114,11 @@ const MessageBlockEditor: FC<Props> = ({ message, topicId, onSave, onResend, onC
|
|||||||
false, // 不需要 pasteLongTextAsFile
|
false, // 不需要 pasteLongTextAsFile
|
||||||
pasteLongTextThreshold,
|
pasteLongTextThreshold,
|
||||||
undefined, // 不需要text
|
undefined, // 不需要text
|
||||||
resizeTextArea,
|
undefined, // 不需要 resizeTextArea
|
||||||
t
|
t
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
[extensions, pasteLongTextThreshold, resizeTextArea, t]
|
[extensions, pasteLongTextThreshold, t]
|
||||||
)
|
)
|
||||||
|
|
||||||
// 添加全局粘贴事件处理
|
// 添加全局粘贴事件处理
|
||||||
@ -149,7 +140,6 @@ const MessageBlockEditor: FC<Props> = ({ message, topicId, onSave, onResend, onC
|
|||||||
if (mainTextBlock) {
|
if (mainTextBlock) {
|
||||||
handleTextChange(mainTextBlock.id, translatedText)
|
handleTextChange(mainTextBlock.id, translatedText)
|
||||||
}
|
}
|
||||||
setTimeout(() => resizeTextArea(), 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理文件删除
|
// 处理文件删除
|
||||||
@ -246,7 +236,6 @@ const MessageBlockEditor: FC<Props> = ({ message, topicId, onSave, onResend, onC
|
|||||||
// set cursor position in the next render cycle
|
// set cursor position in the next render cycle
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
textArea.selectionStart = textArea.selectionEnd = start + 1
|
textArea.selectionStart = textArea.selectionEnd = start + 1
|
||||||
resizeTextArea() // trigger resizeTextArea
|
|
||||||
}, 0)
|
}, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,11 +245,17 @@ const MessageBlockEditor: FC<Props> = ({ message, topicId, onSave, onResend, onC
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<EditorContainer className="message-editor" onDragOver={(e) => e.preventDefault()} onDrop={handleDrop}>
|
<EditorContainer
|
||||||
|
className="message-editor"
|
||||||
|
direction="vertical"
|
||||||
|
size="small"
|
||||||
|
style={{ display: 'flex' }}
|
||||||
|
onDragOver={(e) => e.preventDefault()}
|
||||||
|
onDrop={handleDrop}>
|
||||||
{editedBlocks
|
{editedBlocks
|
||||||
.filter((block) => block.type === MessageBlockType.MAIN_TEXT)
|
.filter((block) => block.type === MessageBlockType.MAIN_TEXT)
|
||||||
.map((block) => (
|
.map((block) => (
|
||||||
<Textarea
|
<TextArea
|
||||||
className={classNames('editing-message', isFileDragging && 'file-dragging')}
|
className={classNames('editing-message', isFileDragging && 'file-dragging')}
|
||||||
key={block.id}
|
key={block.id}
|
||||||
ref={textareaRef}
|
ref={textareaRef}
|
||||||
@ -268,7 +263,6 @@ const MessageBlockEditor: FC<Props> = ({ message, topicId, onSave, onResend, onC
|
|||||||
value={block.content}
|
value={block.content}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
handleTextChange(block.id, e.target.value)
|
handleTextChange(block.id, e.target.value)
|
||||||
resizeTextArea()
|
|
||||||
}}
|
}}
|
||||||
onKeyDown={(e) => handleKeyDown(e, block.id)}
|
onKeyDown={(e) => handleKeyDown(e, block.id)}
|
||||||
autoFocus
|
autoFocus
|
||||||
@ -282,12 +276,12 @@ const MessageBlockEditor: FC<Props> = ({ message, topicId, onSave, onResend, onC
|
|||||||
// 阻止事件冒泡,避免触发全局的 Electron contextMenu
|
// 阻止事件冒泡,避免触发全局的 Electron contextMenu
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
}}
|
}}
|
||||||
|
autoSize={{ minRows: 3, maxRows: 15 }}
|
||||||
style={{
|
style={{
|
||||||
fontSize,
|
fontSize
|
||||||
padding: '0px 15px 8px 15px'
|
|
||||||
}}>
|
}}>
|
||||||
<TranslateButton onTranslated={onTranslated} />
|
<TranslateButton onTranslated={onTranslated} />
|
||||||
</Textarea>
|
</TextArea>
|
||||||
))}
|
))}
|
||||||
{(editedBlocks.some((block) => block.type === MessageBlockType.FILE || block.type === MessageBlockType.IMAGE) ||
|
{(editedBlocks.some((block) => block.type === MessageBlockType.FILE || block.type === MessageBlockType.IMAGE) ||
|
||||||
files.length > 0) && (
|
files.length > 0) && (
|
||||||
@ -359,14 +353,9 @@ const MessageBlockEditor: FC<Props> = ({ message, topicId, onSave, onResend, onC
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const EditorContainer = styled.div`
|
const EditorContainer = styled(Space)`
|
||||||
padding: 18px 0;
|
margin: 15px 0 5px 0;
|
||||||
padding-bottom: 5px;
|
|
||||||
border: 0.5px solid var(--color-border);
|
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
border-radius: 15px;
|
|
||||||
margin-top: 18px;
|
|
||||||
background-color: var(--color-background-opacity);
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
&.file-dragging {
|
&.file-dragging {
|
||||||
@ -385,6 +374,22 @@ const EditorContainer = styled.div`
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.editing-message {
|
||||||
|
background-color: var(--color-background-opacity);
|
||||||
|
border: 0.5px solid var(--color-border);
|
||||||
|
border-radius: 15px;
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
flex: 1;
|
||||||
|
font-family: Ubuntu;
|
||||||
|
resize: none !important;
|
||||||
|
overflow: auto;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
&.ant-input {
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
const FileBlocksContainer = styled.div`
|
const FileBlocksContainer = styled.div`
|
||||||
@ -397,21 +402,6 @@ const FileBlocksContainer = styled.div`
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
`
|
`
|
||||||
|
|
||||||
const Textarea = styled(TextArea)`
|
|
||||||
padding: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
font-family: Ubuntu;
|
|
||||||
resize: none !important;
|
|
||||||
overflow: auto;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
&.ant-input {
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const ActionBar = styled.div`
|
const ActionBar = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user