index.tsx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import { makeStyles } from "@material-ui/core/styles";
  2. import { useState, useEffect, useRef, useCallback } from "react";
  3. import { useSelector,useDispatch } from "react-redux";
  4. import SendMessage from "./SendMessage";
  5. import MessageLeftText from './Messages/MessageLeftText'
  6. import MessageLeftImage from './Messages/MessageLeftImage'
  7. import MessageLeftAudio from './Messages/MessageLeftAudio'
  8. import MessageLeftVideo from './Messages/MessageLeftVideo'
  9. import MessageLeftFile from "./Messages/MessageLeftFile";
  10. import MessageRightText from './Messages/MessageRightText'
  11. import MessageRightImage from './Messages/MessageRightImage'
  12. import MessageRightAudio from './Messages/MessageRightAudio'
  13. import MessageRightVideo from './Messages/MessageRightVideo'
  14. import MessageRightFile from "./Messages/MessageRightFile";
  15. import MessageTime from "./Messages/MessageTime";
  16. import AlertInfo from "../../../reusableComponents/AlertInfo";
  17. import { getMessagesMemo } from '../../../../redux/messages/selector'
  18. import { getNumber } from '../../../../redux/authorization/selector'
  19. import { getChat } from '../../../../redux/chat/selector'
  20. import { getScroll } from '../../../../redux/control/selector'
  21. import { actionScroll } from '../../../../redux/control/action'
  22. import { asyncGetMessagesById } from '../../../../redux/messages/operations'
  23. import { seenChat } from "../../../../api-data";
  24. import { timeStampFilter } from "../../../../helpers";
  25. const debounce = require('lodash.debounce');
  26. const useStyles = makeStyles({
  27. container: {
  28. width: "100%",
  29. height: "100%",
  30. maxWidth: "100%",
  31. maxHeight: "100%",
  32. display: "flex",
  33. alignItems: "center",
  34. alignContent:"center",
  35. flexDirection: "column",
  36. position: "relative",
  37. overflowY: "scroll",
  38. paddingTop: 60,
  39. },
  40. messagesBody: {
  41. width: "60%",
  42. height: "80%",
  43. },
  44. });
  45. const ChatBar = () => {
  46. const classes = useStyles();
  47. const dispatch = useDispatch()
  48. const messages = useSelector(getMessagesMemo)
  49. const userNumber = useSelector(getNumber)
  50. const { companionId } = useSelector(getChat)
  51. const scroll = useSelector(getScroll)
  52. const [isArrow, setIsArrow] = useState<boolean>(false)
  53. const divRef = useRef<any | null>(null)
  54. let time:any
  55. const handleScrollTo = () => {
  56. divRef.current&&divRef.current.scrollTo({
  57. top: divRef.current.scrollHeight,
  58. behavior: 'smooth'
  59. })
  60. }
  61. const handleScroll = ({ target }: any) => {
  62. const different = target.scrollHeight - target.scrollTop
  63. if (different < 900) seenChat(companionId)
  64. setIsArrow(different < 1500 ? false : true)
  65. }
  66. const debouncedHandleScroll = useCallback(debounce(handleScroll, 300), []);
  67. useEffect(() => {
  68. if (scroll) {
  69. dispatch(asyncGetMessagesById(companionId, handleScrollTo))
  70. dispatch(actionScroll(false))
  71. }
  72. }, [dispatch,scroll, companionId])
  73. useEffect(() => {
  74. dispatch(asyncGetMessagesById(companionId, handleScrollTo))
  75. const handleReset = () => dispatch(asyncGetMessagesById(companionId,null))
  76. const idInterval = setInterval(handleReset, 1500);
  77. return () => clearInterval(idInterval);
  78. }, [dispatch, companionId]);
  79. return (
  80. <div ref={divRef} className={classes.container} onScroll={debouncedHandleScroll}>
  81. <div className={classes.messagesBody}>
  82. {messages.length > 0 ? messages.map(({ message, name, lastName, color, updatedAt,createdAt, number, type }) => {
  83. let isTime
  84. if (!time) {
  85. isTime = true
  86. time = updatedAt
  87. } else if (timeStampFilter(time) !== timeStampFilter(updatedAt)) {
  88. time = updatedAt
  89. isTime = true
  90. }
  91. const url = `http://localhost:3000/${message}`
  92. if (number !== userNumber) {
  93. if (type === 'text') return (<div key={createdAt}>
  94. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  95. <MessageLeftText
  96. message={message}
  97. updatedAt={updatedAt}
  98. name={name}
  99. lastName={lastName}
  100. /></div>)
  101. if (type === 'image') return (<div key={createdAt}>
  102. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  103. <MessageLeftImage
  104. url={url}
  105. updatedAt={updatedAt}
  106. color={color}
  107. message={message}
  108. messages={messages}
  109. /></div>)
  110. if (type === 'audio') return (<div key={createdAt}>
  111. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  112. <MessageLeftAudio
  113. url={url}
  114. updatedAt={updatedAt}
  115. /></div>)
  116. if (type === 'video') return (<div key={createdAt}>
  117. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  118. <MessageLeftVideo
  119. url={url}
  120. updatedAt={updatedAt}
  121. /></div>)
  122. if (type) return (<div key={createdAt}>
  123. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  124. <MessageLeftFile
  125. url={url}
  126. updatedAt={updatedAt}
  127. type={type}
  128. /></div>)
  129. } else {
  130. if (type === 'text') return (<div key={createdAt}>
  131. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  132. <MessageRightText
  133. message={message}
  134. updatedAt={updatedAt}
  135. name={name}
  136. lastName={lastName}
  137. /></div>)
  138. if (type === 'image') return (<div key={createdAt}>
  139. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  140. <MessageRightImage
  141. url={url}
  142. updatedAt={updatedAt}
  143. color={color}
  144. message={message}
  145. messages={messages}
  146. /></div>)
  147. if (type === 'audio') return (<div key={createdAt}>
  148. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  149. <MessageRightAudio
  150. url={url}
  151. updatedAt={updatedAt}
  152. /></div>)
  153. if (type === 'video') return (<div key={createdAt}>
  154. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  155. <MessageRightVideo
  156. url={url}
  157. updatedAt={updatedAt}
  158. /></div>)
  159. if (type) return (<div key={createdAt}>
  160. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  161. <MessageRightFile
  162. url={url}
  163. updatedAt={updatedAt}
  164. type={type}
  165. /></div>)
  166. }
  167. }) : <AlertInfo name='You do not have messages yet!' />}
  168. </div>
  169. <SendMessage isArrow={isArrow} handleScrollTo={handleScrollTo}/>
  170. </div>
  171. );
  172. }
  173. export default ChatBar