@@ -137,7 +137,8 @@ export function Chat({ preSelectedAgentId }: ChatProps = {}) {
137137 // Session list will be refreshed when user opens the drawer (on-demand)
138138 } ,
139139 } ) ;
140- const contentToText = ( content : SimpleContentItem ) : string => {
140+ // Memoized content conversion to prevent recreation on every render
141+ const contentToText = React . useCallback ( ( content : SimpleContentItem ) : string => {
141142 if ( content . type === 'input_text' || content . type === 'output_text' ) {
142143 return content . text ;
143144 }
@@ -151,44 +152,33 @@ export function Chat({ preSelectedAgentId }: ChatProps = {}) {
151152 }
152153
153154 return '' ;
154- } ;
155-
156- const multipleContentToText = React . useCallback ( ( content : SimpleContentItem [ ] ) : string => {
157- return content . map ( ( m ) => contentToText ( m ) ) . join ( '\n' ) ;
158155 } , [ ] ) ;
159156
160- // Convert our chat messages to PatternFly format
161- const messages = React . useMemo (
162- ( ) =>
163- chatMessages . map (
164- ( msg ) : MessageProps => ( {
165- id : msg . id ,
166- role : msg . role === 'user' ? 'user' : 'bot' ,
167- content : multipleContentToText ( msg . content ) ,
168- name : msg . role === 'user' ? 'You' : 'Agent' ,
169- timestamp : msg . timestamp . toLocaleString ( ) ,
170- avatar : msg . role === 'user' ? userAvatar : botAvatar ,
171- avatarProps : { isBordered : true } ,
172- isLoading :
173- msg . role === 'assistant' &&
174- isLoading &&
175- msg . id === chatMessages [ chatMessages . length - 1 ] ?. id ,
176- } )
177- ) ,
178- [ chatMessages , isLoading , multipleContentToText ]
157+ const multipleContentToText = React . useCallback (
158+ ( content : SimpleContentItem [ ] ) : string => {
159+ return content . map ( ( m ) => contentToText ( m ) ) . join ( '\n' ) ;
160+ } ,
161+ [ contentToText ]
179162 ) ;
180163
181- const displayMode = ChatbotDisplayMode . embedded ;
164+ // Convert our chat messages to PatternFly format
165+ const messages = React . useMemo ( ( ) => {
166+ const lastMessageId = chatMessages [ chatMessages . length - 1 ] ?. id ;
167+ return chatMessages . map (
168+ ( msg ) : MessageProps => ( {
169+ id : msg . id ,
170+ role : msg . role === 'user' ? 'user' : 'bot' ,
171+ content : multipleContentToText ( msg . content ) ,
172+ name : msg . role === 'user' ? 'You' : 'Agent' ,
173+ timestamp : msg . timestamp . toLocaleString ( ) ,
174+ avatar : msg . role === 'user' ? userAvatar : botAvatar ,
175+ avatarProps : { isBordered : true } ,
176+ isLoading : msg . role === 'assistant' && isLoading && msg . id === lastMessageId ,
177+ } )
178+ ) ;
179+ } , [ chatMessages , isLoading , multipleContentToText ] ) ;
182180
183- // Track message composer width to align suggestions with it
184- useEffect ( ( ) => {
185- // Keeping observer attached in case of future width-based logic
186- if ( ! composerRef . current ) return ;
187- const el = composerRef . current ;
188- const ro = new ResizeObserver ( ( ) => { } ) ;
189- ro . observe ( el ) ;
190- return ( ) => ro . disconnect ( ) ;
191- } , [ ] ) ;
181+ const displayMode = ChatbotDisplayMode . embedded ;
192182
193183 // Load demo questions for the selected agent (if template-backed)
194184 useEffect ( ( ) => {
0 commit comments