import { useEffect, useState, } from 'react' import { useAsyncEffect } from 'ahooks' import { useTranslation } from 'react-i18next' import { RiLoopLeftLine } from '@remixicon/react' import { EmbeddedChatbotContext, useEmbeddedChatbotContext, } from './context' import { useEmbeddedChatbot } from './hooks' import { isDify } from './utils' import { useThemeContext } from './theme/theme-context' import cn from '@/utils/classnames' import { checkOrSetAccessToken } from '@/app/components/share/utils' import AppUnavailable from '@/app/components/base/app-unavailable' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import Loading from '@/app/components/base/loading' import LogoHeader from '@/app/components/base/logo/logo-embedded-chat-header' import Header from '@/app/components/base/chat/embedded-chatbot/header' import ConfigPanel from '@/app/components/base/chat/embedded-chatbot/config-panel' import ChatWrapper from '@/app/components/base/chat/embedded-chatbot/chat-wrapper' import Tooltip from '@/app/components/base/tooltip' const Chatbot = () => { const { t } = useTranslation() const { isMobile, appInfoError, appInfoLoading, appData, appPrevChatList, showConfigPanelBeforeChat, appChatListDataLoading, handleNewConversation, themeBuilder, } = useEmbeddedChatbotContext() const chatReady = (!showConfigPanelBeforeChat || !!appPrevChatList.length) const customConfig = appData?.custom_config const site = appData?.site const difyIcon = useEffect(() => { themeBuilder?.buildTheme(site?.chat_color_theme, site?.chat_color_theme_inverted) if (site) { if (customConfig) document.title = `${site.title}` else document.title = `${site.title} - Powered by Dify` } }, [site, customConfig, themeBuilder]) if (appInfoLoading) { return ( ) } if (appInfoError) { return ( ) } return (
{showConfigPanelBeforeChat && !appChatListDataLoading && !appPrevChatList.length && (
)} {appChatListDataLoading && chatReady && ( )} {chatReady && !appChatListDataLoading && (
{!isMobile && (
)}
)}
) } const EmbeddedChatbotWrapper = () => { const media = useBreakpoints() const isMobile = media === MediaType.mobile const themeBuilder = useThemeContext() const { appInfoError, appInfoLoading, appData, appParams, appMeta, appChatListDataLoading, currentConversationId, currentConversationItem, appPrevChatList, pinnedConversationList, conversationList, showConfigPanelBeforeChat, newConversationInputs, newConversationInputsRef, handleNewConversationInputsChange, inputsForms, handleNewConversation, handleStartChat, handleChangeConversation, handleNewConversationCompleted, chatShouldReloadKey, isInstalledApp, appId, handleFeedback, currentChatInstanceRef, } = useEmbeddedChatbot() return } const EmbeddedChatbot = () => { const [initialized, setInitialized] = useState(false) const [appUnavailable, setAppUnavailable] = useState(false) const [isUnknownReason, setIsUnknownReason] = useState(false) useAsyncEffect(async () => { if (!initialized) { try { await checkOrSetAccessToken() } catch (e: any) { if (e.status === 404) { setAppUnavailable(true) } else { setIsUnknownReason(true) setAppUnavailable(true) } } setInitialized(true) } }, []) if (!initialized) return null if (appUnavailable) return return } export default EmbeddedChatbot