You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.tsx 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. 'use client'
  2. import {
  3. useEffect,
  4. } from 'react'
  5. import { useTranslation } from 'react-i18next'
  6. import {
  7. EmbeddedChatbotContext,
  8. useEmbeddedChatbotContext,
  9. } from './context'
  10. import { useEmbeddedChatbot } from './hooks'
  11. import { isDify } from './utils'
  12. import { useThemeContext } from './theme/theme-context'
  13. import { CssTransform } from './theme/utils'
  14. import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
  15. import Loading from '@/app/components/base/loading'
  16. import LogoHeader from '@/app/components/base/logo/logo-embedded-chat-header'
  17. import Header from '@/app/components/base/chat/embedded-chatbot/header'
  18. import ChatWrapper from '@/app/components/base/chat/embedded-chatbot/chat-wrapper'
  19. import DifyLogo from '@/app/components/base/logo/dify-logo'
  20. import cn from '@/utils/classnames'
  21. import useDocumentTitle from '@/hooks/use-document-title'
  22. import { useGlobalPublicStore } from '@/context/global-public-context'
  23. const Chatbot = () => {
  24. const {
  25. isMobile,
  26. allowResetChat,
  27. appData,
  28. appChatListDataLoading,
  29. chatShouldReloadKey,
  30. handleNewConversation,
  31. themeBuilder,
  32. } = useEmbeddedChatbotContext()
  33. const { t } = useTranslation()
  34. const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
  35. const customConfig = appData?.custom_config
  36. const site = appData?.site
  37. const difyIcon = <LogoHeader />
  38. useEffect(() => {
  39. themeBuilder?.buildTheme(site?.chat_color_theme, site?.chat_color_theme_inverted)
  40. }, [site, customConfig, themeBuilder])
  41. useDocumentTitle(site?.title || 'Chat')
  42. return (
  43. <div className='relative'>
  44. <div
  45. className={cn(
  46. 'flex flex-col rounded-2xl border border-components-panel-border-subtle',
  47. isMobile ? 'h-[calc(100vh_-_60px)] border-[0.5px] border-components-panel-border shadow-xs' : 'h-[100vh] bg-chatbot-bg',
  48. )}
  49. style={isMobile ? Object.assign({}, CssTransform(themeBuilder?.theme?.backgroundHeaderColorStyle ?? '')) : {}}
  50. >
  51. <Header
  52. isMobile={isMobile}
  53. allowResetChat={allowResetChat}
  54. title={site?.title || ''}
  55. customerIcon={isDify() ? difyIcon : ''}
  56. theme={themeBuilder?.theme}
  57. onCreateNewChat={handleNewConversation}
  58. />
  59. <div className={cn('flex grow flex-col overflow-y-auto', isMobile && '!h-[calc(100vh_-_3rem)] rounded-2xl bg-chatbot-bg')}>
  60. {appChatListDataLoading && (
  61. <Loading type='app' />
  62. )}
  63. {!appChatListDataLoading && (
  64. <ChatWrapper key={chatShouldReloadKey} />
  65. )}
  66. </div>
  67. </div>
  68. {/* powered by */}
  69. {isMobile && (
  70. <div className='flex h-[60px] shrink-0 items-center pl-2'>
  71. {!appData?.custom_config?.remove_webapp_brand && (
  72. <div className={cn(
  73. 'flex shrink-0 items-center gap-1.5 px-2',
  74. )}>
  75. <div className='system-2xs-medium-uppercase text-text-tertiary'>{t('share.chat.poweredBy')}</div>
  76. {
  77. systemFeatures.branding.enabled && systemFeatures.branding.workspace_logo
  78. ? <img src={systemFeatures.branding.workspace_logo} alt='logo' className='block h-5 w-auto' />
  79. : appData?.custom_config?.replace_webapp_logo
  80. ? <img src={`${appData?.custom_config?.replace_webapp_logo}`} alt='logo' className='block h-5 w-auto' />
  81. : <DifyLogo size='small' />
  82. }
  83. </div>
  84. )}
  85. </div>
  86. )}
  87. </div>
  88. )
  89. }
  90. const EmbeddedChatbotWrapper = () => {
  91. const media = useBreakpoints()
  92. const isMobile = media === MediaType.mobile
  93. const themeBuilder = useThemeContext()
  94. const {
  95. appData,
  96. userCanAccess,
  97. appParams,
  98. appMeta,
  99. appChatListDataLoading,
  100. currentConversationId,
  101. currentConversationItem,
  102. appPrevChatList,
  103. pinnedConversationList,
  104. conversationList,
  105. newConversationInputs,
  106. newConversationInputsRef,
  107. handleNewConversationInputsChange,
  108. inputsForms,
  109. handleNewConversation,
  110. handleStartChat,
  111. handleChangeConversation,
  112. handleNewConversationCompleted,
  113. chatShouldReloadKey,
  114. isInstalledApp,
  115. allowResetChat,
  116. appId,
  117. handleFeedback,
  118. currentChatInstanceRef,
  119. clearChatList,
  120. setClearChatList,
  121. isResponding,
  122. setIsResponding,
  123. currentConversationInputs,
  124. setCurrentConversationInputs,
  125. allInputsHidden,
  126. initUserVariables,
  127. } = useEmbeddedChatbot()
  128. return <EmbeddedChatbotContext.Provider value={{
  129. userCanAccess,
  130. appData,
  131. appParams,
  132. appMeta,
  133. appChatListDataLoading,
  134. currentConversationId,
  135. currentConversationItem,
  136. appPrevChatList,
  137. pinnedConversationList,
  138. conversationList,
  139. newConversationInputs,
  140. newConversationInputsRef,
  141. handleNewConversationInputsChange,
  142. inputsForms,
  143. handleNewConversation,
  144. handleStartChat,
  145. handleChangeConversation,
  146. handleNewConversationCompleted,
  147. chatShouldReloadKey,
  148. isMobile,
  149. isInstalledApp,
  150. allowResetChat,
  151. appId,
  152. handleFeedback,
  153. currentChatInstanceRef,
  154. themeBuilder,
  155. clearChatList,
  156. setClearChatList,
  157. isResponding,
  158. setIsResponding,
  159. currentConversationInputs,
  160. setCurrentConversationInputs,
  161. allInputsHidden,
  162. initUserVariables,
  163. }}>
  164. <Chatbot />
  165. </EmbeddedChatbotContext.Provider>
  166. }
  167. const EmbeddedChatbot = () => {
  168. return <EmbeddedChatbotWrapper />
  169. }
  170. export default EmbeddedChatbot