@@ -2,8 +2,8 @@ import React, { forwardRef, useImperativeHandle, useLayoutEffect, useRef, useSta
2
2
import classNames from 'classnames' ;
3
3
4
4
import { Message as MessageEntity , MessageStatus , Prompt as PromptEntity } from '../entity' ;
5
- import Message from '../message' ;
6
- import Prompt from '../prompt' ;
5
+ import Message , { IMessageProps } from '../message' ;
6
+ import Prompt , { IPromptProps } from '../prompt' ;
7
7
import { useContext } from '../useContext' ;
8
8
import './index.scss' ;
9
9
@@ -13,6 +13,8 @@ export interface IContentProps {
13
13
scrollable ?: boolean ;
14
14
onRegenerate ?: ( data : MessageEntity , prompt : PromptEntity ) => void ;
15
15
onStop ?: ( data : MessageEntity , prompt : PromptEntity ) => void ;
16
+ replacePrompt ?: ( promptProps : IPromptProps ) => React . ReactNode ;
17
+ replaceMessage ?: ( messageProps : IMessageProps ) => React . ReactNode ;
16
18
}
17
19
18
20
export interface IContentRef {
@@ -21,7 +23,7 @@ export interface IContentRef {
21
23
}
22
24
23
25
const Content = forwardRef < IContentRef , IContentProps > ( function (
24
- { data, placeholder, scrollable = true , onRegenerate, onStop } ,
26
+ { data, placeholder, scrollable = true , onRegenerate, onStop, replacePrompt , replaceMessage } ,
25
27
forwardedRef
26
28
) {
27
29
const { maxRegenerateCount, copy, regenerate } = useContext ( ) ;
@@ -107,34 +109,45 @@ const Content = forwardRef<IContentRef, IContentProps>(function (
107
109
{ data . map ( ( row , idx ) => {
108
110
const defaultRegenerate =
109
111
idx === data . length - 1 && row . messages . length < maxRegenerateCount ;
112
+ const messageProps : IMessageProps = {
113
+ prompt : row ,
114
+ data : row . messages ,
115
+ regenerate :
116
+ typeof regenerate === 'function'
117
+ ? regenerate ( row , idx , data )
118
+ : regenerate ?? defaultRegenerate ,
119
+ copy,
120
+ onRegenerate : ( message ) => onRegenerate ?.( message , row ) ,
121
+ onStop : ( message ) => onStop ?.( message , row ) ,
122
+ onLazyRendered : ( renderFn ) => {
123
+ // 在触发懒加载之前判断是否在底部,如果是则加载完成后滚动到底部
124
+ const scrolledToBottom = checkIfScrolledToBottom ( ) ;
125
+ renderFn ( ) . then ( ( ) => {
126
+ window . requestAnimationFrame ( ( ) => {
127
+ setIsStickyAtBottom ( scrolledToBottom ) ;
128
+ if ( scrolledToBottom && containerRef . current ) {
129
+ containerRef . current . scrollTop =
130
+ containerRef . current . scrollHeight ;
131
+ }
132
+ } ) ;
133
+ } ) ;
134
+ } ,
135
+ } ;
136
+ const promptProps : IPromptProps = {
137
+ data : row ,
138
+ } ;
110
139
return (
111
140
< React . Fragment key = { row . id } >
112
- < Prompt data = { row } />
113
- < Message
114
- prompt = { row }
115
- data = { row . messages }
116
- regenerate = {
117
- typeof regenerate === 'function'
118
- ? regenerate ( row , idx , data )
119
- : regenerate ?? defaultRegenerate
120
- }
121
- copy = { copy }
122
- onRegenerate = { ( message ) => onRegenerate ?.( message , row ) }
123
- onStop = { ( message ) => onStop ?.( message , row ) }
124
- onLazyRendered = { ( renderFn ) => {
125
- // 在触发懒加载之前判断是否在底部,如果是则加载完成后滚动到底部
126
- const scrolledToBottom = checkIfScrolledToBottom ( ) ;
127
- renderFn ( ) . then ( ( ) => {
128
- window . requestAnimationFrame ( ( ) => {
129
- setIsStickyAtBottom ( scrolledToBottom ) ;
130
- if ( scrolledToBottom && containerRef . current ) {
131
- containerRef . current . scrollTop =
132
- containerRef . current . scrollHeight ;
133
- }
134
- } ) ;
135
- } ) ;
136
- } }
137
- />
141
+ { replacePrompt ? (
142
+ replacePrompt ( promptProps )
143
+ ) : (
144
+ < Prompt { ...promptProps } />
145
+ ) }
146
+ { replaceMessage ? (
147
+ replaceMessage ( messageProps )
148
+ ) : (
149
+ < Message { ...messageProps } />
150
+ ) }
138
151
</ React . Fragment >
139
152
) ;
140
153
} ) }
0 commit comments