index.tsx 8.1 KB

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