import { useCallback } from 'react'; import { useChatContext } from 'tuikit-atomicx-react/chat'; import { useChatUIState } from '../context/useChatUIState'; import { scrollToMessage } from './useScroll'; import type { MessageInfo } from 'tuikit-atomicx-react/chat'; const MESSAGE_LIST_CONTAINER_SELECTOR = '#message-list-container'; export interface NavigateToMessageOptions { messageID: string; /** Cursor for loadMessages when the target is not in the current list */ cursor?: MessageInfo; highlightDuration?: number; } function waitForDomPaint(): Promise { return new Promise((resolve) => { requestAnimationFrame(() => { requestAnimationFrame(() => resolve()); }); }); } /** * Navigate to a message in the current conversation: scroll + highlight if already * loaded, otherwise load a history fragment around the cursor then scroll. */ function useMessageNavigation() { const { messageList, loadMessages } = useChatContext(); const { highlightMessage, setPendingLocateMessage } = useChatUIState(); const navigateToMessage = useCallback(async (options: NavigateToMessageOptions) => { const { messageID, cursor, highlightDuration = 3000 } = options; const container = document.querySelector(MESSAGE_LIST_CONTAINER_SELECTOR) as HTMLElement | null; const isInList = messageList?.some(msg => msg.msgID === messageID) ?? false; if (isInList) { await waitForDomPaint(); await scrollToMessage(container, messageID, { block: 'center', skipIfVisible: false, behavior: 'smooth', }).catch(() => {}); highlightMessage({ messageID, duration: highlightDuration }); return; } if (!cursor) { return; } setPendingLocateMessage(cursor); // setListMode('fragment'); // await loadMessages({ // messageListType: 'history', // cursor, // direction: 'both', // }); // await waitForDomPaint(); // await scrollToMessage(container, messageID, { // block: 'center', // skipIfVisible: false, // behavior: 'instant', // }).catch(() => {}); // highlightMessage({ messageID, duration: highlightDuration }); }, [messageList, loadMessages, highlightMessage]); return { navigateToMessage }; } export { useMessageNavigation };