mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
perf(web): narrow message state subscriptions
- web/src/components/AssistantChat/messages/UserMessage.tsx now subscribes only to role, text, status, and localId instead of the entire message object to avoid re-renders caused by unrelated message state changes (hover/isLast/etc.). - web/src/components/AssistantChat/messages/SystemMessage.tsx now subscribes only to role, text, and icon for the same reason. - This reduces unnecessary renders observed in React DevTools without changing message UI or behavior.
This commit is contained in:
@@ -3,13 +3,19 @@ import { getEventPresentation } from '@/chat/presentation'
|
||||
import type { HappyChatMessageMetadata } from '@/lib/assistant-runtime'
|
||||
|
||||
export function HappySystemMessage() {
|
||||
const message = useAssistantState(({ message }) => message)
|
||||
if (message.role !== 'system') return null
|
||||
const role = useAssistantState(({ message }) => message.role)
|
||||
const text = useAssistantState(({ message }) => {
|
||||
if (message.role !== 'system') return ''
|
||||
return message.content[0]?.type === 'text' ? message.content[0].text : ''
|
||||
})
|
||||
const icon = useAssistantState(({ message }) => {
|
||||
if (message.role !== 'system') return null
|
||||
const custom = message.metadata.custom as Partial<HappyChatMessageMetadata> | undefined
|
||||
const event = custom?.kind === 'event' ? custom.event : undefined
|
||||
return event ? getEventPresentation(event).icon : null
|
||||
})
|
||||
|
||||
const text = message.content[0]?.type === 'text' ? message.content[0].text : ''
|
||||
const custom = message.metadata.custom as Partial<HappyChatMessageMetadata> | undefined
|
||||
const event = custom?.kind === 'event' ? custom.event : undefined
|
||||
const icon = event ? getEventPresentation(event).icon : null
|
||||
if (role !== 'system') return null
|
||||
|
||||
return (
|
||||
<div className="py-1">
|
||||
|
||||
@@ -6,14 +6,23 @@ import { MessageStatusIndicator } from '@/components/AssistantChat/messages/Mess
|
||||
|
||||
export function HappyUserMessage() {
|
||||
const ctx = useHappyChatContext()
|
||||
const message = useAssistantState(({ message }) => message)
|
||||
const role = useAssistantState(({ message }) => message.role)
|
||||
const text = useAssistantState(({ message }) => {
|
||||
if (message.role !== 'user') return ''
|
||||
return message.content.find((part) => part.type === 'text')?.text ?? ''
|
||||
})
|
||||
const status = useAssistantState(({ message }) => {
|
||||
if (message.role !== 'user') return undefined
|
||||
const custom = message.metadata.custom as Partial<HappyChatMessageMetadata> | undefined
|
||||
return custom?.status
|
||||
})
|
||||
const localId = useAssistantState(({ message }) => {
|
||||
if (message.role !== 'user') return null
|
||||
const custom = message.metadata.custom as Partial<HappyChatMessageMetadata> | undefined
|
||||
return custom?.localId ?? null
|
||||
})
|
||||
|
||||
if (message.role !== 'user') return null
|
||||
|
||||
const text = message.content.find((part) => part.type === 'text')?.text ?? ''
|
||||
const custom = message.metadata.custom as Partial<HappyChatMessageMetadata> | undefined
|
||||
const status = custom?.status
|
||||
const localId = custom?.localId
|
||||
if (role !== 'user') return null
|
||||
const canRetry = status === 'failed' && typeof localId === 'string' && Boolean(ctx.onRetryMessage)
|
||||
const onRetry = canRetry ? () => ctx.onRetryMessage!(localId) : undefined
|
||||
|
||||
|
||||
Reference in New Issue
Block a user