123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- import React from 'react';
- import { Typography, Button } from '@material-ui/core';
- import TextField from '@material-ui/core/TextField';
- import { makeStyles } from '@material-ui/core/styles';
- import './message.scss';
- import { useState, useEffect } from "react";
- import Avatar from '@material-ui/core/Avatar';
- import { useDispatch, useSelector, connect } from "react-redux";
- import Card from '@material-ui/core/Card';
- import CardActionArea from '@material-ui/core/CardActionArea';
- import { defaultAvatar, origUrl } from '../../App.js';
- import ImageList from '@material-ui/core/ImageList';
- import MenuOpenIcon from '@material-ui/icons/MenuOpen';
- import HighlightOffIcon from '@material-ui/icons/HighlightOff';
- import { actionMyUserMessage, actionForMeMessage, actionAdMessage } from '../../actions';
- const useStyles = makeStyles((theme) => ({
- messageList: {
- width: "50%",
- maxWidth: "70%",
- backgroundColor: '#ccd7e3',
- display: 'flex',
- flexDirection: 'column-reverse',
- },
- messageListClose: {
- width: "90%",
- backgroundColor: '#ccd7e3',
- display: 'flex',
- flexDirection: 'column-reverse',
- },
- userList: {
- width: "30%",
- marginRight: "5px",
- minWidth: "max-content",
- backgroundColor: '#ccd7e3'
- },
- userListButton: {
- minWidth: "max-content",
- backgroundColor: '#ccd7e3',
- height: '498px',
- cursor: 'pointer'
- },
- MessageInput: {
- margin: '10px'
- },
- user: {
- display: 'flex',
- height: '60px',
- backgroundColor: '#88a0b9',
- margin: '10px',
- alignItems: 'center',
- padding: '5px'
- },
- avatar: {
- marginRight: '5px'
- },
- messageCard: {
- maxWidth: '80%',
- margin: '10px 10px 0px 10px',
- width: 'max-content',
- padding: '4px',
- height: 'max-content'
- },
- myUserColor: {
- backgroundColor: "#848bd8",
- maxWidth: '80%',
- margin: '10px 10px 0px 10px',
- marginRight: '-6px',
- marginLeft: '-5px',
- width: 'max-content',
- padding: '4px',
- },
- imageList: {
- width: 'auto',
- height: '402px',
- display: 'block',
- overflowY: 'scroll'
- },
- imageListUsers: {
- width: 'auto',
- height: '502px',
- display: 'block',
- overflowY: 'scroll'
- },
- userColor: {
- backgroundColor: "#50905f",
- maxWidth: '80%',
- maxHeight: '21px',
- margin: '10px 10px 0px 10px',
- marginRight: '-6px',
- width: 'max-content',
- padding: '4px',
- },
- UserDiv: {
- display: 'flex',
- },
- myUserDiv: {
- display: 'flex',
- flexDirection: 'row-reverse',
- marginRight: '15px',
- },
- time: {
- float: "right",
- fontSize: "80%",
- marginLeft: "12px",
- }
- }));
- function timeConverter(UNIX_timestamp) {
- const time = new Date(UNIX_timestamp);
- const months = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"];
- const month = months[time.getMonth()];
- const date = time.getDate();
- const hour = time.getHours();
- const min = time.getMinutes();
- const newTime = date + '.' + month + ' ' + hour + ':' + min;
- return newTime;
- }
- function MyMessage({ user, message, time }) {
- const login = useSelector(state => state.auth?.payload?.sub?.login)
- const classes = useStyles();
- return (<>
- <div className={login === user ? classes.myUserDiv : classes.UserDiv}>
- <Card className={login === user ? classes.myUserColor : classes.userColor}>{user} </Card>
- <Card className={classes.messageCard}>{message} </Card>
- </div>
- <div className={login === user ? classes.myUserDiv : classes.UserDiv}>
- <Typography className={classes.time} gutterBottom >
- {timeConverter(+time)}
- </Typography></div></>
- )
- }
- const Users = ({ myOnclick, user }) => {
- const classes = useStyles();
- return (
- <CardActionArea onClick={() => myOnclick(user._id)}>
- <Card className={classes.user}>
- <Avatar className={classes.avatar} src={user.avatar ? origUrl + user.avatar.url : defaultAvatar} alt="Remy Sharp" />
- <p >{user.login} </p>
- </Card>
- </CardActionArea>
- )
- }
- const Spoiler = ({ open, children }) => {
- return <>
- <div>{open && children}</div>
- </>
- }
- const Message = ({ loadData, dataMyUser, myMessage = [], forMeMessage = [], forMeStatus, myMessageStatus }) => {
- const classes = useStyles();
- const dispatch = useDispatch();
- const id = useSelector(state => state.auth?.payload?.sub?.id)
- const [time, setTime] = useState(true);
- const [users, setUsers] = useState([]);
- const [send, setSend] = useState(false);
- const [message, setMessage] = useState('');
- const [iduser, setIduser] = useState("");
- const [messageArr, setMessageArr] = useState([]);
- const [allmessage, setAllMessage] = useState([]);
- useEffect(() => {
- if (forMeStatus === 'FULFILLED' && myMessageStatus === 'FULFILLED') {
- if (forMeMessage.length > 0 || myMessage.length > 0) {
- let allmessages = []
- if (forMeMessage.length > 0) {
- allmessages = [...forMeMessage]
- }
- if (myMessage.length > 0) {
- allmessages = [...myMessage]
- }
- if (forMeMessage.length > 0 && myMessage.length > 0) {
- allmessages = [...forMeMessage, ...myMessage]
- }
- if (allmessages.length > 0) {
- let usersList = allmessages.map((el) => {
- if (el.to) {
- return { login: el.to.login, _id: el.to._id, avatar: el.to.avatar }
- }
- return { login: el.owner.login, _id: el.owner._id, avatar: el.owner.avatar }
- })
- usersList = usersList.reduce((a, b) => {
- if (!a.find(v => v._id == b._id)) {
- a.push(b);
- }
- return a;
- }, []);
- setUsers(usersList)
- }
- }
- }
- }, [forMeMessage, myMessage])
- useEffect(() => {
- loadData(id)
- }, [send])
- useEffect(() => {
- const element = document.getElementById('list');
- element.scrollTop = element.scrollHeight;
- }, [messageArr])
- const onclickSend = () => {
- if (message) {
- dispatch(actionAdMessage({ text: message, to: { _id: iduser } }))
- setSend(!send)
- setMessage('')
- }
- }
- const enterHandler = (event) => {
- if (event.key === 'Enter') {
- if (message) {
- dispatch(actionAdMessage({ text: message, to: { _id: iduser } }))
- setSend(!send)
- setMessage('')
- }
- }
- }
- const upDate = () => {
- let usersMessage = []
- forMeMessage.map((el) => {
- if (el.owner._id === iduser) {
- usersMessage.push(el)
- }
- })
- myMessage.map((el) => {
- if (el.to._id === iduser) {
- usersMessage.push(el)
- }
- })
- const sort = usersMessage.sort((a, b) => a.createdAt - b.createdAt)
- setMessageArr(sort)
- setAllMessage([...forMeMessage, ...myMessage])
- }
- useEffect(() => {
- setTimeout(() => {
- dataMyUser(id)
- setTime(!time);
- }, 3000)
- }, [time])
- const onclickUser = (id) => {
- setIduser(id)
- let usersMessage = []
- forMeMessage.map((el) => {
- if (el.owner._id === id) {
- usersMessage.push(el)
- }
- })
- myMessage.map((el) => {
- if (el.to._id === id) {
- usersMessage.push(el)
- }
- })
- const sort = usersMessage.sort((a, b) => a.createdAt - b.createdAt)
- setMessageArr(sort)
- }
- if (allmessage.length < forMeMessage.length + myMessage.length) {
- upDate()
- }
- const [open, setOpen] = useState(true);
- const onclickOpen = () => {
- setOpen(!open)
- }
- return (
- <main className='mainMessage'>
- <Card onClick={onclickOpen} className={classes.userListButton} >{open ? <HighlightOffIcon /> : <MenuOpenIcon />}</Card>
- <Spoiler open={open}>
- <Card className={classes.userList}>
- <ImageList rowHeight={180} className={classes.imageListUsers}>
- {users.map((el) => <Users myOnclick={onclickUser} user={el} />)}
- </ImageList>
- </Card>
- </Spoiler>
- <Card className={open ? classes.messageList : classes.messageListClose}>
- <div className='divButtonText'>
- <Button onClick={onclickSend} size="small" color="primary">SEND</Button>
- <TextField
- onKeyPress={enterHandler}
- value={message}
- onChange={(e) => setMessage(e.target.value)}
- className={classes.MessageInput}
- id="standard-basic"
- label="Message" />
- <ImageList id='list' rowHeight={180} className={classes.imageList}>
- {messageArr.map((el) => <MyMessage user={el.owner.login} message={el.text} time={el.createdAt} />)}
- </ImageList>
- </div>
- </Card>
- </main>
- );
- }
- const Messages = connect(state => ({
- myMessage: state.promise?.allMeMessage?.payload,
- forMeMessage: state.promise?.allForMeMessage?.payload?.incomings || [],
- forMeStatus: state.promise?.allForMeMessage?.status || [],
- myMessageStatus: state.promise?.allMeMessage?.status || []
- }), {
- loadData: actionMyUserMessage,
- dataMyUser: actionForMeMessage
- })(Message)
- export default Messages
|