diff --git a/web/app/components/explore/sidebar/index.tsx b/web/app/components/explore/sidebar/index.tsx
index 2d44676100..5a9df13771 100644
--- a/web/app/components/explore/sidebar/index.tsx
+++ b/web/app/components/explore/sidebar/index.tsx
@@ -1,14 +1,15 @@
'use client'
-import React, { FC, useEffect, useState } from 'react'
+import type { FC } from 'react'
+import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
-import ExploreContext from '@/context/explore-context'
import cn from 'classnames'
import { useSelectedLayoutSegments } from 'next/navigation'
import Link from 'next/link'
-import Item from './app-nav-item'
-import { fetchInstalledAppList as doFetchInstalledAppList, uninstallApp, updatePinStatus } from '@/service/explore'
import Toast from '../../base/toast'
+import Item from './app-nav-item'
+import { fetchInstalledAppList as doFetchInstalledAppList, uninstallApp, updatePinStatus } from '@/service/explore'
+import ExploreContext from '@/context/explore-context'
import Confirm from '@/app/components/base/confirm'
const SelectedDiscoveryIcon = () => (
@@ -19,12 +20,12 @@ const SelectedDiscoveryIcon = () => (
const DiscoveryIcon = () => (
)
const SideBar: FC<{
- controlUpdateInstalledApps: number,
+ controlUpdateInstalledApps: number
}> = ({
controlUpdateInstalledApps,
}) => {
@@ -35,10 +36,10 @@ const SideBar: FC<{
const { installedApps, setInstalledApps } = useContext(ExploreContext)
const fetchInstalledAppList = async () => {
- const {installed_apps} : any = await doFetchInstalledAppList()
+ const { installed_apps }: any = await doFetchInstalledAppList()
setInstalledApps(installed_apps)
}
-
+
const [showConfirm, setShowConfirm] = useState(false)
const [currId, setCurrId] = useState('')
const handleDelete = async () => {
@@ -47,7 +48,7 @@ const SideBar: FC<{
setShowConfirm(false)
Toast.notify({
type: 'success',
- message: t('common.api.remove')
+ message: t('common.api.remove'),
})
fetchInstalledAppList()
}
@@ -56,7 +57,7 @@ const SideBar: FC<{
await updatePinStatus(id, isPinned)
Toast.notify({
type: 'success',
- message: t('common.api.success')
+ message: t('common.api.success'),
})
fetchInstalledAppList()
}
@@ -74,8 +75,8 @@ const SideBar: FC<{
{isDiscoverySelected ?
:
}
{t('explore.sidebar.discovery')}
@@ -86,12 +87,12 @@ const SideBar: FC<{
{t('explore.sidebar.workspace')}
- {installedApps.map(({id, is_pinned, uninstallable, app : { name, icon, icon_background }}) => {
+ {installedApps.map(({ id, is_pinned, uninstallable, app: { name, icon, icon_background } }) => {
return (
- -
)}
{showConfirm && (
- setShowConfirm(false)}
- onConfirm={handleDelete}
- onCancel={() => setShowConfirm(false)}
- />
- )}
+ setShowConfirm(false)}
+ onConfirm={handleDelete}
+ onCancel={() => setShowConfirm(false)}
+ />
+ )}
)
}
diff --git a/web/app/components/share/chat/index.tsx b/web/app/components/share/chat/index.tsx
index 8e5db6d850..9fe0d302d0 100644
--- a/web/app/components/share/chat/index.tsx
+++ b/web/app/components/share/chat/index.tsx
@@ -1,40 +1,39 @@
+/* eslint-disable @typescript-eslint/no-use-before-define */
'use client'
import type { FC } from 'react'
-import React, { useEffect, useState, useRef } from 'react'
+import React, { useEffect, useRef, useState } from 'react'
import cn from 'classnames'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import produce from 'immer'
import { useBoolean, useGetState } from 'ahooks'
+import AppUnavailable from '../../base/app-unavailable'
import useConversation from './hooks/use-conversation'
+import s from './style.module.css'
import { ToastContext } from '@/app/components/base/toast'
import Sidebar from '@/app/components/share/chat/sidebar'
import ConfigSence from '@/app/components/share/chat/config-scence'
import Header from '@/app/components/share/header'
-import { fetchAppInfo, fetchAppParams, fetchChatList, fetchConversations, sendChatMessage, updateFeedback, fetchSuggestedQuestions } from '@/service/share'
+import { fetchAppInfo, fetchAppParams, fetchChatList, fetchConversations, fetchSuggestedQuestions, sendChatMessage, updateFeedback } from '@/service/share'
import type { ConversationItem, SiteInfo } from '@/models/share'
-import type { PromptConfig } from '@/models/debug'
+import type { PromptConfig, SuggestedQuestionsAfterAnswerConfig } from '@/models/debug'
import type { Feedbacktype, IChatItem } from '@/app/components/app/chat'
import Chat from '@/app/components/app/chat'
import { changeLanguage } from '@/i18n/i18next-config'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import Loading from '@/app/components/base/loading'
import { replaceStringWithValues } from '@/app/components/app/configuration/prompt-value-panel'
-import AppUnavailable from '../../base/app-unavailable'
import { userInputsFormToPromptVariables } from '@/utils/model-config'
-import { SuggestedQuestionsAfterAnswerConfig } from '@/models/debug'
-import { InstalledApp } from '@/models/explore'
-
-import s from './style.module.css'
+import type { InstalledApp } from '@/models/explore'
export type IMainProps = {
- isInstalledApp?: boolean,
- installedAppInfo? : InstalledApp
+ isInstalledApp?: boolean
+ installedAppInfo?: InstalledApp
}
const Main: FC
= ({
isInstalledApp = false,
- installedAppInfo
+ installedAppInfo,
}) => {
const { t } = useTranslation()
const media = useBreakpoints()
@@ -53,7 +52,7 @@ const Main: FC = ({
const [plan, setPlan] = useState('basic') // basic/plus/pro
// in mobile, show sidebar by click button
const [isShowSidebar, { setTrue: showSidebar, setFalse: hideSidebar }] = useBoolean(false)
- // Can Use metadata(https://beta.nextjs.org/docs/api-reference/metadata) to set title. But it only works in server side client.
+ // Can Use metadata(https://beta.nextjs.org/docs/api-reference/metadata) to set title. But it only works in server side client.
useEffect(() => {
if (siteInfo?.title) {
if (plan !== 'basic')
@@ -61,7 +60,6 @@ const Main: FC = ({
else
document.title = `${siteInfo.title} - Powered by Dify`
}
-
}, [siteInfo?.title, plan])
/*
@@ -81,7 +79,7 @@ const Main: FC = ({
resetNewConversationInputs,
setCurrInputs,
setNewConversationInfo,
- setExistConversationInfo
+ setExistConversationInfo,
} = useConversation()
const [hasMore, setHasMore] = useState(false)
const onMoreLoaded = ({ data: conversations, has_more }: any) => {
@@ -101,9 +99,9 @@ const Main: FC = ({
setChatList(generateNewChatListWithOpenstatement('', inputs))
}
const hasSetInputs = (() => {
- if (!isNewConversation) {
+ if (!isNewConversation)
return true
- }
+
return isChatStarted
})()
@@ -111,7 +109,8 @@ const Main: FC = ({
const conversationIntroduction = currConversationInfo?.introduction || ''
const handleConversationSwitch = () => {
- if (!inited) return
+ if (!inited)
+ return
if (!appId) {
// wait for appId
setTimeout(handleConversationSwitch, 100)
@@ -130,12 +129,13 @@ const Main: FC = ({
name: item?.name || '',
introduction: notSyncToStateIntroduction,
})
- } else {
+ }
+ else {
notSyncToStateInputs = newConversationInputs
setCurrInputs(notSyncToStateInputs)
}
- // update chat list of current conversation
+ // update chat list of current conversation
if (!isNewConversation && !conversationIdChangeBecauseOfNew && !isResponsing) {
fetchChatList(currConversationId, isInstalledApp, installedAppInfo?.id).then((res: any) => {
const { data } = res
@@ -158,9 +158,8 @@ const Main: FC = ({
})
}
- if (isNewConversation && isChatStarted) {
+ if (isNewConversation && isChatStarted)
setChatList(generateNewChatListWithOpenstatement())
- }
setControlFocus(Date.now())
}
@@ -170,7 +169,8 @@ const Main: FC = ({
if (id === '-1') {
createNewChat()
setConversationIdChangeBecauseOfNew(true)
- } else {
+ }
+ else {
setConversationIdChangeBecauseOfNew(false)
}
// trigger handleConversationSwitch
@@ -186,9 +186,8 @@ const Main: FC = ({
const chatListDomRef = useRef(null)
useEffect(() => {
// scroll to bottom
- if (chatListDomRef.current) {
+ if (chatListDomRef.current)
chatListDomRef.current.scrollTop = chatListDomRef.current.scrollHeight
- }
}, [chatList, currConversationId])
// user can not edit inputs if user had send message
const canEditInpus = !chatList.some(item => item.isAnswer === false) && isNewConversation
@@ -196,15 +195,15 @@ const Main: FC = ({
// if new chat is already exist, do not create new chat
abortController?.abort()
setResponsingFalse()
- if (conversationList.some(item => item.id === '-1')) {
+ if (conversationList.some(item => item.id === '-1'))
return
- }
- setConversationList(produce(conversationList, draft => {
+
+ setConversationList(produce(conversationList, (draft) => {
draft.unshift({
id: '-1',
name: t('share.chat.newChatDefaultName'),
inputs: newConversationInputs,
- introduction: conversationIntroduction
+ introduction: conversationIntroduction,
})
}))
}
@@ -213,36 +212,37 @@ const Main: FC = ({
const generateNewChatListWithOpenstatement = (introduction?: string, inputs?: Record | null) => {
let caculatedIntroduction = introduction || conversationIntroduction || ''
const caculatedPromptVariables = inputs || currInputs || null
- if (caculatedIntroduction && caculatedPromptVariables) {
+ if (caculatedIntroduction && caculatedPromptVariables)
caculatedIntroduction = replaceStringWithValues(caculatedIntroduction, promptConfig?.prompt_variables || [], caculatedPromptVariables)
- }
+
// console.log(isPublicVersion)
const openstatement = {
id: `${Date.now()}`,
content: caculatedIntroduction,
isAnswer: true,
feedbackDisabled: true,
- isOpeningStatement: isPublicVersion
+ isOpeningStatement: isPublicVersion,
}
- if (caculatedIntroduction) {
+ if (caculatedIntroduction)
return [openstatement]
- }
+
return []
}
const fetchInitData = () => {
- return Promise.all([isInstalledApp ? {
- app_id: installedAppInfo?.id,
- site: {
- title: installedAppInfo?.app.name,
- prompt_public: false,
- copyright: ''
- },
- plan: 'basic',
- }: fetchAppInfo(), fetchConversations(isInstalledApp, installedAppInfo?.id), fetchAppParams(isInstalledApp, installedAppInfo?.id)])
+ return Promise.all([isInstalledApp
+ ? {
+ app_id: installedAppInfo?.id,
+ site: {
+ title: installedAppInfo?.app.name,
+ prompt_public: false,
+ copyright: '',
+ },
+ plan: 'basic',
+ }
+ : fetchAppInfo(), fetchConversations(isInstalledApp, installedAppInfo?.id), fetchAppParams(isInstalledApp, installedAppInfo?.id)])
}
-
// init
useEffect(() => {
(async () => {
@@ -255,16 +255,16 @@ const Main: FC = ({
setIsPublicVersion(tempIsPublicVersion)
const prompt_template = ''
// handle current conversation id
- const { data: conversations, has_more } = conversationData as { data: ConversationItem[], has_more: boolean }
+ const { data: conversations, has_more } = conversationData as { data: ConversationItem[]; has_more: boolean }
const _conversationId = getConversationIdFromStorage(appId)
const isNotNewConversation = conversations.some(item => item.id === _conversationId)
setHasMore(has_more)
// fetch new conversation info
const { user_input_form, opening_statement: introduction, suggested_questions_after_answer }: any = appParams
const prompt_variables = userInputsFormToPromptVariables(user_input_form)
- if(siteInfo.default_language) {
+ if (siteInfo.default_language)
changeLanguage(siteInfo.default_language)
- }
+
setNewConversationInfo({
name: t('share.chat.newChatDefaultName'),
introduction,
@@ -272,20 +272,22 @@ const Main: FC = ({
setSiteInfo(siteInfo as SiteInfo)
setPromptConfig({
prompt_template,
- prompt_variables: prompt_variables,
+ prompt_variables,
} as PromptConfig)
setSuggestedQuestionsAfterAnswerConfig(suggested_questions_after_answer)
setConversationList(conversations as ConversationItem[])
- if (isNotNewConversation) {
+ if (isNotNewConversation)
setCurrConversationId(_conversationId, appId, false)
- }
+
setInited(true)
- } catch (e: any) {
+ }
+ catch (e: any) {
if (e.status === 404) {
setAppUnavailable(true)
- } else {
+ }
+ else {
setIsUnknwonReason(true)
setAppUnavailable(true)
}
@@ -303,21 +305,20 @@ const Main: FC = ({
const checkCanSend = () => {
const prompt_variables = promptConfig?.prompt_variables
const inputs = currInputs
- if (!inputs || !prompt_variables || prompt_variables?.length === 0) {
+ if (!inputs || !prompt_variables || prompt_variables?.length === 0)
return true
- }
+
let hasEmptyInput = false
const requiredVars = prompt_variables?.filter(({ key, name, required }) => {
const res = (!key || !key.trim()) || (!name || !name.trim()) || (required || required === undefined || required === null)
return res
}) || [] // compatible with old version
requiredVars.forEach(({ key }) => {
- if (hasEmptyInput) {
+ if (hasEmptyInput)
return
- }
- if (!inputs?.[key]) {
+
+ if (!inputs?.[key])
hasEmptyInput = true
- }
})
if (hasEmptyInput) {
@@ -378,9 +379,8 @@ const Main: FC = ({
onData: (message: string, isFirstMessage: boolean, { conversationId: newConversationId, messageId }: any) => {
responseItem.content = responseItem.content + message
responseItem.id = messageId
- if (isFirstMessage && newConversationId) {
+ if (isFirstMessage && newConversationId)
tempNewConversationId = newConversationId
- }
// closesure new list is outdated.
const newListWithAnswer = produce(
@@ -395,9 +395,9 @@ const Main: FC = ({
},
async onCompleted(hasError?: boolean) {
setResponsingFalse()
- if (hasError) {
+ if (hasError)
return
- }
+
let currChatList = conversationList
if (getConversationIdChangeBecauseOfNew()) {
const { data: conversations, has_more }: any = await fetchConversations(isInstalledApp, installedAppInfo?.id)
@@ -418,7 +418,7 @@ const Main: FC = ({
onError() {
setResponsingFalse()
// role back placeholder answer
- setChatList(produce(getChatList(), draft => {
+ setChatList(produce(getChatList(), (draft) => {
draft.splice(draft.findIndex(item => item.id === placeholderAnswerId), 1)
}))
},
@@ -476,18 +476,20 @@ const Main: FC = ({
onCreateNewChat={() => handleConversationIdChange('-1')}
/>
)}
-
+
{/* {isNewConversation ? 'new' : 'exist'}
{JSON.stringify(newConversationInputs ? newConversationInputs : {})}
{JSON.stringify(existConversationInputs ? existConversationInputs : {})} */}
-
{/* sidebar */}
{!isMobile && renderSidebar()}
@@ -504,8 +506,8 @@ const Main: FC
= ({
{/* main */}
= ({
{
hasSetInputs && (
-