import type { FC } from 'react' import { useEffect, useState, } from 'react' import { useAsyncEffect } from 'ahooks' import { useThemeContext } from '@/app/components/chat/embedded-chatbot/theme/theme-context' import { ChatWithHistoryContext, useChatWithHistoryContext, } from './context' import { useChatWithHistory } from './hooks' import Sidebar from './sidebar' import HeaderInMobile from './header-in-mobile' import ConfigPanel from './config-panel' import ChatWrapper from './chat-wrapper' import type { InstalledApp } from '@/models/explore' import Loading from '@/app/components/base/loading' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import { useRouter } from 'next/navigation' import AppUnavailable from '@/app/components/base/app-unavailable' type ChatWithHistoryProps = { className?: string userStr?: string } const ChatWithHistory: FC = ({ className, userStr, }) => { const { appInfoError, appData, appInfoLoading, appPrevChatTree, showConfigPanelBeforeChat, appChatListDataLoading, chatShouldReloadKey, isMobile, themeBuilder, } = useChatWithHistoryContext() const chatReady = (!showConfigPanelBeforeChat || !!appPrevChatTree.length) const customConfig = appData?.custom_config const site = appData?.site 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 (
{ !isMobile && ( ) } { isMobile && ( ) }
{ showConfigPanelBeforeChat && !appChatListDataLoading && !appPrevChatTree.length && (
) } { appChatListDataLoading && chatReady && ( ) } { chatReady && !appChatListDataLoading && ( ) }
) } export type ChatWithHistoryWrapProps = { installedAppInfo?: InstalledApp className?: string userStr?: string } const ChatWithHistoryWrap: FC = ({ installedAppInfo, className, userStr, }) => { const media = useBreakpoints() const isMobile = media === MediaType.mobile const themeBuilder = useThemeContext() const { appInfoError, appInfoLoading, appData, appParams, appMeta, appChatListDataLoading, currentConversationId, currentConversationItem, appPrevChatTree, pinnedConversationList, conversationList, showConfigPanelBeforeChat, newConversationInputs, newConversationInputsRef, handleNewConversationInputsChange, inputsForms, handleNewConversation, handleStartChat, handleChangeConversation, handlePinConversation, handleUnpinConversation, handleDeleteConversation, conversationRenaming, handleRenameConversation, handleNewConversationCompleted, chatShouldReloadKey, isInstalledApp, appId, handleFeedback, currentChatInstanceRef, } = useChatWithHistory(installedAppInfo) return ( ) } const ChatWithHistoryWrapWithCheckToken: FC = ({ installedAppInfo, className, }) => { const [initialized, setInitialized] = useState(false) const [appUnavailable, setAppUnavailable] = useState(false) const [resCode, setResCode] = useState(200) const router = useRouter() const [userName, setUserName] = useState('') const [nickName, setNickName] = useState('') useAsyncEffect(async () => { if (!initialized) { if (!installedAppInfo) { const accessToken = localStorage.getItem('token') if (!accessToken) { router.replace('/login') } else { fetch(`${process.env.NEXT_PUBLIC_BASE_API_URL}/getInfo`, { method: 'GET', headers: { Authorization: `Bearer ${accessToken}`, }, }).then(res => res.json()).then(data => { if (data.code !== 200) { localStorage.removeItem('token') router.replace('/login') } else { setUserName(data.user.userName) setNickName(data.user.nickName) } }).catch(() => { setResCode(500) setAppUnavailable(true) }) } } setInitialized(true) } }, []) if (!initialized) return null if (appUnavailable) return return ( ) } export default ChatWithHistoryWrapWithCheckToken