refactor(playground): extract conversation message helpers

- move send, regenerate, and edit message list construction into focused utilities.
- keep the conversation hook focused on edit state and update dispatch.
This commit is contained in:
QuentinHsu
2026-05-30 09:30:47 +08:00
parent 1f3eb1e419
commit 0339e36246
3 changed files with 100 additions and 36 deletions
@@ -18,9 +18,9 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { useCallback, useState } from 'react'
import {
createLoadingAssistantMessage,
createUserMessage,
updateCurrentVersionContent,
appendUserMessagePair,
applyMessageEdit,
createRegeneratedMessages,
} from '../lib'
import type { Message } from '../types'
@@ -43,10 +43,7 @@ export function usePlaygroundConversation({
const handleSendMessage = useCallback(
(text: string) => {
const userMessage = createUserMessage(text)
const assistantMessage = createLoadingAssistantMessage()
const nextMessages = [...messages, userMessage, assistantMessage]
const nextMessages = appendUserMessagePair(messages, text)
updateMessages(nextMessages)
sendChat(nextMessages)
},
@@ -55,13 +52,8 @@ export function usePlaygroundConversation({
const handleRegenerateMessage = useCallback(
(message: Message) => {
const messageIndex = messages.findIndex((m) => m.key === message.key)
if (messageIndex === -1) return
const nextMessages = [
...messages.slice(0, messageIndex),
createLoadingAssistantMessage(),
]
const nextMessages = createRegeneratedMessages(messages, message.key)
if (!nextMessages) return
updateMessages(nextMessages)
sendChat(nextMessages)
@@ -83,33 +75,20 @@ export function usePlaygroundConversation({
(newContent: string, shouldSubmit: boolean) => {
if (!editingMessageKey) return
const messageIndex = messages.findIndex(
(message) => message.key === editingMessageKey
const editResult = applyMessageEdit(
messages,
editingMessageKey,
newContent,
shouldSubmit
)
if (messageIndex === -1) return
const updatedMessages = messages.map((message) => {
if (message.key !== editingMessageKey) {
return message
}
return updateCurrentVersionContent(message, newContent)
})
if (!editResult) return
setEditingMessageKey(null)
updateMessages(editResult.messages)
if (!shouldSubmit || updatedMessages[messageIndex].from !== 'user') {
updateMessages(updatedMessages)
return
if (editResult.shouldSend) {
sendChat(editResult.messages)
}
const nextMessages = [
...updatedMessages.slice(0, messageIndex + 1),
createLoadingAssistantMessage(),
]
updateMessages(nextMessages)
sendChat(nextMessages)
},
[editingMessageKey, messages, updateMessages, sendChat]
)
@@ -0,0 +1,84 @@
/*
Copyright (C) 2023-2026 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import type { Message } from '../types'
import {
createLoadingAssistantMessage,
createUserMessage,
updateCurrentVersionContent,
} from './message-utils'
type ApplyMessageEditResult = {
messages: Message[]
shouldSend: boolean
}
export function appendUserMessagePair(
messages: Message[],
content: string
): Message[] {
return [
...messages,
createUserMessage(content),
createLoadingAssistantMessage(),
]
}
export function createRegeneratedMessages(
messages: Message[],
messageKey: string
): Message[] | null {
const messageIndex = messages.findIndex((message) => message.key === messageKey)
if (messageIndex === -1) {
return null
}
return [...messages.slice(0, messageIndex), createLoadingAssistantMessage()]
}
export function applyMessageEdit(
messages: Message[],
messageKey: string,
content: string,
shouldSubmit: boolean
): ApplyMessageEditResult | null {
const messageIndex = messages.findIndex((message) => message.key === messageKey)
if (messageIndex === -1) {
return null
}
const updatedMessages = messages.map((message) =>
message.key === messageKey
? updateCurrentVersionContent(message, content)
: message
)
if (!shouldSubmit || updatedMessages[messageIndex].from !== 'user') {
return { messages: updatedMessages, shouldSend: false }
}
return {
messages: [
...updatedMessages.slice(0, messageIndex + 1),
createLoadingAssistantMessage(),
],
shouldSend: true,
}
}
+1
View File
@@ -25,3 +25,4 @@ export * from './storage'
export * from './message-styles'
export * from './stream-utils'
export * from './request-error-utils'
export * from './conversation-message-utils'