UNPKG

@botonic/react

Version:

Build Chatbots using React

107 lines 5.12 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import React, { useContext, useEffect, useRef, useState } from 'react'; import { ROLES } from '../../constants'; import { WebchatContext } from '../../webchat/context'; import { BotonicContainerId } from '../constants'; import TypingIndicator from '../typing-indicator'; import { IntroMessage } from './intro-message'; import { ScrollButton } from './scroll-button'; import { ContainerMessage, ScrollableMessageList } from './styles'; import { UnreadMessagesBanner } from './unread-messages-banner'; import { useNotifications } from './use-notifications'; const SCROLL_TIMEOUT = 200; const scrollOptionsEnd = { block: 'end', }; const scrollOptionsCenter = { block: 'center', }; export const WebchatMessageList = () => { const { webchatState, resetUnreadMessages, setLastMessageVisible, scrollableMessagesListRef, } = useContext(WebchatContext); const { notificationsEnabled } = useNotifications(); const [firstUnreadMessageId, setFirstUnreadMessageId] = useState(); const lastMessageRef = useRef(null); const typingRef = useRef(null); const unreadMessagesBannerRef = useRef(null); const scrollToTyping = () => { setTimeout(() => { var _a; (_a = typingRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView(scrollOptionsEnd); }, SCROLL_TIMEOUT); }; const scrollToLastMessage = () => { setTimeout(() => { var _a; (_a = lastMessageRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView(scrollOptionsEnd); }, SCROLL_TIMEOUT); }; const scrollToBanner = () => { setTimeout(() => { var _a; (_a = unreadMessagesBannerRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView(scrollOptionsCenter); }, SCROLL_TIMEOUT); }; const handleScrollToBottom = () => { resetUnreadMessages(); if (webchatState.typing) { scrollToTyping(); return; } scrollToLastMessage(); }; const showUnreadMessagesBanner = (messageComponentId) => { return (!webchatState.isInputFocused && firstUnreadMessageId && messageComponentId === firstUnreadMessageId && webchatState.numUnreadMessages > 0); }; useEffect(() => { var _a; const firstUnreadMessage = webchatState.messagesComponents.find(message => message.props.isUnread); setFirstUnreadMessageId((_a = firstUnreadMessage === null || firstUnreadMessage === void 0 ? void 0 : firstUnreadMessage.props) === null || _a === void 0 ? void 0 : _a.id); }, [webchatState.messagesComponents]); useEffect(() => { if (webchatState.messagesComponents.length > 0 && lastMessageRef.current) { const observer = new IntersectionObserver(entries => { entries.forEach(entry => { setLastMessageVisible(entry.isIntersecting); }); }); observer.observe(lastMessageRef.current); } }, [webchatState.messagesComponents]); useEffect(() => { if (!notificationsEnabled) { if (webchatState.typing) { scrollToTyping(); return; } scrollToLastMessage(); } }, [webchatState.typing, webchatState.messagesComponents]); useEffect(() => { if (webchatState.isWebchatOpen && notificationsEnabled) { if (unreadMessagesBannerRef.current) { scrollToBanner(); return; } if (webchatState.typing) { scrollToTyping(); return; } scrollToLastMessage(); } }, [ firstUnreadMessageId, webchatState.isWebchatOpen, webchatState.typing, webchatState.messagesComponents, ]); const showScrollButton = webchatState.numUnreadMessages > 0 && !webchatState.isLastMessageVisible; return (_jsxs(_Fragment, { children: [_jsxs(ScrollableMessageList, Object.assign({ id: BotonicContainerId.ScrollableMessagesList, ref: scrollableMessagesListRef, role: ROLES.MESSAGE_LIST }, { children: [_jsx(IntroMessage, {}), webchatState.messagesComponents.map((messageComponent, index) => { return (_jsxs(React.Fragment, { children: [_jsxs(ContainerMessage, Object.assign({ role: ROLES.MESSAGE }, { children: [showUnreadMessagesBanner(messageComponent.props.id) && (_jsx(UnreadMessagesBanner, { unreadMessagesBannerRef: unreadMessagesBannerRef })), messageComponent] })), index === webchatState.messagesComponents.length - 1 && (_jsx("div", { ref: lastMessageRef, style: { content: '', } }))] }, messageComponent.props.id)); }), webchatState.typing && _jsx(TypingIndicator, { ref: typingRef })] })), showScrollButton && _jsx(ScrollButton, { handleClick: handleScrollToBottom })] })); }; //# sourceMappingURL=index.js.map