import React, { useEffect, useRef, useState, useMemo } from 'react'; import {useHMSTheme} from '../../hooks/HMSThemeProvider' import { CloseIcon, DownCaratIcon, PeopleIcon, SendIcon } from '../Icons'; import './index.css'; import { hmsUiClassParserGenerator } from '../../utils/classes'; import Autolinker from 'autolinker'; import ReactHtmlParser from 'react-html-parser'; import { Button } from '../TwButton'; import { useInView } from 'react-intersection-observer'; import { HMSMessage } from '../../store/schema'; import { isTotallyScrolled, scrollToBottom } from './chatBoxUtils'; import { useHMSActions, useHMSStore } from '../../hooks/HMSRoomProvider'; import { selectHMSMessages } from '../../store/selectors'; interface ChatBoxClasses { root?: string; header?: string; headerLine?: string; headerRoot?: string; headerText?: string; headerCloseButton?: string; messageBox?: string; messageRoot?: string; messageInfo?: string; messageSender?: string; messageTime?: string; messageText?: string; notificationRoot?: string; notificationInfo?: string; notificationText?: string; notificationTime?: string; time?: string; noMessageRoot?: string; footer?: string; chatInput?: string; unreadMessagesContainer?: string; unreadMessagesInner?: string; unreadIcon?: string; } const defaultClasses: ChatBoxClasses = { root: 'w-full h-full rounded-2xl flex flex-col shadow-2', header: `bg-white dark:bg-gray-200 rounded-t-2xl p-3 text-gray-300 dark:text-gray-500 flex flex-col justify-center items-center shadow border-b-1 border-gray-500`, headerLine: 'w-8 h-1 rounded bg-white dark:bg-gray-400 m-2', headerRoot: 'flex w-full justify-between', headerText: 'text-gray-300 dark:text-gray-500 flex items-center', headerCloseButton: 'focus:outline-none', messageBox: 'bg-white dark:bg-gray-100 w-full h-full p-3 text-gray-300 dark:text-gray-500 overflow-y-auto no-scrollbar flex-grow', messageRoot: 'py-3', messageInfo: 'flex justify-between', messageTime: 'text-xs', messageText: 'text-gray-100 dark:text-white leading-5 max-w-full break-words', noMessageRoot: 'flex justify-center items-center text-gray-300 dark:text-gray-400 h-full', footer: 'bg-white dark:bg-gray-200 min-h-11 rounded-b-2xl flex w-full justify-between p-3 border-t-1 border-gray-500 relative', chatInput: 'bg-white dark:bg-gray-200 placeholder-gray-500 text-gray-100 dark:text-white focus:outline-none leading-5 overflow-y-auto no-scrollbar resize-none w-5/6', notificationRoot: 'py-3', notificationInfo: 'flex justify-between text-gray-300 dark:text-gray-400', notificationTime: 'text-xs', unreadMessagesContainer: 'absolute left-0 p-1 w-full bottom-full flex justify-center', unreadMessagesInner: 'rounded-md px-2 py-1 bg-brand-main text-white flex cursor-pointer items-center ', unreadIcon: 'ml-2 w-3 h-3', }; const customClasses: ChatBoxClasses = { messageBox: 'hmsui-chatBox-no-scrollbar', chatInput: 'hmsui-chatBox-no-scrollbar', }; export interface Message extends HMSMessage { notification?: boolean; direction?: 'left' | 'right' | 'center'; } export interface ChatProps { messages?: Message[]; onSend?: (message: string) => void; onClose?: () => void; // when the chat box is closed autoScrollToBottom?: boolean; scrollAnimation?: ScrollBehavior; messageFormatter?: (message: string) => React.ReactNode; /** * extra classes added by user */ classes?: ChatBoxClasses; timeFormatter?: (date: Date) => string; } export const ChatBox = ({ messages, onSend, onClose, autoScrollToBottom = true, //TODO shouldn't be exposed as a prop scrollAnimation = 'auto', //TODO shouldn't be exposed as a prop messageFormatter = (message: string) => { let text = Autolinker.link(message, { sanitizeHtml: true, mention: 'twitter', className: 'text-brand-tint', }); return (