import React, { useCallback, useEffect, useRef } from 'react'; import { useRouter } from 'next/router'; import { initShareChatInfo } from '@/api/chat'; import { Box, Flex, useDisclosure, Drawer, DrawerOverlay, DrawerContent } from '@chakra-ui/react'; import { useToast } from '@/hooks/useToast'; import { useGlobalStore } from '@/store/global'; import { useQuery } from '@tanstack/react-query'; import { streamFetch } from '@/api/fetch'; import { useShareChatStore, defaultHistory } from '@/store/shareChat'; import SideBar from '@/components/SideBar'; import { gptMessage2ChatType } from '@/utils/adapt'; import { getErrText } from '@/utils/tools'; import ChatBox, { type ComponentRef, type StartChatFnProps } from '@/components/ChatBox'; import PageContainer from '@/components/PageContainer'; import ChatHistorySlider from './components/ChatHistorySlider'; import ChatHeader from './components/ChatHeader'; const ShareChat = ({ shareId, historyId }: { shareId: string; historyId: string }) => { const router = useRouter(); const { toast } = useToast(); const { isOpen: isOpenSlider, onClose: onCloseSlider, onOpen: onOpenSlider } = useDisclosure(); const { isPc } = useGlobalStore(); const ChatBoxRef = useRef(null); const { shareChatData, setShareChatData, shareChatHistory, saveChatResponse, delShareChatHistoryItemById, delOneShareHistoryByHistoryId, delManyShareChatHistoryByShareId } = useShareChatStore(); const startChat = useCallback( async ({ messages, controller, generatingMessage, variables }: StartChatFnProps) => { const prompts = messages.slice(-shareChatData.maxContext - 2); const { responseText } = await streamFetch({ data: { history, messages: prompts, variables, shareId }, onMessage: generatingMessage, abortSignal: controller }); const result = { question: messages[messages.length - 2].content || '', answer: responseText }; prompts[prompts.length - 1].content = responseText; /* save chat */ const { newChatId } = saveChatResponse({ historyId, prompts: gptMessage2ChatType(prompts).map((item) => ({ ...item, status: 'finish' })), variables, shareId }); if (newChatId) { router.replace({ query: { shareId, historyId: newChatId } }); } window.top?.postMessage( { type: 'shareChatFinish', data: result }, '*' ); return { responseText }; }, [historyId, router, saveChatResponse, shareChatData.maxContext, shareId] ); const loadAppInfo = useCallback( async (shareId: string, historyId: string) => { console.log(shareId, historyId); if (!shareId) return null; const history = shareChatHistory.find((item) => item._id === historyId) || defaultHistory; ChatBoxRef.current?.resetHistory(history.chats); ChatBoxRef.current?.resetVariables(history.variables); try { const chatData = await (async () => { if (shareChatData.app.name === '') { return initShareChatInfo({ shareId }); } return shareChatData; })(); setShareChatData({ ...chatData, history }); } catch (e: any) { toast({ status: 'error', title: getErrText(e, '获取应用失败') }); if (e?.code === 501) { delManyShareChatHistoryByShareId(shareId); } } if (history.chats.length > 0) { ChatBoxRef.current?.scrollToBottom('auto'); } return history; }, [delManyShareChatHistoryByShareId, setShareChatData, shareChatData, shareChatHistory, toast] ); useQuery(['init', shareId, historyId], () => { return loadAppInfo(shareId, historyId); }); return ( {((children: React.ReactNode) => { return isPc ? ( {children} ) : ( {children} ); })( ({ id: item._id, title: item.title }))} onChangeChat={(historyId) => { router.push({ query: { historyId: historyId || '', shareId } }); if (!isPc) { onCloseSlider(); } }} onDelHistory={delOneShareHistoryByHistoryId} /> )} {/* chat container */} {/* header */} {/* chat box */} { setShareChatData((state) => ({ ...state, history: { ...state.history, variables: e } })); }} onStartChat={startChat} onDelMessage={({ index }) => delShareChatHistoryItemById({ historyId, index })} /> ); }; export async function getServerSideProps(context: any) { const shareId = context?.query?.shareId || ''; const historyId = context?.query?.historyId || ''; return { props: { shareId, historyId } }; } export default ShareChat;