index.tsx 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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 [isNew, setIsNew] = useState<{new:number,mute:boolean}>({new:0,mute:false})
  54. const divRef = useRef<any | null>(null)
  55. let time:any
  56. const handleScrollTo = () => {
  57. divRef.current&&divRef.current.scrollTo({
  58. top: divRef.current.scrollHeight,
  59. behavior: 'smooth'
  60. })
  61. }
  62. const handleScroll = ({ target }: any) => {
  63. const different = target.scrollHeight - target.scrollTop
  64. if (different < 900) seenChat(companionId)
  65. setIsArrow(different < 1500 ? false : true)
  66. }
  67. const debouncedHandleScroll = useCallback(debounce(handleScroll, 300), []);
  68. useEffect(() => {
  69. if (scroll) {
  70. dispatch(asyncGetMessagesById(companionId, handleScrollTo))
  71. dispatch(actionScroll(false))
  72. }
  73. }, [dispatch,scroll, companionId])
  74. useEffect(() => {
  75. dispatch(asyncGetMessagesById(companionId, handleScrollTo))
  76. const handleReset = () => {
  77. dispatch(asyncGetMessagesById(companionId, null))
  78. const arr: any = localStorage.getItem('isNew')
  79. if(arr) setIsNew(JSON.parse(arr))
  80. }
  81. const idInterval = setInterval(handleReset, 3000);
  82. return () => clearInterval(idInterval);
  83. }, [dispatch, companionId]);
  84. return (
  85. <div ref={divRef} className={classes.container} onScroll={debouncedHandleScroll}>
  86. <div className={classes.messagesBody}>
  87. {messages.length > 0 ? messages.map(({ message, name, lastName, color,
  88. updatedAt, createdAt,number, type,fullType }) => {
  89. let isTime
  90. if (!time) {
  91. isTime = true
  92. time = updatedAt
  93. } else if (timeStampFilter(time) !== timeStampFilter(updatedAt)) {
  94. time = updatedAt
  95. isTime = true
  96. }
  97. const url = `http://localhost:3000/${message}`
  98. if (number !== userNumber) {
  99. if (type === 'text') return (<div key={createdAt}>
  100. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  101. <MessageLeftText
  102. message={message}
  103. updatedAt={updatedAt}
  104. name={name}
  105. lastName={lastName}
  106. /></div>)
  107. if (type === 'image') return (<div key={createdAt}>
  108. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  109. <MessageLeftImage
  110. url={url}
  111. updatedAt={updatedAt}
  112. color={color}
  113. message={message}
  114. messages={messages}
  115. fullType={fullType}
  116. /></div>)
  117. if (type === 'audio') return (<div key={createdAt}>
  118. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  119. <MessageLeftAudio
  120. url={url}
  121. updatedAt={updatedAt}
  122. fullType={fullType}
  123. /></div>)
  124. if (type === 'video') return (<div key={createdAt}>
  125. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  126. <MessageLeftVideo
  127. url={url}
  128. updatedAt={updatedAt}
  129. fullType={fullType}
  130. /></div>)
  131. if (type) return (<div key={createdAt}>
  132. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  133. <MessageLeftFile
  134. url={url}
  135. updatedAt={updatedAt}
  136. type={type}
  137. /></div>)
  138. } else {
  139. if (type === 'text') return (<div key={createdAt}>
  140. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  141. <MessageRightText
  142. message={message}
  143. updatedAt={updatedAt}
  144. name={name}
  145. lastName={lastName}
  146. /></div>)
  147. if (type === 'image') return (<div key={createdAt}>
  148. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  149. <MessageRightImage
  150. url={url}
  151. updatedAt={updatedAt}
  152. color={color}
  153. message={message}
  154. messages={messages}
  155. fullType={fullType}
  156. /></div>)
  157. if (type === 'audio') return (<div key={createdAt}>
  158. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  159. <MessageRightAudio
  160. url={url}
  161. updatedAt={updatedAt}
  162. fullType={fullType}
  163. /></div>)
  164. if (type === 'video') return (<div key={createdAt}>
  165. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  166. <MessageRightVideo
  167. url={url}
  168. updatedAt={updatedAt}
  169. fullType={fullType}
  170. /></div>)
  171. if (type) return (<div key={createdAt}>
  172. {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
  173. <MessageRightFile
  174. url={url}
  175. updatedAt={updatedAt}
  176. type={type}
  177. /></div>)
  178. }
  179. }) : <AlertInfo name='You do not have messages yet!' />}
  180. </div>
  181. <SendMessage isArrow={isArrow} isNew={isNew} handleScrollTo={handleScrollTo}/>
  182. </div>
  183. );
  184. }
  185. export default ChatBar