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 && (
)}
)
}
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