123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- 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 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 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 { getNumber } from '../../../../redux/authorization/selector'
- import { getChat } from '../../../../redux/chat/selector'
- import { getScrollChat } from '../../../../redux/control/selector'
- import { actionScrollChat } 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 { 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<React.SetStateAction<string[] | []>>,
- isSomeSelected: boolean,
- setIsSomeSelected: React.Dispatch<React.SetStateAction<boolean>>,
- 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 userNumber = useSelector(getNumber)
- const { companionId,total,seen,mute } = useSelector(getChat)
- const scrollChat = useSelector(getScrollChat)
- const [isArrow, setIsArrow] = useState<boolean>(false)
- const [isNew, setIsNew] = useState<{new:number,mute:boolean}>({new:0,mute:false})
- let time: 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 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)
-
- 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(() => {
- 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]);
-
- const renderArr = useMemo(() => {
- return !openPinned ? messagesMemo : pinnedMessagesMemo
- },[messagesMemo,pinnedMessagesMemo,openPinned])
- return (
- <div className={classes.container} >
- <ArrowBack isArrow={isArrow} isNew={isNew} handleScrollTo={handleScrollTo} openPinned={openPinned}/>
- <div id={companionId} ref={chatDivRef} onScroll={debouncedHandleScroll}
- className={messagesMemo.length > 0 ? classes.messagesScroll : classes.messagesEmpty}>
- <div className={classes.messagesBody}>
- {messagesMemo.length > 0 ? renderArr.map(({ message, name, lastName, color,pinned,
- createdAt,number, type,fullType,caption,emoji,emojiCompanion,_id }) => {
- let isTime
- if (!time) {
- isTime = true
- time = createdAt
- } else if (timeStampFilter(time) !== timeStampFilter(createdAt)) {
- time = createdAt
- isTime = true
- }
- const url = `${prodAwsS3}/${message}`
- if (number !== userNumber) {
- if (type === 'text') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
- {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
- <MessageLeftText
- message={message}
- createdAt={createdAt}
- name={name}
- lastName={lastName}
- caption={caption}
- emoji={emoji}
- emojiCompanion={emojiCompanion}
- pinned={pinned}
- isSomeSelected={isSomeSelected}
- isSelected={isSelected}
- handleSelected={handleSelected}
- _id={_id}
- /></div>)
- if (type === 'image') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
- {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
- <MessageLeftImage
- url={url}
- createdAt={createdAt}
- color={color}
- fullType={fullType}
- caption={caption}
- emoji={emoji}
- emojiCompanion={emojiCompanion}
- pinned={pinned}
- isSomeSelected={isSomeSelected}
- isSelected={isSelected}
- handleSelected={handleSelected}
- _id={_id}
- /></div>)
- if (type === 'audio') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
- {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
- <MessageLeftAudio
- url={url}
- createdAt={createdAt}
- fullType={fullType}
- caption={caption}
- emoji={emoji}
- emojiCompanion={emojiCompanion}
- pinned={pinned}
- isSomeSelected={isSomeSelected}
- isSelected={isSelected}
- handleSelected={handleSelected}
- _id={_id}
- /></div>)
- if (type === 'video') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
- {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
- <MessageLeftVideo
- url={url}
- createdAt={createdAt}
- fullType={fullType}
- caption={caption}
- emoji={emoji}
- emojiCompanion={emojiCompanion}
- pinned={pinned}
- isSomeSelected={isSomeSelected}
- isSelected={isSelected}
- handleSelected={handleSelected}
- _id={_id}
- /></div>)
- if (type) return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
- {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
- <MessageLeftFile
- url={url}
- createdAt={createdAt}
- type={type}
- caption={caption}
- emoji={emoji}
- emojiCompanion={emojiCompanion}
- pinned={pinned}
- isSomeSelected={isSomeSelected}
- isSelected={isSelected}
- handleSelected={handleSelected}
- _id={_id}
- /></div>)
- } else {
- if (type === 'text') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
- {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
- <MessageRightText
- message={message}
- createdAt={createdAt}
- name={name}
- lastName={lastName}
- caption={caption}
- emoji={emoji}
- emojiCompanion={emojiCompanion}
- pinned={pinned}
- isSomeSelected={isSomeSelected}
- isSelected={isSelected}
- handleSelected={handleSelected}
- _id={_id}
- /></div>)
- if (type === 'image') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
- {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
- <MessageRightImage
- url={url}
- createdAt={createdAt}
- color={color}
- fullType={fullType}
- caption={caption}
- emoji={emoji}
- emojiCompanion={emojiCompanion}
- pinned={pinned}
- isSomeSelected={isSomeSelected}
- isSelected={isSelected}
- handleSelected={handleSelected}
- _id={_id}
- /></div>)
- if (type === 'audio') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
- {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
- <MessageRightAudio
- url={url}
- createdAt={createdAt}
- fullType={fullType}
- caption={caption}
- emoji={emoji}
- emojiCompanion={emojiCompanion}
- pinned={pinned}
- isSomeSelected={isSomeSelected}
- isSelected={isSelected}
- handleSelected={handleSelected}
- _id={_id}
- /></div>)
- if (type === 'video') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
- {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
- <MessageRightVideo
- url={url}
- createdAt={createdAt}
- fullType={fullType}
- caption={caption}
- emoji={emoji}
- emojiCompanion={emojiCompanion}
- pinned={pinned}
- isSomeSelected={isSomeSelected}
- isSelected={isSelected}
- handleSelected={handleSelected}
- _id={_id}
- /></div>)
- if (type) return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
- {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
- <MessageRightFile
- url={url}
- createdAt={createdAt}
- type={type}
- caption={caption}
- emoji={emoji}
- emojiCompanion={emojiCompanion}
- pinned={pinned}
- isSomeSelected={isSomeSelected}
- isSelected={isSelected}
- handleSelected={handleSelected}
- _id={_id}
- /></div>)
- }
- }) : <AlertInfo name='You do not have messages yet!' />}
- </div>
- </div>
- {!openPinned ? <SendMessage isArrow={isArrow} /> :
- <UnpinBar pinnedMessagesMemo={pinnedMessagesMemo} handleUnpinAll={handleUnpinAll} />}
- </div>
- );
- }
- export default ChatBar
|