refactor: Enhance message context menu with improved text selection and copying

This commit is contained in:
kangfenmao 2025-03-03 17:40:17 +08:00
parent 4ca2d61ccc
commit 59c69e065c

View File

@ -35,14 +35,6 @@ interface Props {
onDeleteMessage?: (message: Message) => Promise<void>
}
const getMessageBackground = (isBubbleStyle: boolean, isAssistantMessage: boolean) => {
return isBubbleStyle
? isAssistantMessage
? 'var(--chat-background-assistant)'
: 'var(--chat-background-user)'
: undefined
}
const MessageItem: FC<Props> = ({
message: _message,
topic: _topic,
@ -64,6 +56,7 @@ const MessageItem: FC<Props> = ({
const topic = useTopic(assistant, _topic?.id)
const [contextMenuPosition, setContextMenuPosition] = useState<{ x: number; y: number } | null>(null)
const [selectedQuoteText, setSelectedQuoteText] = useState<string>('')
const [selectedText, setSelectedText] = useState<string>('')
const isLastMessage = index === 0
const isAssistantMessage = message.role === 'assistant'
@ -79,15 +72,16 @@ const MessageItem: FC<Props> = ({
const handleContextMenu = useCallback((e: React.MouseEvent) => {
e.preventDefault()
const selectedText = window.getSelection()?.toString()
if (selectedText) {
const _selectedText = window.getSelection()?.toString()
if (_selectedText) {
const quotedText =
selectedText
_selectedText
.split('\n')
.map((line) => `> ${line}`)
.join('\n') + '\n-------------'
setSelectedQuoteText(quotedText)
setContextMenuPosition({ x: e.clientX, y: e.clientY })
setSelectedText(_selectedText)
}
}, [])
@ -214,35 +208,9 @@ const MessageItem: FC<Props> = ({
onContextMenu={handleContextMenu}
style={{ ...style, alignItems: isBubbleStyle ? (isAssistantMessage ? 'start' : 'end') : undefined }}>
{contextMenuPosition && (
<ContextMenuOverlay
style={{
position: 'fixed',
left: contextMenuPosition.x,
top: contextMenuPosition.y,
zIndex: 1000
}}>
<ContextMenuOverlay style={{ left: contextMenuPosition.x, top: contextMenuPosition.y, zIndex: 1000 }}>
<Dropdown
menu={{
items: [
{
key: 'copy',
label: t('common.copy'),
onClick: () => {
navigator.clipboard.writeText(
selectedQuoteText.replace(/^> /gm, '').replace(/\n-------------$/, '')
)
window.message.success({ content: t('message.copied'), key: 'copy-message' })
}
},
{
key: 'quote',
label: t('chat.message.quote'),
onClick: () => {
EventEmitter.emit(EVENT_NAMES.QUOTE_TEXT, selectedQuoteText)
}
}
]
}}
menu={{ items: getContextMenuItems(t, selectedQuoteText, selectedText) }}
open={true}
trigger={['contextMenu']}>
<div />
@ -284,6 +252,32 @@ const MessageItem: FC<Props> = ({
)
}
const getMessageBackground = (isBubbleStyle: boolean, isAssistantMessage: boolean) => {
return isBubbleStyle
? isAssistantMessage
? 'var(--chat-background-assistant)'
: 'var(--chat-background-user)'
: undefined
}
const getContextMenuItems = (t: (key: string) => string, selectedQuoteText: string, selectedText: string) => [
{
key: 'copy',
label: t('common.copy'),
onClick: () => {
navigator.clipboard.writeText(selectedText)
window.message.success({ content: t('message.copied'), key: 'copy-message' })
}
},
{
key: 'quote',
label: t('chat.message.quote'),
onClick: () => {
EventEmitter.emit(EVENT_NAMES.QUOTE_TEXT, selectedQuoteText)
}
}
]
const MessageContainer = styled.div`
display: flex;
flex-direction: column;