logic-hooks.ts
Overview
logic-hooks.ts is a utility and state management file primarily designed for a React-based frontend application. It provides a collection of custom React hooks that encapsulate common logic related to:
Pagination management
Language and UI settings
Chat messaging workflows, including sending and receiving messages with Server-Sent Events (SSE)
Scroll management for chat views
Message lifecycle management (adding, removing, regenerating)
Form handling utilities
Fetching configuration or tenant-specific data
This file serves as a centralized place to handle complex UI and interaction logic related to chat conversations and user settings, enhancing code reuse and maintainability.
Detailed Documentation
Custom Hooks
usePrevious<T>(value: T): T | undefined
Purpose: Tracks the previous value of a given state or prop.
Parameters:
value: T- The current value to track.
Returns: The value from the previous render or
undefinedon the first render.Usage Example:
const prevCount = usePrevious(count);Implementation Details: Uses a mutable
useRefto store the previous value and updates it in auseEffect.
useSetSelectedRecord<T = IKnowledgeFile>()
Purpose: State manager for currently selected record/item (e.g., knowledge file).
Returns:
currentRecord: T— The selected record.setRecord(record: T): void— Setter function to update the selected record.
Usage Example:
const { currentRecord, setRecord } = useSetSelectedRecord<IKnowledgeFile>(); setRecord(newRecord);Details: Simple wrapper over
useStatefor selected record management.
useChangeLanguage()
Purpose: Changes the application language locale and persists the selection.
Returns: A function
changeLanguage(lng: string): voidthat switches the language.Parameters:
lng- language code string (e.g.,"en","zh").Usage Example:
const changeLanguage = useChangeLanguage(); changeLanguage('en');Implementation: Uses
i18nfromreact-i18nextand persists language setting viasaveSetting.
useGetPaginationWithRouter()
Purpose: Provides pagination props integrated with routing (page & size state persisted in route or global state).
Returns:
pagination: PaginationProps— Ant Design pagination config.setPagination(pagination: { page: number; pageSize?: number }): void— Setter.
Implementation: Uses
useSetPaginationParamshook to sync pagination with router params.Usage: Suitable for paginated lists where URL must reflect pagination state.
useHandleSearchChange()
Purpose: Manages search input state and resets pagination on search term change.
Returns:
handleInputChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): voidsearchString: string
Details: Resets pagination to page 1 on input change.
useGetPagination()
Purpose: A simpler pagination state handler without routing integration.
Returns:
pagination: PaginationProps— Ant Design pagination config.
Usage: For components requiring local pagination state.
useFetchAppConf()
Purpose: Loads application configuration from
/conf.json.Returns:
appConf: AppConf—{ appName: string }
Implementation: Fetches configuration once on mount.
useSetDoneRecord()
Purpose: Tracks completion status of multiple asynchronous operations keyed by IDs.
Returns:
doneRecord: Record<string, boolean>— Map of task IDs to completion status.setDoneRecordById(id: string, val: boolean): voidclearDoneRecord(): voidallDone: boolean— True if all tracked tasks are done.
Usage: Useful for tracking multiple SSE or async completion states.
useSendMessageWithSse(url?: string)
Purpose: Sends chat messages to a backend API with streaming response handled via SSE.
Parameters:
url: string(default:api.completeConversation) — Endpoint for SSE.
Returns:
send(body: any, controller?: AbortController): Promise<{ response: Response; data: ResponseType } | undefined>answer: IAnswer— The streaming answer state.done: boolean— Indicates if streaming is complete.doneRecord: Record<string, boolean>allDone: booleansetDone(val: boolean): voidresetAnswer(): voidstopOutputMessage(): void— Aborts SSE stream.clearDoneRecord(): void
Usage Example:
const { send, answer, done } = useSendMessageWithSse(); send({ conversation_id: '...', message: 'Hello' });Implementation Details:
Uses native
fetchwithAbortControllerfor SSE.Parses streamed data using
eventsource-parser/stream.Updates answer state incrementally.
Manages multiple concurrent SSE calls with unique IDs using
doneRecord.
useSpeechWithSse(url?: string)
Purpose: Sends text-to-speech requests to backend; no streaming response handling.
Parameters:
url: string(default:api.tts)
Returns:
read(body: any): Promise<Response>— Sends TTS request.
Details: Shows error messages on non-zero response codes.
useScrollToBottom(messages?, containerRef?)
Purpose: Automatically scrolls a container to bottom when new messages arrive, unless user has scrolled up.
Parameters:
messages?: unknown— Dependency to trigger scroll.containerRef?: React.RefObject<HTMLDivElement>— Scroll container.
Returns:
scrollRef: React.RefObject<HTMLDivElement>isAtBottom: boolean— Whether user is scrolled to bottom.scrollToBottom(): void— Imperative scroll function.
Usage: Used in chat message windows.
useHandleMessageInputChange()
Purpose: Manages textarea input for messages, replacing escaped newlines and tabs with real characters.
Returns:
handleInputChange: ChangeEventHandler<HTMLTextAreaElement>value: stringsetValue: React.Dispatch<React.SetStateAction<string>>
useSelectDerivedMessages()
Purpose: Manages a derived list of chat messages with utility functions for adding/removing questions and answers.
Returns: Object containing:
derivedMessages: IMessage[]— Current message list.setDerivedMessages: Setter.addNewestQuestion(message: Message, answer?: string): Adds a question-answer pair.addNewestOneQuestion(message: Message): Adds a single question.addNewestAnswer(answer: IAnswer): Adds/updates last answer streaming message.addNewestOneAnswer(answer: IAnswer): Adds/updates answer by id.removeLatestMessage()removeMessageById(messageId: string)removeMessagesAfterCurrentMessage(messageId: string)removeAllMessages()removeAllMessagesExceptFirst()scrollRef, messageContainerRef, scrollToBottom
Implementation Details:
Uses
buildMessageUuidto generate stable IDs.Handles streaming updates by replacing last messages.
Supports message deletion and truncation workflows.
useRemoveMessagesAfterCurrentMessage(setCurrentConversation)
Purpose: Removes messages after a given message ID from the current conversation state.
Parameters:
setCurrentConversation: React.Dispatch— Setter for conversation state.
Returns:
removeMessagesAfterCurrentMessage(messageId: string): void
Usage: Used for message rollback or regeneration workflows.
useRegenerateMessage({ removeMessagesAfterCurrentMessage, sendMessage, messages })
Purpose: Regenerates a single message by removing subsequent messages and resending it.
Parameters:
removeMessagesAfterCurrentMessage(messageId: string): voidsendMessage({ message, messages }): void | Promise<any>— Function to send messages.messages: Message[]— Current message list.
Returns:
regenerateMessage(message: Message): Promise<void>
Usage: Used for "Regenerate response" feature in chat UIs.
useSelectItem(defaultId?: string)
Purpose: Manages selection state like a radio button group.
Parameters:
defaultId?: string— Optional default selected id.
Returns:
selectedId: stringhandleItemClick(id: string): () => void
Usage: General purpose selection hook.
useFetchModelId()
Purpose: Retrieves the tenant's model ID from tenant info.
Returns:
string— the model ID or empty string if unavailable.
useHandleChunkMethodSelectChange(form: FormInstance)
Purpose: Updates a form field for chunk token number based on chunk method selected.
Parameters:
form: FormInstance
Returns: A callback
(value: string) => voidto be used on chunk method select change.Details: Maps chunk methods like
"naive"or"knowledge_graph"to numeric token counts.
useResetFormOnCloseModal({ form, visible })
Purpose: Resets an Ant Design form when a modal closes.
Parameters:
form: FormInstancevisible?: boolean
Details: Tracks previous visibility and resets form fields when modal switches from open to closed.
Important Implementation Details
SSE Streaming:
useSendMessageWithSseuses thefetchAPI withAbortControllerto stream responses from the backend. It useseventsource-parser/streamto parse the event stream and updates the answer state incrementally. The hook also manages multiple concurrent message streams withdoneRecordkeyed by chat box IDs.Message ID Management:
Messages are assigned unique IDs usingbuildMessageUuidto correlate frontend and backend messages, enabling reliable message pairing, deletion, and updates.Pagination Integration:
Two pagination hooks exist: one integrates pagination state with routing (useGetPaginationWithRouter), and the other manages local pagination state (useGetPagination).Scroll Management:
useScrollToBottomdetects if the user scrolled up and only auto-scrolls when the user is at the bottom, preventing disruptive scrolling behavior.Form Reset on Modal Close:
useResetFormOnCloseModalensures that forms inside modals reset their fields whenever the modal closes, preventing stale data.
Interaction with Other System Parts
Imports constants such as authorization tokens, message types, and language maps from shared constants modules.
Interfaces imported from database and chat-related modules indicate this file is tightly coupled with chat-related data structures.
Calls backend APIs via
fetchoraxiosto endpoints such as/conf.json, chat completion API, and text-to-speech API.Utilizes utility functions like
getAuthorizationandbuildMessageUuidfrom utils for authentication and ID generation.Leverages Ant Design (
antd) for pagination and form handling.Supports localization through
react-i18next.The hooks are designed to be used within React components to manage chat and application state effectively.
Visual Diagram: Class/Hook Structure Flowchart
flowchart TD
A[usePrevious<T>] -->|Tracks| B[Previous value]
C[useSetSelectedRecord] -->|Manages| D[Selected record]
E[useChangeLanguage] -->|Changes & Saves| F[Language setting]
G[useGetPaginationWithRouter] -->|Syncs| H[Pagination with Router]
I[useGetPagination] -->|Local| J[Pagination state]
K[useHandleSearchChange] -->|Updates| L[Search input & resets pagination]
M[useFetchAppConf] -->|Fetches| N[App configuration]
O[useSetDoneRecord] -->|Tracks| P[Async completion flags]
Q[useSendMessageWithSse] -->|Handles| R[SSE streaming chat messages]
S[useSpeechWithSse] -->|Sends| T[TTS requests]
U[useScrollToBottom] -->|Manages| V[Scrolling behavior]
W[useHandleMessageInputChange] -->|Handles| X[Message input changes]
Y[useSelectDerivedMessages] -->|Manages| Z[Derived chat messages list]
AA[useRemoveMessagesAfterCurrentMessage] -->|Removes| AB[Messages after given ID]
AC[useRegenerateMessage] -->|Regenerates| AD[Message by resending]
AE[useSelectItem] -->|Manages| AF[Selected item state]
AG[useFetchModelId] -->|Fetches| AH[Tenant model ID]
AI[useHandleChunkMethodSelectChange] -->|Updates| AJ[Form chunk token count]
AK[useResetFormOnCloseModal] -->|Resets| AL[Form on modal close]
style Q fill:#f9f,stroke:#333,stroke-width:1px
style Y fill:#bbf,stroke:#333,stroke-width:1px
Summary
The logic-hooks.ts file is a comprehensive collection of React hooks that provide modular, reusable logic for managing chat conversations, pagination, language settings, SSE streaming, form handling, and UI behaviors. It integrates tightly with backend APIs and frontend state management, facilitating complex chat workflows with streaming responses, message regeneration, and user interaction management. This modular approach simplifies component code and enhances maintainability across the chat application.