mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-09 14:59:27 +08:00
fix: refactor message deletion logic and enhance message selection handling
This commit is contained in:
parent
0c9f20e65b
commit
397f6ce526
@ -1,11 +1,12 @@
|
|||||||
|
import { useMessageOperations } from '@renderer/hooks/useMessageOperations'
|
||||||
import { RootState } from '@renderer/store'
|
import { RootState } from '@renderer/store'
|
||||||
import { messageBlocksSelectors } from '@renderer/store/messageBlock'
|
import { messageBlocksSelectors } from '@renderer/store/messageBlock'
|
||||||
import { newMessagesActions, selectMessagesForTopic } from '@renderer/store/newMessage'
|
import { selectMessagesForTopic } from '@renderer/store/newMessage'
|
||||||
import { Topic } from '@renderer/types'
|
import { Topic } from '@renderer/types'
|
||||||
import { Modal } from 'antd'
|
import { Modal } from 'antd'
|
||||||
import { createContext, FC, ReactNode, use, useCallback, useState } from 'react'
|
import { createContext, FC, ReactNode, use, useCallback, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useDispatch, useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
|
|
||||||
interface ChatContextProps {
|
interface ChatContextProps {
|
||||||
isMultiSelectMode: boolean
|
isMultiSelectMode: boolean
|
||||||
@ -36,7 +37,7 @@ export const useChatContext = () => {
|
|||||||
|
|
||||||
export const ChatProvider: FC<ChatProviderProps> = ({ children, activeTopic }) => {
|
export const ChatProvider: FC<ChatProviderProps> = ({ children, activeTopic }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const dispatch = useDispatch()
|
const { deleteMessage } = useMessageOperations(activeTopic)
|
||||||
const [isMultiSelectMode, setIsMultiSelectMode] = useState(false)
|
const [isMultiSelectMode, setIsMultiSelectMode] = useState(false)
|
||||||
const [selectedMessageIds, setSelectedMessageIds] = useState<string[]>([])
|
const [selectedMessageIds, setSelectedMessageIds] = useState<string[]>([])
|
||||||
const [confirmDeleteVisible, setConfirmDeleteVisible] = useState(false)
|
const [confirmDeleteVisible, setConfirmDeleteVisible] = useState(false)
|
||||||
@ -163,12 +164,7 @@ export const ChatProvider: FC<ChatProviderProps> = ({ children, activeTopic }) =
|
|||||||
|
|
||||||
const confirmDelete = async () => {
|
const confirmDelete = async () => {
|
||||||
try {
|
try {
|
||||||
dispatch(
|
await Promise.all(messagesToDelete.map((messageId) => deleteMessage(messageId)))
|
||||||
newMessagesActions.removeMessages({
|
|
||||||
topicId: activeTopic.id,
|
|
||||||
messageIds: messagesToDelete
|
|
||||||
})
|
|
||||||
)
|
|
||||||
window.message.success(t('message.delete.success'))
|
window.message.success(t('message.delete.success'))
|
||||||
setMessagesToDelete([])
|
setMessagesToDelete([])
|
||||||
toggleMultiSelectMode(false)
|
toggleMultiSelectMode(false)
|
||||||
|
|||||||
@ -126,7 +126,9 @@ const MessageItem: FC<Props> = ({
|
|||||||
|
|
||||||
if (message.type === 'clear') {
|
if (message.type === 'clear') {
|
||||||
return (
|
return (
|
||||||
<NewContextMessage onClick={() => EventEmitter.emit(EVENT_NAMES.NEW_CONTEXT)}>
|
<NewContextMessage
|
||||||
|
className="clear-context-divider"
|
||||||
|
onClick={() => EventEmitter.emit(EVENT_NAMES.NEW_CONTEXT)}>
|
||||||
<Divider dashed style={{ padding: '0 20px' }} plain>
|
<Divider dashed style={{ padding: '0 20px' }} plain>
|
||||||
{t('chat.message.new.context')}
|
{t('chat.message.new.context')}
|
||||||
</Divider>
|
</Divider>
|
||||||
|
|||||||
@ -178,7 +178,8 @@ const MessageGroup = ({
|
|||||||
isMultiSelectMode={isMultiSelectMode}
|
isMultiSelectMode={isMultiSelectMode}
|
||||||
isSelected={selectedMessages.has(message.id)}
|
isSelected={selectedMessages.has(message.id)}
|
||||||
onSelect={(selected) => onSelectMessage?.(message.id, selected)}
|
onSelect={(selected) => onSelectMessage?.(message.id, selected)}
|
||||||
registerElement={registerMessageElement}>
|
registerElement={registerMessageElement}
|
||||||
|
isClearMessage={message.type === 'clear'}>
|
||||||
{messageContent}
|
{messageContent}
|
||||||
</SelectableMessage>
|
</SelectableMessage>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -11,6 +11,7 @@ interface SelectableMessageProps {
|
|||||||
onSelect: (selected: boolean) => void
|
onSelect: (selected: boolean) => void
|
||||||
messageId: string
|
messageId: string
|
||||||
registerElement?: (id: string, element: HTMLElement | null) => void
|
registerElement?: (id: string, element: HTMLElement | null) => void
|
||||||
|
isClearMessage?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const SelectableMessage: FC<SelectableMessageProps> = ({
|
const SelectableMessage: FC<SelectableMessageProps> = ({
|
||||||
@ -19,7 +20,8 @@ const SelectableMessage: FC<SelectableMessageProps> = ({
|
|||||||
isSelected,
|
isSelected,
|
||||||
onSelect,
|
onSelect,
|
||||||
messageId,
|
messageId,
|
||||||
registerElement
|
registerElement,
|
||||||
|
isClearMessage = false
|
||||||
}) => {
|
}) => {
|
||||||
const containerRef = useRef<HTMLDivElement>(null)
|
const containerRef = useRef<HTMLDivElement>(null)
|
||||||
const { registerMessageElement: contextRegister } = useChatContext()
|
const { registerMessageElement: contextRegister } = useChatContext()
|
||||||
@ -43,7 +45,7 @@ const SelectableMessage: FC<SelectableMessageProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Container ref={containerRef}>
|
<Container ref={containerRef}>
|
||||||
{isMultiSelectMode && (
|
{isMultiSelectMode && !isClearMessage && (
|
||||||
<CheckboxWrapper>
|
<CheckboxWrapper>
|
||||||
<Checkbox checked={isSelected} onChange={(e) => onSelect(e.target.checked)} />
|
<Checkbox checked={isSelected} onChange={(e) => onSelect(e.target.checked)} />
|
||||||
</CheckboxWrapper>
|
</CheckboxWrapper>
|
||||||
|
|||||||
@ -122,8 +122,7 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic, o
|
|||||||
|
|
||||||
const MIN_SELECTION_SIZE = 5
|
const MIN_SELECTION_SIZE = 5
|
||||||
const isValidSelection =
|
const isValidSelection =
|
||||||
Math.abs(right - left) > MIN_SELECTION_SIZE &&
|
Math.abs(right - left) > MIN_SELECTION_SIZE && Math.abs(bottom - top) > MIN_SELECTION_SIZE
|
||||||
Math.abs(bottom - top) > MIN_SELECTION_SIZE
|
|
||||||
|
|
||||||
if (isValidSelection) {
|
if (isValidSelection) {
|
||||||
// 处理元素选择
|
// 处理元素选择
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user