use-send-multiple-message.ts
Overview
The use-send-multiple-message.ts file defines a custom React hook named useSendMultipleChatMessage that manages sending chat messages concurrently across multiple chat boxes. It handles composing, sending, and updating chat messages in real-time, including support for streaming responses from the server, file upload integration, and aborting ongoing requests.
This hook is designed for chat applications where a single user input can be broadcast to multiple chat contexts (chat boxes) simultaneously. It manages message state per chat box, interacts with server APIs to send messages and receive streaming answers, and provides utility functions to update UI components accordingly.
Detailed Explanation
useSendMultipleChatMessage(controller: AbortController, chatBoxIds: string[])
Description
A React hook to manage multiple chat messages sending processes concurrently for different chat boxes. It maintains message states, supports streaming answers, handles file attachments, and integrates with UI form references.
Parameters
controller: AbortController
An AbortController instance used to cancel ongoing fetch requests or server-sent event streams.chatBoxIds: string[]
An array of chat box IDs to which the messages will be sent. The hook manages message states for each of these chat boxes.
Returns
An object exposing the following methods and data:
Name | Type | Description |
|---|---|---|
|
| The current input value of the message text field. |
|
| A record mapping each chat box ID to its array of chat messages. |
|
| Sends a message to a specific chat box. |
|
| Handler to update the message input field value. |
|
| Handler to trigger sending messages to all chat boxes when user presses Enter. |
|
| Aborts ongoing message streaming output for all chat boxes. |
|
| Indicates whether any message sending is currently ongoing (loading state). |
|
| Sets form references for UI components associated with each chat box. |
|
| Handles file uploads and associates file IDs with messages. |
Internal Functions and Methods
1. stopOutputMessage()
Aborts the current streaming message output by calling controller.abort(). This cancels any ongoing server-sent events or fetch requests.
Example Usage:
const { stopOutputMessage } = useSendMultipleChatMessage(controller, chatBoxIds);
stopOutputMessage();
2. addNewestQuestion(message: Message, answer?: string)
Adds a new user question message and optionally its assistant answer to the messageRecord state for the corresponding chat box.
message: Message— The user message object to add.answer?: string— The assistant's answer content (optional).
Generates unique IDs for messages using buildMessageUuid and appends both the question and answer messages in the chat box’s message array.
3. addNewestAnswer(answer: IAnswer)
Updates the last assistant answer message in the message list with incoming streaming content.
answer: IAnswer— Contains the answer text, references, prompt, audio binary data, and associated chat box ID.
Replaces the last assistant message in the chat box’s messages with the updated streaming answer.
4. removeLatestMessage(chatBoxId?: string)
Removes the most recent message in the specified chat box’s message list.
chatBoxId?: string— The chat box ID from which to remove the last message.
Useful when handling errors or canceling message sending.
5. adjustRecordByChatBoxIds()
Ensures the messageRecord state contains only keys corresponding to current chatBoxIds. Initializes empty arrays for new chat boxes and deletes records for removed ones.
Invoked on chatBoxIds changes to maintain consistency.
6. sendMessage({ message, currentConversationId, messages, chatBoxId })
Sends a single message to the server for a specified chat box.
message: Message— The message to send.currentConversationId?: string— Optional conversation ID override.messages?: Message[]— Optional array of previous messages to send as context.chatBoxId: string— Target chat box ID.
This function uses the send method from useSendMessageWithSse hook to stream the server completion response, passing chat box specific LLM (Large Language Model) configuration. Handles error responses by showing error messages, resetting input, and removing the last message.
7. handlePressEnter()
Triggered when the user presses Enter in the message input box.
Validates that input is not empty.
Generates a UUID for the new message.
For each chat box, if its LLM config is not empty:
Adds the new user question message.
Sends the message using
sendMessage.
Clears file IDs used as attachments.
Resets input value if all previous messages have finished loading.
Important Implementation Details
Message ID Generation: Uses
buildMessageUuidto create unique and consistent IDs for pairing user questions and assistant answers. This helps in managing deletion and updates.Streaming Responses: Integrates with
useSendMessageWithSseto handle server-sent events streaming assistant answers in real-time.File Uploads: Supports file attachment IDs through the
useUploadFilehook, which are included in messages.Multiple Chat Box Synchronization: Maintains separate message records per chat box to enable simultaneous multi-chat workflows.
AbortController Integration: Allows aborting message sending and streaming gracefully.
LLM Configuration: Retrieves chat box-specific LLM parameters via
useBuildFormRefsto tailor message sending requests.
Interactions with Other System Parts
UI Components:
Imports
showMessagefor user notifications.Uses form references and input handlers from
useBuildFormRefsanduseHandleMessageInputChange.Supports file upload handling with
useUploadFile.
Hooks:
useSendMessageWithSsefor sending messages with streaming server responses.useGetChatSearchParamsto extract conversation IDs from URL or context.
APIs:
Calls
api.completeConversationendpoint to send messages and receive assistant answers.
Data Structures:
Uses interfaces
IMessage,Message, andIAnswerfor typing chat messages and answers.
Utilities:
buildMessageUuidfor consistent message ID generation.lodash.trimto sanitize input.uuidto generate unique message IDs.
Usage Example
import { useSendMultipleChatMessage } from './use-send-multiple-message';
function MultiChatInput({ chatBoxIds }) {
const controller = new AbortController();
const {
value,
handleInputChange,
handlePressEnter,
messageRecord,
sendLoading,
stopOutputMessage,
handleUploadFile,
} = useSendMultipleChatMessage(controller, chatBoxIds);
return (
<div>
<textarea
value={value}
onChange={handleInputChange}
onKeyDown={(e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
handlePressEnter();
}
}}
/>
<button onClick={stopOutputMessage} disabled={!sendLoading}>
Stop
</button>
<input type="file" multiple onChange={handleUploadFile} />
{/* Render messages from messageRecord for each chatBoxId */}
</div>
);
}
Mermaid Diagram
classDiagram
class useSendMultipleChatMessage {
- controller: AbortController
- chatBoxIds: string[]
- messageRecord: Record<string, IMessage[]>
- value: string
+ stopOutputMessage()
+ addNewestQuestion(message: Message, answer?: string)
+ addNewestAnswer(answer: IAnswer)
+ removeLatestMessage(chatBoxId?: string)
+ adjustRecordByChatBoxIds()
+ sendMessage(params: {message: Message, currentConversationId?: string, messages?: Message[], chatBoxId: string})
+ handlePressEnter()
+ handleInputChange()
+ handleUploadFile()
+ setFormRef()
}
Summary
The use-send-multiple-message.ts file provides a robust custom React hook for managing multi-chat messaging flows. It handles input, streaming message sending, file uploads, and message state management across multiple chat boxes in parallel. Integration with streaming APIs and abort control makes it suitable for real-time chat applications with advanced LLM backends.