@@ -2,8 +2,8 @@ import React, { forwardRef, useImperativeHandle, useLayoutEffect, useRef, useSta
22import classNames from 'classnames' ;
33
44import { 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' ;
77import { useContext } from '../useContext' ;
88import './index.scss' ;
99
@@ -13,6 +13,8 @@ export interface IContentProps {
1313 scrollable ?: boolean ;
1414 onRegenerate ?: ( data : MessageEntity , prompt : PromptEntity ) => void ;
1515 onStop ?: ( data : MessageEntity , prompt : PromptEntity ) => void ;
16+ replacePrompt ?: ( promptProps : IPromptProps ) => React . ReactNode ;
17+ replaceMessage ?: ( messageProps : IMessageProps ) => React . ReactNode ;
1618}
1719
1820export interface IContentRef {
@@ -21,7 +23,7 @@ export interface IContentRef {
2123}
2224
2325const Content = forwardRef < IContentRef , IContentProps > ( function (
24- { data, placeholder, scrollable = true , onRegenerate, onStop } ,
26+ { data, placeholder, scrollable = true , onRegenerate, onStop, replacePrompt , replaceMessage } ,
2527 forwardedRef
2628) {
2729 const { maxRegenerateCount, copy, regenerate } = useContext ( ) ;
@@ -107,34 +109,45 @@ const Content = forwardRef<IContentRef, IContentProps>(function (
107109 { data . map ( ( row , idx ) => {
108110 const defaultRegenerate =
109111 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+ } ;
110139 return (
111140 < 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+ ) }
138151 </ React . Fragment >
139152 ) ;
140153 } ) }
0 commit comments