Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dify
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
dify
Commits
f2b2effc
Unverified
Commit
f2b2effc
authored
Jan 25, 2024
by
zxhlyh
Committed by
GitHub
Jan 25, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: typing delay (#2200)
parent
301e0496
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
201 additions
and
161 deletions
+201
-161
index.tsx
web/app/components/app/chat/answer/index.tsx
+9
-7
index.tsx
web/app/components/app/chat/index.tsx
+76
-73
index.tsx
web/app/components/app/chat/question/index.tsx
+2
-2
use-conversation.ts
web/app/components/share/chat/hooks/use-conversation.ts
+3
-3
index.tsx
web/app/components/share/chat/index.tsx
+101
-73
index.tsx
web/app/components/share/chat/sidebar/index.tsx
+10
-3
No files found.
web/app/components/app/chat/answer/index.tsx
View file @
f2b2effc
...
...
@@ -43,6 +43,7 @@ const IconWrapper: FC<{ children: React.ReactNode | string }> = ({ children }) =
}
export
type
IAnswerProps
=
{
item
:
IChatItem
index
:
number
feedbackDisabled
:
boolean
isHideFeedbackEdit
:
boolean
onQueryChange
:
(
query
:
string
)
=>
void
...
...
@@ -59,14 +60,15 @@ export type IAnswerProps = {
supportAnnotation
?:
boolean
appId
?:
string
question
:
string
onAnnotationEdited
?:
(
question
:
string
,
answer
:
string
)
=>
void
onAnnotationAdded
?:
(
annotationId
:
string
,
authorName
:
string
,
question
:
string
,
answer
:
string
)
=>
void
onAnnotationRemoved
?:
()
=>
void
onAnnotationEdited
?:
(
question
:
string
,
answer
:
string
,
index
:
number
)
=>
void
onAnnotationAdded
?:
(
annotationId
:
string
,
authorName
:
string
,
question
:
string
,
answer
:
string
,
index
:
number
)
=>
void
onAnnotationRemoved
?:
(
index
:
number
)
=>
void
allToolIcons
?:
Record
<
string
,
string
|
Emoji
>
}
// The component needs to maintain its own state to control whether to display input component
const
Answer
:
FC
<
IAnswerProps
>
=
({
item
,
index
,
onQueryChange
,
feedbackDisabled
=
false
,
isHideFeedbackEdit
=
false
,
...
...
@@ -340,9 +342,9 @@ const Answer: FC<IAnswerProps> = ({
cached=
{
hasAnnotation
}
query=
{
question
}
answer=
{
content
}
onAdded=
{
(
id
,
authorName
)
=>
onAnnotationAdded
?.(
id
,
authorName
,
question
,
content
)
}
onAdded=
{
(
id
,
authorName
)
=>
onAnnotationAdded
?.(
id
,
authorName
,
question
,
content
,
index
)
}
onEdit=
{
()
=>
setIsShowReplyModal
(
true
)
}
onRemoved=
{
onAnnotationRemoved
!
}
onRemoved=
{
()
=>
onAnnotationRemoved
!
(
index
)
}
/>
)
}
...
...
@@ -351,8 +353,8 @@ const Answer: FC<IAnswerProps> = ({
onHide=
{
()
=>
setIsShowReplyModal
(
false
)
}
query=
{
question
}
answer=
{
content
}
onEdited=
{
onAnnotationEdited
!
}
onAdded=
{
onAnnotationAdded
!
}
onEdited=
{
(
editedQuery
,
editedAnswer
)
=>
onAnnotationEdited
!
(
editedQuery
,
editedAnswer
,
index
)
}
onAdded=
{
(
annotationId
,
authorName
,
editedQuery
,
editedAnswer
)
=>
onAnnotationAdded
!
(
annotationId
,
authorName
,
editedQuery
,
editedAnswer
,
index
)
}
appId=
{
appId
!
}
messageId=
{
id
}
annotationId=
{
annotation
?.
id
||
''
}
...
...
web/app/components/app/chat/index.tsx
View file @
f2b2effc
'use client'
import
type
{
FC
,
ReactNode
}
from
'react'
import
React
,
{
useEffect
,
useLayoutEffect
,
useRef
,
useState
}
from
'react'
import
React
,
{
use
Callback
,
use
Effect
,
useLayoutEffect
,
useRef
,
useState
}
from
'react'
import
Textarea
from
'rc-textarea'
import
{
useContext
}
from
'use-context-selector'
import
cn
from
'classnames'
...
...
@@ -197,6 +197,76 @@ const Chat: FC<IChatProps> = ({
logError
(
t
(
'common.voiceInput.notAllow'
))
})
}
const
handleQueryChangeFromAnswer
=
useCallback
((
val
:
string
)
=>
{
onQueryChange
(
val
)
handleSend
(
val
)
},
[])
const
handleAnnotationEdited
=
useCallback
((
query
:
string
,
answer
:
string
,
index
:
number
)
=>
{
onChatListChange
?.(
chatList
.
map
((
item
,
i
)
=>
{
if
(
i
===
index
-
1
)
{
return
{
...
item
,
content
:
query
,
}
}
if
(
i
===
index
)
{
return
{
...
item
,
content
:
answer
,
annotation
:
{
...
item
.
annotation
,
logAnnotation
:
undefined
,
}
as
any
,
}
}
return
item
}))
},
[])
const
handleAnnotationAdded
=
useCallback
((
annotationId
:
string
,
authorName
:
string
,
query
:
string
,
answer
:
string
,
index
:
number
)
=>
{
onChatListChange
?.(
chatList
.
map
((
item
,
i
)
=>
{
if
(
i
===
index
-
1
)
{
return
{
...
item
,
content
:
query
,
}
}
if
(
i
===
index
)
{
const
answerItem
=
{
...
item
,
content
:
item
.
content
,
annotation
:
{
id
:
annotationId
,
authorName
,
logAnnotation
:
{
content
:
answer
,
account
:
{
id
:
''
,
name
:
authorName
,
email
:
''
,
},
},
}
as
Annotation
,
}
return
answerItem
}
return
item
}))
},
[])
const
handleAnnotationRemoved
=
useCallback
((
index
:
number
)
=>
{
onChatListChange
?.(
chatList
.
map
((
item
,
i
)
=>
{
if
(
i
===
index
)
{
return
{
...
item
,
content
:
item
.
content
,
annotation
:
{
...(
item
.
annotation
||
{}),
id
:
''
,
}
as
Annotation
,
}
}
return
item
}))
},
[])
return
(
<
div
className=
{
cn
(
'px-3.5'
,
'h-full'
)
}
>
...
...
@@ -210,10 +280,8 @@ const Chat: FC<IChatProps> = ({
return
<
Answer
key=
{
item
.
id
}
item=
{
item
}
onQueryChange=
{
(
val
)
=>
{
onQueryChange
(
val
)
handleSend
(
val
)
}
}
index=
{
index
}
onQueryChange=
{
handleQueryChangeFromAnswer
}
feedbackDisabled=
{
feedbackDisabled
}
isHideFeedbackEdit=
{
isHideFeedbackEdit
}
onFeedback=
{
onFeedback
}
...
...
@@ -228,72 +296,9 @@ const Chat: FC<IChatProps> = ({
supportAnnotation=
{
supportAnnotation
}
appId=
{
appId
}
question=
{
chatList
[
index
-
1
]?.
content
}
onAnnotationEdited=
{
(
query
,
answer
)
=>
{
onChatListChange
?.(
chatList
.
map
((
item
,
i
)
=>
{
if
(
i
===
index
-
1
)
{
return
{
...
item
,
content
:
query
,
}
}
if
(
i
===
index
)
{
return
{
...
item
,
content
:
answer
,
annotation
:
{
...
item
.
annotation
,
logAnnotation
:
undefined
,
}
as
any
,
}
}
return
item
}))
}
}
onAnnotationAdded=
{
(
annotationId
,
authorName
,
query
,
answer
)
=>
{
onChatListChange
?.(
chatList
.
map
((
item
,
i
)
=>
{
if
(
i
===
index
-
1
)
{
return
{
...
item
,
content
:
query
,
}
}
if
(
i
===
index
)
{
const
answerItem
=
{
...
item
,
content
:
item
.
content
,
annotation
:
{
id
:
annotationId
,
authorName
,
logAnnotation
:
{
content
:
answer
,
account
:
{
id
:
''
,
name
:
authorName
,
email
:
''
,
},
},
}
as
Annotation
,
}
return
answerItem
}
return
item
}))
}
}
onAnnotationRemoved=
{
()
=>
{
onChatListChange
?.(
chatList
.
map
((
item
,
i
)
=>
{
if
(
i
===
index
)
{
return
{
...
item
,
content
:
item
.
content
,
annotation
:
{
...(
item
.
annotation
||
{}),
id
:
''
,
}
as
Annotation
,
}
}
return
item
}))
}
}
onAnnotationEdited=
{
handleAnnotationEdited
}
onAnnotationAdded=
{
handleAnnotationAdded
}
onAnnotationRemoved=
{
handleAnnotationRemoved
}
allToolIcons=
{
allToolIcons
}
/>
}
...
...
@@ -307,8 +312,6 @@ const Chat: FC<IChatProps> = ({
item=
{
item
}
isShowPromptLog=
{
isShowPromptLog
}
isResponsing=
{
isResponsing
}
// ['https://placekitten.com/360/360', 'https://placekitten.com/360/640']
imgSrcs=
{
(
item
.
message_files
&&
item
.
message_files
?.
length
>
0
)
?
item
.
message_files
.
map
(
item
=>
item
.
url
)
:
[]
}
/>
)
})
}
...
...
web/app/components/app/chat/question/index.tsx
View file @
f2b2effc
...
...
@@ -13,14 +13,14 @@ import ImageGallery from '@/app/components/base/image-gallery'
type
IQuestionProps
=
Pick
<
IChatItem
,
'id'
|
'content'
|
'more'
|
'useCurrentUserAvatar'
>
&
{
isShowPromptLog
?:
boolean
item
:
IChatItem
imgSrcs
?:
string
[]
isResponsing
?:
boolean
}
const
Question
:
FC
<
IQuestionProps
>
=
({
id
,
content
,
imgSrcs
,
more
,
useCurrentUserAvatar
,
isShowPromptLog
,
item
,
isResponsing
})
=>
{
const
Question
:
FC
<
IQuestionProps
>
=
({
id
,
content
,
more
,
useCurrentUserAvatar
,
isShowPromptLog
,
item
,
isResponsing
})
=>
{
const
{
userProfile
}
=
useContext
(
AppContext
)
const
userName
=
userProfile
?.
name
const
ref
=
useRef
(
null
)
const
imgSrcs
=
item
.
message_files
?.
map
(
item
=>
item
.
url
)
return
(
<
div
className=
{
`flex items-start justify-end ${isShowPromptLog && 'first-of-type:pt-[14px]'}`
}
key=
{
id
}
ref=
{
ref
}
>
...
...
web/app/components/share/chat/hooks/use-conversation.ts
View file @
f2b2effc
import
{
useState
}
from
'react'
import
{
use
Callback
,
use
State
}
from
'react'
import
produce
from
'immer'
import
{
useGetState
}
from
'ahooks'
import
type
{
ConversationItem
}
from
'@/models/share'
...
...
@@ -11,7 +11,7 @@ function useConversation() {
const
[
pinnedConversationList
,
setPinnedConversationList
]
=
useState
<
ConversationItem
[]
>
([])
const
[
currConversationId
,
doSetCurrConversationId
,
getCurrConversationId
]
=
useGetState
<
string
>
(
'-1'
)
// when set conversation id, we do not have set appId
const
setCurrConversationId
=
(
id
:
string
,
appId
:
string
,
isSetToLocalStroge
=
true
,
newConversationName
=
''
)
=>
{
const
setCurrConversationId
=
useCallback
(
(
id
:
string
,
appId
:
string
,
isSetToLocalStroge
=
true
,
newConversationName
=
''
)
=>
{
doSetCurrConversationId
(
id
)
if
(
isSetToLocalStroge
&&
id
!==
'-1'
)
{
// conversationIdInfo: {[appId1]: conversationId1, [appId2]: conversationId2}
...
...
@@ -19,7 +19,7 @@ function useConversation() {
conversationIdInfo
[
appId
]
=
id
globalThis
.
localStorage
?.
setItem
(
storageConversationIdKey
,
JSON
.
stringify
(
conversationIdInfo
))
}
}
}
,
[
doSetCurrConversationId
])
const
getConversationIdFromStorage
=
(
appId
:
string
)
=>
{
const
conversationIdInfo
=
globalThis
.
localStorage
?.
getItem
(
storageConversationIdKey
)
?
JSON
.
parse
(
globalThis
.
localStorage
?.
getItem
(
storageConversationIdKey
)
||
''
)
:
{}
...
...
web/app/components/share/chat/index.tsx
View file @
f2b2effc
This diff is collapsed.
Click to expand it.
web/app/components/share/chat/sidebar/index.tsx
View file @
f2b2effc
import
React
,
{
useEffect
,
useState
}
from
'react'
import
React
,
{
use
Callback
,
use
Effect
,
useState
}
from
'react'
import
type
{
FC
}
from
'react'
import
{
useTranslation
}
from
'react-i18next'
import
{
...
...
@@ -76,6 +76,13 @@ const Sidebar: FC<ISidebarProps> = ({
checkHasPinned
()
},
[
controlUpdateList
])
const
handleUnpin
=
useCallback
((
id
:
string
)
=>
{
onUnpin
(
id
)
},
[
onUnpin
])
const
handlePin
=
useCallback
((
id
:
string
)
=>
{
onPin
(
id
)
},
[
onPin
])
const
maxListHeight
=
(
isInstalledApp
)
?
'max-h-[30vh]'
:
'max-h-[40vh]'
return
(
...
...
@@ -119,7 +126,7 @@ const Sidebar: FC<ISidebarProps> = ({
onMoreLoaded=
{
onPinnedMoreLoaded
}
isNoMore=
{
isPinnedNoMore
}
isPinned=
{
true
}
onPinChanged=
{
id
=>
onUnpin
(
id
)
}
onPinChanged=
{
handleUnpin
}
controlUpdate=
{
controlUpdateList
+
1
}
onDelete=
{
onDelete
}
/>
...
...
@@ -142,7 +149,7 @@ const Sidebar: FC<ISidebarProps> = ({
onMoreLoaded=
{
onMoreLoaded
}
isNoMore=
{
isNoMore
}
isPinned=
{
false
}
onPinChanged=
{
id
=>
onPin
(
id
)
}
onPinChanged=
{
handlePin
}
controlUpdate=
{
controlUpdateList
+
1
}
onDelete=
{
onDelete
}
/>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment