import React, { ReactNode } from 'react'; import { AIChatDialogueActionProps, DefaultActionNodeObj } from '../interface'; import { IconThumbUpStroked, IconDeleteStroked, IconShareStroked, IconCopyStroked, IconLikeThumb, IconRedoStroked, IconEditStroked, IconMoreStroked } from '@douyinfe/semi-icons'; import BaseComponent from '../../_base/baseComponent'; import { Button, Dropdown, Modal, Toast } from '../../index'; import copy from 'copy-text-to-clipboard'; import { cssClasses, strings } from '@douyinfe/semi-foundation/aiChatDialogue/constants'; import DialogueActionFoundation, { DialogueActionAdapter } from '@douyinfe/semi-foundation/aiChatDialogue/actionFoundation'; import LocaleConsumer from "../../locale/localeConsumer"; import { Locale } from "../../locale/interface"; import cls from 'classnames'; const { PREFIX_ACTION } = cssClasses; const { ROLE, STATUS } = strings; interface AIChatDialogueActionState { visible: boolean; showAction: boolean } class DialogueAction extends BaseComponent { copySuccessNode: ReactNode; foundation: DialogueActionFoundation; containerRef: React.RefObject; dropdownTriggerRef: React.RefObject; clickOutsideHandler: any; constructor(props: AIChatDialogueActionProps) { super(props); this.foundation = new DialogueActionFoundation(this.adapter); this.state = { visible: false, showAction: false, }; this.copySuccessNode = null; this.clickOutsideHandler = null; this.containerRef = React.createRef(); this.dropdownTriggerRef = React.createRef(); } componentDidMount(): void { this.copySuccessNode = componentName="AIChatDialogue" > {(locale: Locale["AIChatDialogue"]) => locale['copySuccess']} ; } get adapter(): DialogueActionAdapter { return { ...super.adapter, notifyMessageCopy: () => { const { message, onMessageCopy } = this.props; onMessageCopy?.(message); }, copyToClipboardAndToast: () => { const { message } = this.props; if (typeof message?.content === 'string') { copy(message.content); } else if (Array.isArray(message?.content)) { const content = message.content?.map(item => { if (typeof (item as any)?.content === 'string') { return (item as any)?.content; } else { return (item as any)?.content?.map(innerItem => innerItem?.text).join(''); } }).join(''); copy(content); } Toast.success({ content: this.copySuccessNode }); }, notifyLikeMessage: () => { const { message, onMessageGoodFeedback } = this.props; onMessageGoodFeedback?.(message); }, notifyDislikeMessage: () => { const { message, onMessageBadFeedback } = this.props; onMessageBadFeedback?.(message); }, notifyResetMessage: () => { const { message, onMessageReset } = this.props; onMessageReset?.(message); }, notifyShareMessage: () => { const { message, onMessageShare } = this.props; onMessageShare?.(message); }, notifyEditMessage: () => { const { message, onMessageEdit } = this.props; onMessageEdit?.(message); }, notifyDeleteMessage: () => { const { message, onMessageDelete } = this.props; onMessageDelete?.(message); }, setVisible: (visible: boolean) => { this.setState({ visible }); }, setShowAction: (showAction: boolean) => { this.setState({ showAction }); }, registerClickOutsideHandler: (cb: () => void) => { if (this.clickOutsideHandler) { this.adapter.unregisterClickOutsideHandler(); } this.clickOutsideHandler = (e: React.MouseEvent): any => { let el = this.dropdownTriggerRef && this.dropdownTriggerRef.current; const target = e.target as Element; const path = (e as any).composedPath && (e as any).composedPath() || [target]; if ( el && !(el as any).contains(target) && ! path.includes(el) ) { cb(); } }; window.addEventListener('mousedown', this.clickOutsideHandler); }, unregisterClickOutsideHandler: () => { if (this.clickOutsideHandler) { window.removeEventListener('mousedown', this.clickOutsideHandler); this.clickOutsideHandler = null; } }, }; } showDeleteModal = () => { Modal.warning({ title: componentName="AIChatDialogue" > {(locale: Locale["AIChatDialogue"]) => locale['deleteConfirm']} , content: componentName="AIChatDialogue" > {(locale: Locale["AIChatDialogue"]) => locale['deleteContent']} , onOk: this.foundation.deleteMessage }); this.foundation.hideMoreDropdown(); } copyNode = () => { return