@botonic/react
Version:
Build Chatbots using React
87 lines • 4.7 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useContext, useEffect, useRef, useState } from 'react';
import { ROLES, WEBCHAT } from '../../constants';
import { WebchatContext } from '../../contexts';
import { StyledScrollbar } from '../components/styled-scrollbar';
import { TypingIndicator } from '../components/typing-indicator';
import { IntroMessage } from './intro-message';
import { ScrollButton } from './scroll-button';
import { ContainerMessage } from './styles';
import { UnreadMessagesBanner } from './unread-messages-banner';
import { useNotifications } from './use-notifications';
export const WebchatMessageList = () => {
const { webchatState, getThemeProperty, resetUnreadMessages, setLastMessageVisible, } = useContext(WebchatContext);
const scrollbarOptions = Object.assign({ enable: true, autoHide: true }, getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.scrollbar));
const [firstUnreadMessageId, setFirstUnreadMessageId] = useState();
const lastMessageBottomRef = useRef(null);
const scrollToBottom = () => {
setTimeout(() => {
var _a;
(_a = lastMessageBottomRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({
behavior: 'smooth',
block: 'end',
});
}, 100);
};
const handleScrollToBottom = () => {
resetUnreadMessages();
scrollToBottom();
};
const unreadMessagesBannerRef = useRef(null);
const scrollToBanner = () => {
setTimeout(() => {
var _a;
(_a = unreadMessagesBannerRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({
behavior: 'smooth',
block: 'center',
});
}, 100);
};
const showUnreadMessagesBanner = (messageComponentId) => 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 &&
lastMessageBottomRef.current) {
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
setLastMessageVisible(entry.isIntersecting);
});
});
observer.observe(lastMessageBottomRef.current);
}
}, [webchatState.messagesComponents]);
const { notificationsEnabled } = useNotifications();
useEffect(() => {
if (!notificationsEnabled) {
scrollToBottom();
return;
}
}, [webchatState.typing]);
useEffect(() => {
if (notificationsEnabled) {
if (webchatState.isWebchatOpen && unreadMessagesBannerRef.current) {
scrollToBanner();
return;
}
scrollToBottom();
return;
}
}, [firstUnreadMessageId, webchatState.isWebchatOpen, webchatState.typing]);
const showScrollButton = webchatState.numUnreadMessages > 0 && !webchatState.isLastMessageVisible;
return (_jsxs(_Fragment, { children: [_jsxs(StyledScrollbar, Object.assign({ role: ROLES.MESSAGE_LIST,
// TODO: Distinguis between multiple instances of webchat, e.g. `${uniqueId}-botonic-scrollable`
id: 'botonic-scrollable-content',
// @ts-ignore
scrollbar: scrollbarOptions, autoHide: scrollbarOptions.autoHide, ismessagescontainer: true.toString(), style: { flex: 1 } }, { children: [_jsx(IntroMessage, {}), webchatState.messagesComponents.map((messageComponent, index) => {
return (_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: lastMessageBottomRef, style: {
content: '',
} }))] }), index));
}), webchatState.typing && _jsx(TypingIndicator, {})] })), showScrollButton && _jsx(ScrollButton, { handleClick: handleScrollToBottom })] }));
};
//# sourceMappingURL=index.js.map