import type { FC } from "react"; import "antd/dist/reset.css"; // 引入 antd 的样式 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, feedbackModal, } = useChatWithHistory(installedAppInfo); return ( {feedbackModal} {/* 确保 feedbackModal 正确渲染 */} ); }; 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(`/dev-api/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;