hooks.ts
Overview
The hooks.ts file provides a set of custom React hooks designed to manage user interactions related to chat messages within a web application. These hooks encapsulate logic for:
Sending user feedback on chat messages.
Removing chat messages.
Playing speech audio streams, including streamed text-to-speech playback.
By abstracting these functionalities into reusable hooks, the file promotes modularity and separation of concerns, simplifying UI components that consume these hooks.
Exports and Their Functionalities
1. useSendFeedback
Purpose
Handles the logic for sending feedback associated with a specific chat message. It manages modal visibility state and interacts with the feedback API.
Signature
useSendFeedback(messageId: string): {
loading: boolean;
onFeedbackOk: (params: IFeedbackRequestBody) => Promise<void>;
visible: boolean;
hideModal: () => void;
showModal: () => void;
}
Parameters
messageId(string): The unique identifier of the message for which feedback is being sent.
Returns
loading(boolean): Indicates if the feedback request is currently in progress.onFeedbackOk(async function): Called to submit feedback. Accepts an object conforming toIFeedbackRequestBody.visible(boolean): Flag indicating if the feedback modal is visible.hideModal(function): Function to hide the feedback modal.showModal(function): Function to show the feedback modal.
Usage Example
const { loading, onFeedbackOk, visible, hideModal, showModal } = useSendFeedback(messageId);
const handleSubmitFeedback = async (feedbackData) => {
await onFeedbackOk(feedbackData);
};
if (visible) {
return (
<FeedbackModal
onClose={hideModal}
onSubmit={handleSubmitFeedback}
loading={loading}
/>
);
}
Implementation Details
Uses
useSetModalStatehook to control modal visibility.Uses
useFeedbackhook to handle the feedback API call.The
onFeedbackOkcallback merges themessageIdwith the provided feedback parameters before sending.Closes the modal only if the feedback API returns success (code
0).
2. useRemoveMessage
Purpose
Provides functionality to delete a chat message by its ID and optionally remove it from the client-side state.
Signature
useRemoveMessage(
messageId: string,
removeMessageById?: (id: string) => void
): {
onRemoveMessage: () => Promise<void>;
loading: boolean;
}
Parameters
messageId(string): The ID of the message to be removed.removeMessageById(optional function): A callback function to remove the message from local state after successful deletion.
Returns
onRemoveMessage(async function): Triggers the delete operation.loading(boolean): Indicates if the deletion is in progress.
Usage Example
const { onRemoveMessage, loading } = useRemoveMessage(messageId, (id) => {
// Remove message from local state
setMessages((msgs) => msgs.filter((msg) => msg.id !== id));
});
<button onClick={onRemoveMessage} disabled={loading}>Delete</button>
Implementation Details
Uses
useDeleteMessagehook to perform the delete API call.On success (
code === 0), invokes the optionalremoveMessageByIdcallback to update client state.Uses
useCallbackto memoizeonRemoveMessagefunction.
3. useSpeech
Purpose
Manages playing text-to-speech audio streams for a given text content or an optional pre-existing audio binary. It supports streaming speech using Server-Sent Events (SSE) and handles audio playback control.
Signature
useSpeech(content: string, audioBinary?: string): {
ref: React.RefObject<HTMLAudioElement>;
handleRead: () => Promise<void>;
isPlaying: boolean;
}
Parameters
content(string): The text content to be converted to speech.audioBinary(optionalstring): Hex-encoded audio data to be played directly.
Returns
ref(React.RefObject<HTMLAudioElement>): Ref to be attached to an<audio>element to control playback.handleRead(async function): Toggles playback of the speech audio.isPlaying(boolean): Indicates whether the speech audio is currently playing.
Usage Example
const { ref, handleRead, isPlaying } = useSpeech("Hello, world!");
return (
<>
<audio ref={ref} />
<button onClick={handleRead}>
{isPlaying ? 'Pause' : 'Play'}
</button>
</>
);
Implementation Details
Uses
SpeechPlayerfromopenai-speech-stream-playerto handle audio streaming and playback.Initializes
SpeechPlayerwith appropriate MIME type based on browser support.If
audioBinaryis provided, decodes it from hex string to Uint8Array and feeds it directly into the player.Uses
useSpeechWithSsehook to stream speech data via SSE.Playback state (
isPlaying) is managed via React state.Methods:
initialize: Sets up the player instance and binds event callbacks for play/pause.pause: Pauses audio playback.speech: Initiates streaming of TTS audio from the supplied text.handleRead: Toggles between playing and pausing speech audio.
Handles exceptions gracefully when feeding audio data.
Interactions with Other Parts of the System
API and Business Logic Hooks:
useFeedbackanduseDeleteMessageprovide the API integration for feedback submission and message deletion.useSpeechWithSsemanages streaming TTS data using Server-Sent Events.
UI State Management:
useSetModalStatemanages modal visibility state, used in feedback flow.
Utilities:
hexStringToUint8Arrayconverts hex-encoded audio strings into a typed array for playback.
Third-Party Library:
SpeechPlayer(fromopenai-speech-stream-player) manages low-level audio playback and streaming.
This file acts as a bridge between UI components and backend logic/services related to chat messages, feedback, and speech synthesis.
Visual Diagram
flowchart TD
A[useSendFeedback] --> B[useSetModalState]
A --> C[useFeedback]
D[useRemoveMessage] --> E[useDeleteMessage]
D --> F[removeMessageById? callback]
G[useSpeech] --> H[useSpeechWithSse]
G --> I[SpeechPlayer]
G --> J[hexStringToUint8Array]
subgraph Feedback Flow
A
B
C
end
subgraph Message Removal Flow
D
E
F
end
subgraph Speech Playback Flow
G
H
I
J
end
Summary
The hooks.ts file provides three main hooks encapsulating feedback submission, message removal, and speech playback functionalities. It leverages modular hooks and utilities from across the codebase to provide clean APIs for UI components, improving maintainability and testability of chat-related features. The use of streaming audio and modal state management demonstrates an effective combination of asynchronous and UI state logic within React's functional programming paradigm.