import type { FC } from 'react' import React, { useCallback, useEffect, useState } from 'react' import { RiCollapseDiagonal2Line, RiExpandDiagonal2Line, RiResetLeftLine } from '@remixicon/react' import { useTranslation } from 'react-i18next' import type { Theme } from '../theme/theme-context' import { CssTransform } from '../theme/utils' import { useEmbeddedChatbotContext, } from '../context' import Tooltip from '@/app/components/base/tooltip' import ActionButton from '@/app/components/base/action-button' import Divider from '@/app/components/base/divider' import ViewFormDropdown from '@/app/components/base/chat/embedded-chatbot/inputs-form/view-form-dropdown' import DifyLogo from '@/app/components/base/logo/dify-logo' import cn from '@/utils/classnames' export type IHeaderProps = { isMobile?: boolean allowResetChat?: boolean customerIcon?: React.ReactNode title: string theme?: Theme onCreateNewChat?: () => void } const Header: FC = ({ isMobile, allowResetChat, customerIcon, title, theme, onCreateNewChat, }) => { const { t } = useTranslation() const { appData, currentConversationId, inputsForms, } = useEmbeddedChatbotContext() const isClient = typeof window !== 'undefined' const isIframe = isClient ? window.self !== window.top : false const [parentOrigin, setParentOrigin] = useState('') const [showToggleExpandButton, setShowToggleExpandButton] = useState(false) const [expanded, setExpanded] = useState(false) const handleMessageReceived = useCallback((event: MessageEvent) => { let currentParentOrigin = parentOrigin if (!currentParentOrigin && event.data.type === 'dify-chatbot-config') { currentParentOrigin = event.origin setParentOrigin(event.origin) } if (event.origin !== currentParentOrigin) return if (event.data.type === 'dify-chatbot-config') setShowToggleExpandButton(event.data.payload.isToggledByButton && !event.data.payload.isDraggable) }, [parentOrigin]) useEffect(() => { if (!isIframe) return const listener = (event: MessageEvent) => handleMessageReceived(event) window.addEventListener('message', listener) window.parent.postMessage({ type: 'dify-chatbot-iframe-ready' }, '*') return () => window.removeEventListener('message', listener) }, [isIframe, handleMessageReceived]) const handleToggleExpand = useCallback(() => { if (!isIframe || !showToggleExpandButton) return setExpanded(!expanded) window.parent.postMessage({ type: 'dify-chatbot-expand-change', }, parentOrigin) }, [isIframe, parentOrigin, showToggleExpandButton, expanded]) if (!isMobile) { return (
{/* powered by */}
{!appData?.custom_config?.remove_webapp_brand && (
{t('share.chat.poweredBy')}
{appData?.custom_config?.replace_webapp_logo && ( logo )} {!appData?.custom_config?.replace_webapp_logo && ( )}
)}
{currentConversationId && ( )} { showToggleExpandButton && ( { expanded ? : } ) } {currentConversationId && allowResetChat && ( )} {currentConversationId && inputsForms.length > 0 && ( )}
) } return (
{customerIcon}
{title}
{ showToggleExpandButton && ( { expanded ? : } ) } {currentConversationId && allowResetChat && ( )} {currentConversationId && inputsForms.length > 0 && ( )}
) } export default React.memo(Header)