123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- import { useEffect, useState} from 'react';
- import {Button, Box} from '@mui/material';
- import TextareaAutosize from '@mui/material/TextareaAutosize';
- import { MessageForm } from './messageForm/MessegaForm';
- import { UserInfo } from './userInfo/UserInfo';
- import { store } from '../../store';
- import { removeToken, isPrivatChat, privateMessage} from '../../reducers/userDataReducer'
- import { useDispatch, useSelector } from 'react-redux';
- import {getSocket} from'../../reducers/socketReducer';
- import { sendMessage, storeMessage, fileMessage } from '../../reducers/messageReducer';
- import { editMessage } from '../../reducers/messageReducer';
- import { SwitchButton } from './SwitchButton';
- import { MessageEditorMenu } from './MessageEditorMenu.jsx';
- import imgBtn from '../../assets/img/gg.png';
- import imgBtnPhoto from '../../assets/img/photo.png'
- import './chatPage.scss';
- import WebcamCapture from './service/webCam/WebcamCapture';
- import useSound from 'use-sound';
- import getNotif from '../../assets/sendSound.mp3'
- import { PrivateChat } from './privateChat/PrivateChat';
- import { PrivatChatHeader } from './privateChat/PrivatChatHeader';
- import { socketEvents } from '../../utils/socketsEvents';
- export const ChatPage = () => {
- console.log('render')
- const dispatch = useDispatch();
- const token = useSelector(state => localStorage.getItem('token') || state.userDataReducer.token);
- const user = useSelector(state => state.getUserSocketReducer.socketUserData)
- const socket = useSelector(state => state.getUserSocketReducer.socket)
- const editOldMessage = useSelector(state => state.messageReducer.editMessage)
- let showUserInfoBox = useSelector(state => state.messageReducer.showUserInfoBox)// || localStorage.getItem('showBox');
- const toUser = useSelector(state => state.userDataReducer.toUser)
- const chatId = useSelector(state => state.userDataReducer.toUser.socketId)
- const isPrivatChat = useSelector(state => state.userDataReducer.isPrivatChat)
- const newPrivateMessages = useSelector(state => state.getUserSocketReducer.newPrivateMessages)
- const [message, setMessage] = useState({message: ''});
- const [isUserTyping, setUserTyping] = useState([]);
- const [isCamActiv, setisCamActiv] = useState(false);
- const [showSpinner, setshowSpinner] = useState(false);
- const [loadingPercentage, setLoadPercentage] = useState(0)
-
- const isTabletorMobile = (window.screen.width < 730);
- const isNewMessage = newPrivateMessages.length > 0
- const [play] = useSound(getNotif, {volume: 0.005});
- const axiosConfig = {
- headers: {
- "Content-type": "multipart/form-data"
- },
- onUploadProgress: (progress) => {
- const {loaded, total} = progress;
- const loadStatus = Math.floor(loaded * 100 / total);
- setLoadPercentage(loadStatus)
- if(loadStatus == 100) {
- setshowSpinner(false)
- }
- }}
- const webcamEventHandler = async () => {
- let stream = null;
- try {
- stream = await navigator.mediaDevices.getUserMedia({ video: { width: 300 }});
- if (stream){
- setisCamActiv(!isCamActiv)
- }
- } catch(err) {
- console.log(err)
- }
- setisCamActiv(!isCamActiv) // test camera
- }
- const sendPrivateMessage = () => {
- console.log(toUser.socketId)
- socket.emit("private message", {
- fromUser: user,
- message: message.message,
- to: chatId,
- toUser
- })
- }
- useEffect(() => {
- if(socket) {
- socket.on('writing', (data) => {
- setUserTyping(data)
- setTimeout(() => setUserTyping([]), 500 )
- })
- }
- }, [socket, token])
-
- useEffect(() => {
- if(token && socket){
- socketEvents(socket)
- }
- }, [token, socket])
- return (
-
- <div className='rootContainer'>
- <Box className = {isTabletorMobile?'mobileRootBox':'rootBox'}>
-
- <Box className={isTabletorMobile?'usersBoxMobile':'usersBox'}
- sx = {showUserInfoBox ? {
- transform: "translateX(100%)",
- display: "block"
- }: { }}>
- <UserInfo/>
- { isTabletorMobile ? <SwitchButton/> : null}
- <Button
- style={isTabletorMobile ?
- {
- maxHeight:'20px',
- maxWidth: '15px',
- fontSize: '10px',
- marginLeft: '25px',
- marginRight: '10px'}
- :{margin:'10px 5px'}}
- variant="contained"
- onClick={()=> {
- localStorage.removeItem('token');
- dispatch(removeToken());
- socket.disconnect();
- }}>
- Logout
- </Button>
-
-
-
- </Box>
-
-
- <Box className ={isTabletorMobile ? 'rootMessageFormMobile':'rootMessageForm'} >
- {isCamActiv ?
- <div>
- <Button
- variant="contained"
- component="label"
- onClick = {() => webcamEventHandler()}
- >
- close camera
- </Button>
- <WebcamCapture />
- </div>
- :
- ""}
- {isPrivatChat? <PrivateChat/> : <MessageForm/>}
-
- {isUserTyping.isTyping && (isUserTyping.userName !== user.userName)? <span> User {isUserTyping.userName} typing..</span> : ""}
- <Box
- component="form"
- onSubmit = {e => {
- e.preventDefault()
- if (message.message.length){
- isPrivatChat? sendPrivateMessage() : dispatch(sendMessage({user, socket}));
- // isPrivatChat && dispatch(getSocket('allmessages'))
- isPrivatChat &&dispatch(editMessage({editMessage: ''}))
- setMessage({message: ''})
- play()
- }
-
- }}
- sx={(isTabletorMobile)?{
- display: 'flex',
- margin: '10px 2px'}
- :{
- display: 'flex',
- margin: '20px 5px'}
-
- }>
- <Button
- disabled={showSpinner}
- variant="contained"
- component="label"
- sx = {showSpinner?
- {
- minWidth: 'auto'}
- :
- {
- minWidth: 'auto',
- backgroundImage:'url(' + imgBtn + ')' ,
- backgroundPosition: 'center',
- backgroundRepeat: "no-repeat",
- backgroundSize: '20px 20px'
- }}
- style = {{color: 'green'}}
- >
- <input
- onChange={e =>{
- setshowSpinner(true)
- dispatch(fileMessage({files: e.target.files, axiosConfig}))
- }}
- type="file"
- multiple
- hidden
- />
- {showSpinner? loadingPercentage : ""}
- </Button>
- <Button
- variant="contained"
- component="label"
- sx = {{
- minWidth: 'auto',
- backgroundImage:'url(' + imgBtnPhoto + ')' ,
- backgroundPosition: 'center',
- backgroundRepeat: "no-repeat",
- backgroundSize: '20px 20px'
- }}
- onClick = {() => webcamEventHandler()}
- >
-
- </Button>
- <TextareaAutosize
- id="outlined-basic"
- label="Type a message..."
- variant="outlined"
- value={message.message}
- placeholder='type you message...'
- minRows={2}
- maxRows={4}
- className='textArea'
- onKeyPress={(e) => {
- if (e.key === "Enter") {
- e.preventDefault();
- isPrivatChat? sendPrivateMessage() : dispatch(sendMessage({user, socket}));
- //dispatch(getSocket('allmessages'))
- dispatch(editMessage({editMessage: ''}))
- setMessage({message: ''})
- }
- }}
- onChange={e => {
- dispatch(storeMessage({message: e.target.value}))
- !isPrivatChat &&socket.emit('userWriting');
- setMessage({message: e.target.value})}
- }
- // onFocus={ e => {
- // if (isTabletorMobile) {
- // e.target.className = 'focus'
-
- // }
- // }}
- // onBlur={e=> {
- // e.target.className = 'blur'
- // }}
-
- />
- <Button
- variant="contained"
- type='submit'
- disabled={user?.isMutted || !message.message.length}
- style={{width: '20%'}}
- >
- Send
- </Button>
- </Box>
- </Box>
-
- </Box>
- </div>
- )
- }
|