import { makeStyles } from "@material-ui/core/styles"; import { useState, useEffect, useCallback, useMemo } from "react"; import { useSelector,useDispatch } from "react-redux"; import ArrowBack from "./ArrowBack"; import SendMessage from "./SendMessage"; import UnpinBar from "./UnpinBar"; import MessageLeftText from './Messages/MessageLeftText' import MessageLeftReply from "./Messages/MessageLeftReply"; import MessageLeftForward from "./Messages/MessageLeftForward"; import MessageLeftImage from './Messages/MessageLeftImage' import MessageLeftAudio from './Messages/MessageLeftAudio' import MessageLeftVideo from './Messages/MessageLeftVideo' import MessageLeftFile from "./Messages/MessageLeftFile"; import MessageRightText from './Messages/MessageRightText' import MessageRightReply from "./Messages/MessageRightReply"; import MessageRightForward from "./Messages/MessageRightForward"; import MessageRightImage from './Messages/MessageRightImage' import MessageRightAudio from './Messages/MessageRightAudio' import MessageRightVideo from './Messages/MessageRightVideo' import MessageRightFile from "./Messages/MessageRightFile"; import MessageTime from "./Messages/MessageTime"; import AlertInfo from "../../../reusableComponents/AlertInfo"; import { getMessagesMemo } from '../../../../redux/messages/selector' import { getAuthorizationState } from '../../../../redux/authorization/selector' import { getChat } from '../../../../redux/chat/selector' import { getScrollChat } from '../../../../redux/control/selector' import { actionScrollChat,actionOpenPinned } from '../../../../redux/control/action' import { asyncGetMessagesById } from '../../../../redux/messages/operations' import { asyncGetChatById } from "../../../../redux/chat/operations"; import { seenChat } from "../../../../api-data"; import { TPinnedMessages } from "../../../../typescript/redux/pinnedMessages/types"; import { TMessage } from "../../../../typescript/redux/allMessages/types"; import { timeStampFilter,prodAwsS3,refreshAppTime } from "../../../../helpers"; const debounce = require('lodash.debounce'); const useStyles = makeStyles({ container: { height: '93vh', width: "100%", display: "flex", alignItems: "center", alignContent:"center", flexDirection: "column", position: "relative", }, messagesScroll: { paddingTop: 30, overflowY: "scroll", maxHeight: '83vh', width: "100%", display: "flex", justifyContent: 'center', '&::-webkit-scrollbar': { width: '0.4em' }, '&::-webkit-scrollbar-track': { boxShadow: 'inset 0 0 6px rgba(0,0,0,0.00)', webkitBoxShadow: 'inset 0 0 6px rgba(0,0,0,0.00)', backgroundColor: '#eceeec', }, '&::-webkit-scrollbar-thumb': { backgroundColor: '#ccc8c8', }, "&::-webkit-scrollbar-thumb:focus": { backgroundColor: "#959595", }, "&::-webkit-scrollbar-thumb:active": { backgroundColor: "#959595", }, }, messagesEmpty: { overflowY: "hidden", width: "100%", display: "flex", justifyContent: 'center', paddingTop: 30, }, messagesBody: { width: "60%", }, }); interface IChatBar { chatDivRef: any | null, selectedArr: string[] | [], setSelectedArr: React.Dispatch>, isSomeSelected: boolean, setIsSomeSelected: React.Dispatch>, openPinned: boolean, pinnedMessagesMemo: TPinnedMessages, handleUnpinAll: () => void, } const ChatBar = ({chatDivRef,selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected,openPinned,pinnedMessagesMemo,handleUnpinAll}:IChatBar) => { const classes = useStyles(); const dispatch = useDispatch() const messagesMemo = useSelector(getMessagesMemo) const { number:userNumber,nightMode,silentMode} = useSelector(getAuthorizationState) const { companionId,total,seen,mute } = useSelector(getChat) const scrollChat = useSelector(getScrollChat) const [isArrow, setIsArrow] = useState(false) const [isNew, setIsNew] = useState<{ new: number, mute: boolean }>({ new: 0, mute: false }) const [isReply, setIsReply] = useState(undefined) const [isForward, setIsForward] = useState(undefined) const [modalForward, setModalForward] = useState(false) let time: any let tongue: any const isSelected = (_id: string) => selectedArr.some((el: string) => el === _id) const handleSelected = (_id: string) => { !isSomeSelected&&setIsSomeSelected(true) if (selectedArr.some((el: string) => el === _id)) setSelectedArr(selectedArr.filter((el:string) => el !== _id)) else setSelectedArr([...selectedArr,_id]) } const handleReply = (_id: string) => { openPinned&& dispatch(actionOpenPinned(false)) setIsReply(renderArr.find((el) => el._id ===_id)) } const handleForward = (_id: string) => { openPinned && dispatch(actionOpenPinned(false)) isReply&&setIsReply(undefined) setIsForward(renderArr.find((el) => el._id === _id)) setModalForward(true) } const setTongueAndTime = (_id: string) => { openPinned && dispatch(actionOpenPinned(false)) isReply&&setIsReply(undefined) setIsForward(renderArr.find((el) => el._id === _id)) setModalForward(true) } const handleScrollTo = useCallback(() => { chatDivRef.current&&chatDivRef.current.scrollTo({ top: chatDivRef.current.scrollHeight, behavior: 'smooth' }) },[chatDivRef]) const handleScroll = useCallback(({ target:{scrollHeight,scrollTop,clientHeight}}: any) => { const different = scrollHeight - Math.floor(scrollTop) const reached = different - clientHeight if (total !== seen&&reached < 10 && !openPinned) seenChat(companionId) setIsArrow(different === clientHeight ? false : true) }, [total,seen, companionId,openPinned]) const debouncedHandleScroll = debounce(handleScroll, 300) const renderArr = useMemo(() => { return !openPinned ? messagesMemo : pinnedMessagesMemo }, [messagesMemo, pinnedMessagesMemo, openPinned]) const handleScrollToTheMessage = (_id:string) => { const childNodes = chatDivRef.current.childNodes[0].childNodes let toScrollNode = [...childNodes].find((el: any) => el.id === _id) if (toScrollNode) { toScrollNode = [...toScrollNode.childNodes].slice(-1)[0] toScrollNode.style.backgroundColor = 'rgba(70, 70, 70, 0.4)' toScrollNode.style.boxShadow = '0px 0px 6px 0px #ffffff' toScrollNode.scrollIntoView({ behavior: 'smooth' }) setTimeout(() => { toScrollNode.style.backgroundColor = 'unset' toScrollNode.style.boxShadow = 'unset' }, 2000) } } useEffect(() => { if (scrollChat) { dispatch(asyncGetMessagesById(companionId, handleScrollTo)) dispatch(actionScrollChat(false)) } }, [dispatch,handleScrollTo, scrollChat, companionId]) useEffect(() => { const handleReset = () => { dispatch(asyncGetChatById(companionId)) dispatch(asyncGetMessagesById(companionId, null)) } handleReset() const idInterval = setInterval(handleReset, refreshAppTime); return () => clearInterval(idInterval); }, [dispatch, companionId]); useEffect(() => { setIsNew({ new:total-seen,mute}) }, [total, seen, mute]); useEffect(() => { if (chatDivRef.current&&openPinned) { const { scrollHeight, clientHeight } = chatDivRef.current if (scrollHeight === clientHeight && isArrow) setIsArrow(false) } }, [chatDivRef,openPinned,pinnedMessagesMemo.length, isArrow]); useEffect(() => { const handleReset = () => { if (chatDivRef.current&&!openPinned) { const { scrollHeight, clientHeight } = chatDivRef.current if (total !== seen && scrollHeight === clientHeight) seenChat(companionId) } } const idInterval = setInterval(handleReset, refreshAppTime); return () => clearInterval(idInterval); }, [total, seen, chatDivRef, companionId, openPinned]); return (
0 ? classes.messagesScroll : classes.messagesEmpty}>
{messagesMemo.length > 0 ? renderArr.map(({ replyMessage,message, name, lastName,avatarUrl,color,pinned, createdAt, number, type, fullType, replyName, replyLastName, replyCaption, caption, emoji, emojiCompanion, _id, oldId, forwardName, forwardLastName, companionIdForwardToAndFrom},i) => { const watched = true let isTime let isTongue = false const nextTongue = renderArr[i + 1] if (!time) { isTime = true time = createdAt } else if (timeStampFilter(time) !== timeStampFilter(createdAt)) { time = createdAt isTime = true } if (!tongue&&nextTongue&&nextTongue.number === number) { isTongue = false tongue = number } else if (!tongue&&nextTongue&&nextTongue.number !== number) { isTongue = true tongue = null } else if (tongue&&nextTongue&&tongue === number&&nextTongue.number === number) { isTongue = false tongue = number } else if (tongue&&nextTongue&&tongue === number&&nextTongue.number !== number) { isTongue = true tongue = null } else if (tongue&&!nextTongue&&tongue === number) { isTongue = true tongue = null } else if (tongue&&!nextTongue&&tongue !== number) { isTongue = false tongue = number } if (nextTongue && timeStampFilter(nextTongue.createdAt) !== timeStampFilter(createdAt)) { isTongue = true } const url = `${prodAwsS3}/${message}` const urlReply = `${prodAwsS3}/${replyMessage}` if (number !== userNumber) { if (type === 'text' && !oldId && !companionIdForwardToAndFrom) return (
{isTime&&}
) if (type === 'text' && oldId) return (
{isTime&&}
) if (type === 'text' && companionIdForwardToAndFrom) return (
{isTime&&}
) if (type === 'image') return (
{isTime&&}
) if (type === 'audio') return (
{isTime&&}
) if (type === 'video') return (
{isTime&&}
) if (type) return (
{isTime&&}
) } else { if (type === 'text' && !oldId && !companionIdForwardToAndFrom) return (
{isTime&&}
) if (type === 'text' && oldId) return (
{isTime&&}
) if (type === 'text' && companionIdForwardToAndFrom) return (
{isTime&&}
) if (type === 'image') return (
{isTime&&}
) if (type === 'audio') return (
{isTime&&}
) if (type === 'video') return (
{isTime&&}
) if (type) return (
{isTime&&}
) } }) : }
{!openPinned && !isSomeSelected && } {openPinned&&!isSomeSelected&&}
); } export default ChatBar