ChatPage.jsx 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. import { useEffect, useState} from 'react';
  2. import {Button, Box} from '@mui/material';
  3. import TextareaAutosize from '@mui/material/TextareaAutosize';
  4. import { MessageForm } from './messageForm/MessegaForm';
  5. import { UserInfo } from './userInfo/UserInfo';
  6. import { store } from '../../store';
  7. import { removeToken} from '../../reducers/userDataReducer'
  8. import { useDispatch, useSelector } from 'react-redux';
  9. import {getSocket} from'../../reducers/socketReducer';
  10. import { sendMessage, storeMessage, fileMessage } from '../../reducers/messageReducer';
  11. import { editMessage } from '../../reducers/messageReducer';
  12. import { SwitchButton } from './SwitchButton';
  13. import { MessageEditorMenu } from './MessageEditorMenu.jsx';
  14. import imgBtn from '../../assets/img/gg.png';
  15. import imgBtnPhoto from '../../assets/img/photo.png'
  16. import './chatPage.scss';
  17. import WebcamCapture from './service/webCam/WebcamCapture';
  18. export const ChatPage = () => {
  19. const SOCKET_EVENTS = process.env.REACT_APP_SERVER_URL || ['allmessages', 'usersOnline', 'allDbUsers']
  20. const dispatch = useDispatch();
  21. const token = useSelector(state => localStorage.getItem('token') || state.userDataReducer.token);
  22. const user = useSelector(state => state.getUserSocketReducer.socketUserData)
  23. const socket = useSelector(state => state.getUserSocketReducer.socket)
  24. const editOldMessage = useSelector(state => state.messageReducer.editMessage)
  25. let showUserInfoBox = useSelector(state => state.messageReducer.showUserInfoBox)// || localStorage.getItem('showBox');
  26. const [message, setMessage] = useState({message: ''});
  27. const [isUserTyping, setUserTyping] = useState([]);
  28. const [isCamActiv, setisCamActiv] = useState(false);
  29. const isTabletorMobile = (window.screen.width < 730);
  30. const webcamEventHandler = () => {
  31. setisCamActiv(!isCamActiv)
  32. }
  33. useEffect(() => {
  34. if(socket) {
  35. socket.on('writing', (data) => {
  36. setUserTyping(data)
  37. setTimeout(() => setUserTyping([]), 500 )
  38. })
  39. }
  40. }, [socket])
  41. useEffect(() => {
  42. if(token){
  43. SOCKET_EVENTS.map(event => dispatch(getSocket(event)))
  44. }
  45. }, [token, editOldMessage, showUserInfoBox])
  46. return (
  47. <div className='rootContainer'>
  48. <Box className = 'rootBox'>
  49. { isTabletorMobile ? <SwitchButton/> : null}
  50. <Box className ={isTabletorMobile ? 'rootMessageFormMobile':'rootMessageForm'} >
  51. {isCamActiv ?
  52. <div>
  53. <Button
  54. variant="contained"
  55. component="label"
  56. onClick = {() => webcamEventHandler()}
  57. >
  58. close camera
  59. </Button>
  60. <WebcamCapture />
  61. </div>
  62. :
  63. ""}
  64. <MessageForm/>
  65. {isUserTyping.isTyping && (isUserTyping.userName !== user.userName)? <span> User {isUserTyping.userName} typing..</span> : ""}
  66. <Box
  67. component="form"
  68. onSubmit = {e => {
  69. e.preventDefault()
  70. dispatch(sendMessage({user, socket}))
  71. dispatch(getSocket('allmessages'))
  72. dispatch(editMessage({editMessage: ''}))
  73. setMessage({message: ''})
  74. }}
  75. sx={(isTabletorMobile)?{
  76. display: 'flex',
  77. margin: '10px 2px'}
  78. :{
  79. display: 'flex',
  80. margin: '20px 5px'}
  81. }>
  82. <Button
  83. variant="contained"
  84. component="label"
  85. sx = {{
  86. minWidth: 'auto',
  87. backgroundImage:'url(' + imgBtn + ')' ,
  88. backgroundPosition: 'center',
  89. backgroundRepeat: "no-repeat",
  90. backgroundSize: '20px 40px'
  91. }}
  92. >
  93. <input
  94. onChange={e =>{
  95. dispatch(fileMessage(e.target.files))
  96. }}
  97. type="file"
  98. multiple
  99. hidden
  100. />
  101. </Button>
  102. <Button
  103. variant="contained"
  104. component="label"
  105. sx = {{
  106. minWidth: 'auto',
  107. backgroundImage:'url(' + imgBtnPhoto + ')' ,
  108. backgroundPosition: 'center',
  109. backgroundRepeat: "no-repeat",
  110. backgroundSize: '20px 20px'
  111. }}
  112. onClick = {() => webcamEventHandler()}
  113. >
  114. </Button>
  115. <TextareaAutosize
  116. id="outlined-basic"
  117. label="Type a message..."
  118. variant="outlined"
  119. value={message.message || editOldMessage}
  120. placeholder='type you message...'
  121. minRows={3}
  122. maxRows={4}
  123. className='textArea'
  124. onKeyPress={(e) => {
  125. if (e.key === "Enter") {
  126. e.preventDefault();
  127. dispatch(sendMessage({user, socket}))
  128. dispatch(getSocket('allmessages'))
  129. dispatch(editMessage({editMessage: ''}))
  130. setMessage({message: ''})
  131. }
  132. }}
  133. onChange={e => {
  134. dispatch(storeMessage({message: e.target.value}))
  135. socket.emit('userWriting');
  136. setMessage({message: e.target.value})}
  137. }
  138. />
  139. <Button
  140. variant="contained"
  141. type='submit'
  142. disabled={user?.isMutted}
  143. style={{width: '20%'}}
  144. >
  145. Send
  146. </Button>
  147. </Box>
  148. </Box>
  149. <Box className={isTabletorMobile?'usersBoxMobile':'usersBox'}
  150. sx = {showUserInfoBox ? {
  151. transform: "translateX(100%)",
  152. display: "none"
  153. }: {}}>
  154. <Button
  155. sx={isTabletorMobile ?
  156. {
  157. maxHeight:'25px',
  158. maxWidth: '20px'}
  159. :{margin:'10px 5px'}}
  160. variant="outlined"
  161. onClick={()=> {
  162. localStorage.removeItem('token');
  163. dispatch(removeToken());
  164. socket.disconnect();
  165. }}>
  166. Logout
  167. </Button>
  168. <UserInfo/>
  169. </Box>
  170. </Box>
  171. </div>
  172. )
  173. }