| 
									
										
										
										
											2025-06-09 15:44:49 +08:00
										 |  |  | 'use client' | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  | import type { FC } from 'react' | 
					
						
							|  |  |  | import { | 
					
						
							| 
									
										
										
										
											2025-06-09 15:44:49 +08:00
										 |  |  |   useCallback, | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |   useEffect, | 
					
						
							|  |  |  |   useState, | 
					
						
							|  |  |  | } from 'react' | 
					
						
							|  |  |  | import { useAsyncEffect } from 'ahooks' | 
					
						
							| 
									
										
										
										
											2024-08-02 15:08:14 +08:00
										 |  |  | import { useThemeContext } from '../embedded-chatbot/theme/theme-context' | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |   ChatWithHistoryContext, | 
					
						
							|  |  |  |   useChatWithHistoryContext, | 
					
						
							|  |  |  | } from './context' | 
					
						
							|  |  |  | import { useChatWithHistory } from './hooks' | 
					
						
							|  |  |  | import Sidebar from './sidebar' | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  | import Header from './header' | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  | import HeaderInMobile from './header-in-mobile' | 
					
						
							|  |  |  | 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' | 
					
						
							| 
									
										
										
										
											2025-06-09 15:44:49 +08:00
										 |  |  | import { checkOrSetAccessToken, removeAccessToken } from '@/app/components/share/utils' | 
					
						
							| 
									
										
										
										
											2024-02-06 13:43:09 +08:00
										 |  |  | import AppUnavailable from '@/app/components/base/app-unavailable' | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  | import cn from '@/utils/classnames' | 
					
						
							| 
									
										
										
										
											2025-05-20 12:07:50 +08:00
										 |  |  | import useDocumentTitle from '@/hooks/use-document-title' | 
					
						
							| 
									
										
										
										
											2025-06-09 15:44:49 +08:00
										 |  |  | import { useTranslation } from 'react-i18next' | 
					
						
							|  |  |  | import { usePathname, useRouter, useSearchParams } from 'next/navigation' | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | type ChatWithHistoryProps = { | 
					
						
							|  |  |  |   className?: string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | const ChatWithHistory: FC<ChatWithHistoryProps> = ({ | 
					
						
							|  |  |  |   className, | 
					
						
							|  |  |  | }) => { | 
					
						
							|  |  |  |   const { | 
					
						
							| 
									
										
										
										
											2025-05-20 12:07:50 +08:00
										 |  |  |     userCanAccess, | 
					
						
							| 
									
										
										
										
											2024-02-06 13:43:09 +08:00
										 |  |  |     appInfoError, | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |     appData, | 
					
						
							|  |  |  |     appInfoLoading, | 
					
						
							|  |  |  |     appChatListDataLoading, | 
					
						
							|  |  |  |     chatShouldReloadKey, | 
					
						
							|  |  |  |     isMobile, | 
					
						
							| 
									
										
										
										
											2024-08-02 15:08:14 +08:00
										 |  |  |     themeBuilder, | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  |     sidebarCollapseState, | 
					
						
							| 
									
										
										
										
											2025-06-09 15:44:49 +08:00
										 |  |  |     isInstalledApp, | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |   } = useChatWithHistoryContext() | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  |   const isSidebarCollapsed = sidebarCollapseState | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |   const customConfig = appData?.custom_config | 
					
						
							|  |  |  |   const site = appData?.site | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  |   const [showSidePanel, setShowSidePanel] = useState(false) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |   useEffect(() => { | 
					
						
							| 
									
										
										
										
											2024-08-02 15:08:14 +08:00
										 |  |  |     themeBuilder?.buildTheme(site?.chat_color_theme, site?.chat_color_theme_inverted) | 
					
						
							|  |  |  |   }, [site, customConfig, themeBuilder]) | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-20 12:07:50 +08:00
										 |  |  |   useDocumentTitle(site?.title || 'Chat') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-09 15:44:49 +08:00
										 |  |  |   const { t } = useTranslation() | 
					
						
							|  |  |  |   const searchParams = useSearchParams() | 
					
						
							|  |  |  |   const router = useRouter() | 
					
						
							|  |  |  |   const pathname = usePathname() | 
					
						
							|  |  |  |   const getSigninUrl = useCallback(() => { | 
					
						
							|  |  |  |     const params = new URLSearchParams(searchParams) | 
					
						
							|  |  |  |     params.delete('message') | 
					
						
							|  |  |  |     params.set('redirect_url', pathname) | 
					
						
							|  |  |  |     return `/webapp-signin?${params.toString()}` | 
					
						
							|  |  |  |   }, [searchParams, pathname]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const backToHome = useCallback(() => { | 
					
						
							|  |  |  |     removeAccessToken() | 
					
						
							|  |  |  |     const url = getSigninUrl() | 
					
						
							|  |  |  |     router.replace(url) | 
					
						
							|  |  |  |   }, [getSigninUrl, router]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |   if (appInfoLoading) { | 
					
						
							|  |  |  |     return ( | 
					
						
							|  |  |  |       <Loading type='app' /> | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-06-09 15:44:49 +08:00
										 |  |  |   if (!userCanAccess) { | 
					
						
							|  |  |  |     return <div className='flex h-full flex-col items-center justify-center gap-y-2'> | 
					
						
							|  |  |  |       <AppUnavailable className='h-auto w-auto' code={403} unknownReason='no permission.' /> | 
					
						
							|  |  |  |       {!isInstalledApp && <span className='system-sm-regular cursor-pointer text-text-tertiary' onClick={backToHome}>{t('common.userProfile.logout')}</span>} | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-06 13:43:09 +08:00
										 |  |  |   if (appInfoError) { | 
					
						
							|  |  |  |     return ( | 
					
						
							|  |  |  |       <AppUnavailable /> | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |   return ( | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  |     <div className={cn( | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |       'flex h-full bg-background-default-burn', | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  |       isMobile && 'flex-col', | 
					
						
							|  |  |  |       className, | 
					
						
							|  |  |  |     )}> | 
					
						
							|  |  |  |       {!isMobile && ( | 
					
						
							|  |  |  |         <div className={cn( | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |           'flex w-[236px] flex-col p-1 pr-0 transition-all duration-200 ease-in-out', | 
					
						
							|  |  |  |           isSidebarCollapsed && 'w-0 overflow-hidden !p-0', | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  |         )}> | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |           <Sidebar /> | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  |         </div> | 
					
						
							|  |  |  |       )} | 
					
						
							|  |  |  |       {isMobile && ( | 
					
						
							|  |  |  |         <HeaderInMobile /> | 
					
						
							|  |  |  |       )} | 
					
						
							| 
									
										
										
										
											2025-03-13 14:23:41 +08:00
										 |  |  |       <div className={cn('relative grow p-2', isMobile && 'h-[calc(100%_-_56px)] p-0')}> | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  |         {isSidebarCollapsed && ( | 
					
						
							|  |  |  |           <div | 
					
						
							|  |  |  |             className={cn( | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |               'absolute top-0 z-20 flex h-full w-[256px] flex-col p-2 transition-all duration-500 ease-in-out', | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  |               showSidePanel ? 'left-0' : 'left-[-248px]', | 
					
						
							|  |  |  |             )} | 
					
						
							|  |  |  |             onMouseEnter={() => setShowSidePanel(true)} | 
					
						
							|  |  |  |             onMouseLeave={() => setShowSidePanel(false)} | 
					
						
							|  |  |  |           > | 
					
						
							|  |  |  |             <Sidebar isPanel /> | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |         )} | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |         <div className={cn('flex h-full flex-col overflow-hidden border-[0,5px] border-components-panel-border-subtle bg-chatbot-bg', isMobile ? 'rounded-t-2xl' : 'rounded-2xl')}> | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  |           {!isMobile && <Header />} | 
					
						
							|  |  |  |           {appChatListDataLoading && ( | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |             <Loading type='app' /> | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  |           )} | 
					
						
							|  |  |  |           {!appChatListDataLoading && ( | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |             <ChatWrapper key={chatShouldReloadKey} /> | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  |           )} | 
					
						
							|  |  |  |         </div> | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |       </div> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export type ChatWithHistoryWrapProps = { | 
					
						
							|  |  |  |   installedAppInfo?: InstalledApp | 
					
						
							|  |  |  |   className?: string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | const ChatWithHistoryWrap: FC<ChatWithHistoryWrapProps> = ({ | 
					
						
							|  |  |  |   installedAppInfo, | 
					
						
							|  |  |  |   className, | 
					
						
							|  |  |  | }) => { | 
					
						
							|  |  |  |   const media = useBreakpoints() | 
					
						
							|  |  |  |   const isMobile = media === MediaType.mobile | 
					
						
							| 
									
										
										
										
											2024-08-02 15:08:14 +08:00
										 |  |  |   const themeBuilder = useThemeContext() | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const { | 
					
						
							| 
									
										
										
										
											2024-02-06 13:43:09 +08:00
										 |  |  |     appInfoError, | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |     appInfoLoading, | 
					
						
							| 
									
										
										
										
											2025-05-20 12:07:50 +08:00
										 |  |  |     userCanAccess, | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |     appData, | 
					
						
							|  |  |  |     appParams, | 
					
						
							|  |  |  |     appMeta, | 
					
						
							|  |  |  |     appChatListDataLoading, | 
					
						
							|  |  |  |     currentConversationId, | 
					
						
							|  |  |  |     currentConversationItem, | 
					
						
							| 
									
										
										
										
											2025-01-31 13:05:10 +08:00
										 |  |  |     appPrevChatTree, | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |     pinnedConversationList, | 
					
						
							|  |  |  |     conversationList, | 
					
						
							|  |  |  |     newConversationInputs, | 
					
						
							| 
									
										
										
										
											2024-10-21 10:32:37 +08:00
										 |  |  |     newConversationInputsRef, | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |     handleNewConversationInputsChange, | 
					
						
							|  |  |  |     inputsForms, | 
					
						
							|  |  |  |     handleNewConversation, | 
					
						
							|  |  |  |     handleStartChat, | 
					
						
							|  |  |  |     handleChangeConversation, | 
					
						
							|  |  |  |     handlePinConversation, | 
					
						
							|  |  |  |     handleUnpinConversation, | 
					
						
							|  |  |  |     handleDeleteConversation, | 
					
						
							|  |  |  |     conversationRenaming, | 
					
						
							|  |  |  |     handleRenameConversation, | 
					
						
							|  |  |  |     handleNewConversationCompleted, | 
					
						
							|  |  |  |     chatShouldReloadKey, | 
					
						
							|  |  |  |     isInstalledApp, | 
					
						
							|  |  |  |     appId, | 
					
						
							|  |  |  |     handleFeedback, | 
					
						
							|  |  |  |     currentChatInstanceRef, | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  |     sidebarCollapseState, | 
					
						
							|  |  |  |     handleSidebarCollapse, | 
					
						
							| 
									
										
										
										
											2025-03-13 14:23:41 +08:00
										 |  |  |     clearChatList, | 
					
						
							|  |  |  |     setClearChatList, | 
					
						
							|  |  |  |     isResponding, | 
					
						
							|  |  |  |     setIsResponding, | 
					
						
							| 
									
										
										
										
											2025-03-27 11:58:16 +08:00
										 |  |  |     currentConversationInputs, | 
					
						
							|  |  |  |     setCurrentConversationInputs, | 
					
						
							| 
									
										
										
										
											2025-05-21 13:52:21 +08:00
										 |  |  |     allInputsHidden, | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |   } = useChatWithHistory(installedAppInfo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( | 
					
						
							|  |  |  |     <ChatWithHistoryContext.Provider value={{ | 
					
						
							| 
									
										
										
										
											2024-02-06 13:43:09 +08:00
										 |  |  |       appInfoError, | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |       appInfoLoading, | 
					
						
							|  |  |  |       appData, | 
					
						
							| 
									
										
										
										
											2025-05-20 12:07:50 +08:00
										 |  |  |       userCanAccess, | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |       appParams, | 
					
						
							|  |  |  |       appMeta, | 
					
						
							|  |  |  |       appChatListDataLoading, | 
					
						
							|  |  |  |       currentConversationId, | 
					
						
							|  |  |  |       currentConversationItem, | 
					
						
							| 
									
										
										
										
											2025-01-31 13:05:10 +08:00
										 |  |  |       appPrevChatTree, | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |       pinnedConversationList, | 
					
						
							|  |  |  |       conversationList, | 
					
						
							|  |  |  |       newConversationInputs, | 
					
						
							| 
									
										
										
										
											2024-10-21 10:32:37 +08:00
										 |  |  |       newConversationInputsRef, | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |       handleNewConversationInputsChange, | 
					
						
							|  |  |  |       inputsForms, | 
					
						
							|  |  |  |       handleNewConversation, | 
					
						
							|  |  |  |       handleStartChat, | 
					
						
							|  |  |  |       handleChangeConversation, | 
					
						
							|  |  |  |       handlePinConversation, | 
					
						
							|  |  |  |       handleUnpinConversation, | 
					
						
							|  |  |  |       handleDeleteConversation, | 
					
						
							|  |  |  |       conversationRenaming, | 
					
						
							|  |  |  |       handleRenameConversation, | 
					
						
							|  |  |  |       handleNewConversationCompleted, | 
					
						
							|  |  |  |       chatShouldReloadKey, | 
					
						
							|  |  |  |       isMobile, | 
					
						
							|  |  |  |       isInstalledApp, | 
					
						
							|  |  |  |       appId, | 
					
						
							|  |  |  |       handleFeedback, | 
					
						
							|  |  |  |       currentChatInstanceRef, | 
					
						
							| 
									
										
										
										
											2024-08-02 15:08:14 +08:00
										 |  |  |       themeBuilder, | 
					
						
							| 
									
										
										
										
											2025-03-03 14:44:51 +08:00
										 |  |  |       sidebarCollapseState, | 
					
						
							|  |  |  |       handleSidebarCollapse, | 
					
						
							| 
									
										
										
										
											2025-03-13 14:23:41 +08:00
										 |  |  |       clearChatList, | 
					
						
							|  |  |  |       setClearChatList, | 
					
						
							|  |  |  |       isResponding, | 
					
						
							|  |  |  |       setIsResponding, | 
					
						
							| 
									
										
										
										
											2025-03-27 11:58:16 +08:00
										 |  |  |       currentConversationInputs, | 
					
						
							|  |  |  |       setCurrentConversationInputs, | 
					
						
							| 
									
										
										
										
											2025-05-21 13:52:21 +08:00
										 |  |  |       allInputsHidden, | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |     }}> | 
					
						
							|  |  |  |       <ChatWithHistory className={className} /> | 
					
						
							|  |  |  |     </ChatWithHistoryContext.Provider> | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const ChatWithHistoryWrapWithCheckToken: FC<ChatWithHistoryWrapProps> = ({ | 
					
						
							|  |  |  |   installedAppInfo, | 
					
						
							|  |  |  |   className, | 
					
						
							|  |  |  | }) => { | 
					
						
							| 
									
										
										
										
											2024-06-14 08:42:41 +08:00
										 |  |  |   const [initialized, setInitialized] = useState(false) | 
					
						
							| 
									
										
										
										
											2024-02-06 13:43:09 +08:00
										 |  |  |   const [appUnavailable, setAppUnavailable] = useState<boolean>(false) | 
					
						
							| 
									
										
										
										
											2024-06-14 08:42:41 +08:00
										 |  |  |   const [isUnknownReason, setIsUnknownReason] = useState<boolean>(false) | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   useAsyncEffect(async () => { | 
					
						
							| 
									
										
										
										
											2024-06-14 08:42:41 +08:00
										 |  |  |     if (!initialized) { | 
					
						
							| 
									
										
										
										
											2024-02-06 13:43:09 +08:00
										 |  |  |       if (!installedAppInfo) { | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |           await checkOrSetAccessToken() | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         catch (e: any) { | 
					
						
							|  |  |  |           if (e.status === 404) { | 
					
						
							|  |  |  |             setAppUnavailable(true) | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							| 
									
										
										
										
											2024-06-14 08:42:41 +08:00
										 |  |  |             setIsUnknownReason(true) | 
					
						
							| 
									
										
										
										
											2024-02-06 13:43:09 +08:00
										 |  |  |             setAppUnavailable(true) | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2024-06-14 08:42:41 +08:00
										 |  |  |       setInitialized(true) | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   }, []) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-14 08:42:41 +08:00
										 |  |  |   if (!initialized) | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |     return null | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-14 08:42:41 +08:00
										 |  |  |   if (appUnavailable) | 
					
						
							|  |  |  |     return <AppUnavailable isUnknownReason={isUnknownReason} /> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-04 16:10:46 +08:00
										 |  |  |   return ( | 
					
						
							|  |  |  |     <ChatWithHistoryWrap | 
					
						
							|  |  |  |       installedAppInfo={installedAppInfo} | 
					
						
							|  |  |  |       className={className} | 
					
						
							|  |  |  |     /> | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default ChatWithHistoryWrapWithCheckToken |