| |
| |
| |
| |
| |
|
|
| import { useCallback, useEffect, useRef, useState } from 'react'; |
| import { ConsoleMessageItem } from '../types.js'; |
|
|
| export interface UseConsoleMessagesReturn { |
| consoleMessages: ConsoleMessageItem[]; |
| handleNewMessage: (message: ConsoleMessageItem) => void; |
| clearConsoleMessages: () => void; |
| } |
|
|
| export function useConsoleMessages(): UseConsoleMessagesReturn { |
| const [consoleMessages, setConsoleMessages] = useState<ConsoleMessageItem[]>( |
| [], |
| ); |
| const messageQueueRef = useRef<ConsoleMessageItem[]>([]); |
| const messageQueueTimeoutRef = useRef<number | null>(null); |
|
|
| const processMessageQueue = useCallback(() => { |
| if (messageQueueRef.current.length === 0) { |
| return; |
| } |
|
|
| setConsoleMessages((prevMessages) => { |
| const newMessages = [...prevMessages]; |
| messageQueueRef.current.forEach((queuedMessage) => { |
| if ( |
| newMessages.length > 0 && |
| newMessages[newMessages.length - 1].type === queuedMessage.type && |
| newMessages[newMessages.length - 1].content === queuedMessage.content |
| ) { |
| newMessages[newMessages.length - 1].count = |
| (newMessages[newMessages.length - 1].count || 1) + 1; |
| } else { |
| newMessages.push({ ...queuedMessage, count: 1 }); |
| } |
| }); |
| return newMessages; |
| }); |
|
|
| messageQueueRef.current = []; |
| messageQueueTimeoutRef.current = null; |
| }, []); |
|
|
| const scheduleQueueProcessing = useCallback(() => { |
| if (messageQueueTimeoutRef.current === null) { |
| messageQueueTimeoutRef.current = setTimeout( |
| processMessageQueue, |
| 0, |
| ) as unknown as number; |
| } |
| }, [processMessageQueue]); |
|
|
| const handleNewMessage = useCallback( |
| (message: ConsoleMessageItem) => { |
| messageQueueRef.current.push(message); |
| scheduleQueueProcessing(); |
| }, |
| [scheduleQueueProcessing], |
| ); |
|
|
| const clearConsoleMessages = useCallback(() => { |
| setConsoleMessages([]); |
| if (messageQueueTimeoutRef.current !== null) { |
| clearTimeout(messageQueueTimeoutRef.current); |
| messageQueueTimeoutRef.current = null; |
| } |
| messageQueueRef.current = []; |
| }, []); |
|
|
| useEffect( |
| () => |
| |
| () => { |
| if (messageQueueTimeoutRef.current !== null) { |
| clearTimeout(messageQueueTimeoutRef.current); |
| } |
| }, |
| [], |
| ); |
|
|
| return { consoleMessages, handleNewMessage, clearConsoleMessages }; |
| } |
|
|