diff --git a/twistter-frontend/src/pages/directMessages.js b/twistter-frontend/src/pages/directMessages.js index b3c9ab2..ce05a43 100644 --- a/twistter-frontend/src/pages/directMessages.js +++ b/twistter-frontend/src/pages/directMessages.js @@ -1,254 +1,589 @@ -import React, { Component } from 'react' +import React, { Component } from 'react'; import PropTypes from 'prop-types'; +import dayjs from 'dayjs'; +import relativeTime from 'dayjs/plugin/relativeTime'; // Material UI -import Grid from '@material-ui/core/Grid' +import Box from '@material-ui/core/Box'; +import Button from '@material-ui/core/Button'; +import Card from '@material-ui/core/Card'; +import CircularProgress from '@material-ui/core/CircularProgress'; +import Fab from '@material-ui/core/Fab'; +import Grid from '@material-ui/core/Grid'; +import Popover from '@material-ui/core/Popover'; import TextField from '@material-ui/core/TextField'; import Typography from '@material-ui/core/Typography'; -import withStyles from "@material-ui/core/styles/withStyles"; -import GridList from "@material-ui/core/GridList"; -import GridListTile from '@material-ui/core/GridListTileBar'; -import Card from "@material-ui/core/Card"; +import withStyles from '@material-ui/core/styles/withStyles'; +// Material UI Icons +import AddCircleIcon from '@material-ui/icons/AddBox'; +import CheckMarkIcon from '@material-ui/icons/Check'; +import ErrorIcon from '@material-ui/icons/ErrorOutline'; +import SendIcon from '@material-ui/icons/Send'; + +// Redux import { connect } from 'react-redux'; -import { Box } from '@material-ui/core'; +import { getDirectMessages } from '../redux/actions/dataActions'; const styles = { - pageContainer: { - // height: "100%" - minHeight: "calc(100vh - 50px - 60px)" - }, - sidePadding: { - maxWidth: 350, - // margin: "auto" - }, - dmList: { - width: 300, - marginLeft: 15, - // borderRight: "solid" - }, - dmItem: { - marginBottom: 1 - // height: 100, - // border: "solid grey 1px", - // boxShadow: "2px 0px grey" - }, - dmItemUsernameSelected: { - // marginLeft: "auto" - // float: "left" - fontSize: 20, - color: "white" - }, - dmItemUsernameUnselected: { - fontSize: 20, - color: "#1da1f2" - }, - dmRecentMessageSelected: { - color: "#D6D6D6" - }, - dmRecentMessageUnselected: { - color: "black" - }, - dmListItemContainer: { - height: 100 - }, - dmCardUnselected: { - fontSize: 20, - backgroundColor: "#FFFFFF" - }, - dmCardSelected: { - fontSize: 20, - backgroundColor: "#1da1f2" - }, - messagesGrid: { - // // margin: "auto" - // height: "auto", - // width: "auto" - }, - messagesContainer: { - height: "100%", - // width: "calc(100% - 4)", - width: 450, - marginLeft: 2, - marginRight: 17 - }, - fromMessage: { - minWidth: 150, - maxWidth: 350, - minHeight: 40, - marginRight: 2, - marginTop: 2, - marginBottom: 10, - backgroundColor: "#008394", - color: "#FFFFFF", - float: "right" - }, - toMessage : { - minWidth: 150, - maxWidth: 350, - minHeight: 40, - marginLeft: 2, - marginTop: 2, - marginBottom: 10, - backgroundColor: "#008394", - color: "#FFFFFF", - float: "left" - }, - messageContent: { - textAlign: "left", - marginLeft: 5, - marginRight: 5 - }, - messageTime: { - color: "#D6D6D6", - textAlign: "left", - marginLeft: 5, - fontSize: 12 - } -} - + pageContainer: { + minHeight: 'calc(100vh - 50px - 60px)' + }, + sidePadding: { + maxWidth: 350 + }, + dmList: { + width: 300, + marginLeft: 15 + }, + dmItem: { + marginBottom: 1 + }, + dmItemUsernameSelected: { + fontSize: 20, + color: 'white' + }, + dmItemUsernameUnselected: { + fontSize: 20, + color: '#1da1f2' + }, + dmItemTimeSelected: { + color: '#D6D6D6', + fontSize: 12, + float: 'right', + marginRight: 5, + marginTop: 5 + }, + dmItemTimeUnselected: { + color: 'black', + fontSize: 12, + float: 'right', + marginRight: 5, + marginTop: 5 + }, + dmRecentMessageSelected: { + color: '#D6D6D6' + }, + dmRecentMessageUnselected: { + color: 'black' + }, + dmListItemContainer: { + height: 100 + }, + dmListTextLayout: { + height: '100%' + }, + dmCardUnselected: { + fontSize: 20, + backgroundColor: '#FFFFFF' + }, + dmCardSelected: { + fontSize: 20, + backgroundColor: '#1da1f2' + }, + messagesGrid: { + // // margin: "auto" + // height: "auto", + // width: "auto" + }, + messagesBox: { + width: 450 + }, + messagesContainer: { + height: 'calc(100vh - 50px - 110px)', + overflow: 'auto', + width: 450, + marginLeft: 2, + marginRight: 17 + }, + fromMessage: { + minWidth: 150, + maxWidth: 350, + minHeight: 40, + marginRight: 2, + marginTop: 2, + marginBottom: 10, + backgroundColor: '#008394', + color: '#FFFFFF', + float: 'right' + }, + toMessage: { + minWidth: 150, + maxWidth: 350, + minHeight: 40, + marginLeft: 2, + marginTop: 2, + marginBottom: 10, + backgroundColor: '#008394', + color: '#FFFFFF', + float: 'left' + }, + messageContent: { + textAlign: 'left', + marginLeft: 5, + marginRight: 5 + }, + messageTime: { + color: '#D6D6D6', + textAlign: 'left', + marginLeft: 5, + fontSize: 12 + }, + writeMessage: { + backgroundColor: '#FFFFFF', + boxShadow: '0px 0px 5px 0px grey', + width: 450 + }, + messageTextField: { + width: 388 + }, + messageButton: { + backgroundColor: '#1da1f2', + marginTop: 8, + marginLeft: 2 + }, + loadingUsernameCheck: { + height: 85, + width: 85, + marginLeft: 5 + }, + errorIcon: { + height: 55, + width: 55, + marginLeft: 5, + color: '#ff3d00' + }, + checkMarkIcon: { + height: 55, + width: 55, + marginLeft: 5, + color: '#1da1f2' + } +}; export class directMessages extends Component { - constructor() { - super(); - this.state = { - selectedMessage: "-1" - }; - } + constructor() { + super(); + this.state = { + hasChannelSelected: false, + selectedChannel: null, + dmData: null, + anchorEl: null, + createDMUsername: '', + checkingUsername: false, + usernameValid: false + }; + } + componentDidUpdate() { + if (this.state.hasChannelSelected) { + document.getElementById('messagesContainer').scrollTop = document.getElementById( + 'messagesContainer' + ).scrollHeight; + } + } + componentDidMount() { + // this.props.getDirectMessages(); + const resp = { + data: [ + { + recipient: 'batman', + messages: [], + recentMessage: null, + recentMessageTimestamp: null, + dmId: 'Lifb0XAONpNLJRhDnOHj' + }, + { + recipient: 'CrazyEddy', + messages: [ + { + messageId: 'yGqcBbDSM8TsoaQAfAVc', + author: 'CrazyEddy', + message: 'This is message 1', + createdAt: '2019-11-04T17:10:29.180Z' + }, + { + messageId: 'c1Bd1REkMBaMaraH10WP', + author: 'keanureeves', + message: 'This is message 2', + createdAt: '2019-11-04T17:33:35.169Z' + }, + { + messageId: 'CL5sThnuekks6579MKuF', + author: 'keanureeves', + message: 'Yo, this my first message', + createdAt: '2019-11-08T22:15:08.456Z' + }, + { + messageId: 'BgMSSlLLLdC1DMtJl5VJ', + author: 'CrazyEddy', + message: 'That is epic', + createdAt: '2019-11-08T22:20:16.768Z' + }, + { + message: 'test test test', + createdAt: '2019-11-08T22:20:58.961Z', + messageId: '9AeUuz0l4wWyQSG6RQ4A', + author: 'keanureeves' + }, + { + messageId: 'zhfEpirBK7jl9FnFMtsQ', + author: 'CrazyEddy', + message: 'noice', + createdAt: '2019-11-08T22:21:29.768Z' + }, + { + message: 'What time is it?', + createdAt: '2019-11-08T22:23:27.353Z', + messageId: 'XwyKwFU2L5wrTKedzlyF', + author: 'CrazyEddy' + }, + { + message: "it's 5:24 right now", + createdAt: '2019-11-08T22:24:21.807Z', + messageId: 'qeasHYkAtTGvjnc3VJAi', + author: 'keanureeves' + }, + { + messageId: 'I7kzyLUd9Pp5qzxTPzQv', + author: 'keanureeves', + message: 'a', + createdAt: '2019-11-08T22:31:42.852Z' + }, + { + messageId: 'iySWBDFFrbY8FT6E61NL', + author: 'keanureeves', + message: 'b', + createdAt: '2019-11-08T22:31:51.558Z' + }, + { + messageId: 'Yis0vXSEuMggj6z5Mq1a', + author: 'keanureeves', + message: 'c', + createdAt: '2019-11-08T22:32:01.293Z' + }, + { + messageId: 'DIgjDvFczqO0OWkOrL0t', + author: 'keanureeves', + message: 'd', + createdAt: '2019-11-08T22:32:16.095Z' + }, + { + message: 'e', + createdAt: '2019-11-08T22:32:22.134Z', + messageId: '6h1dnFE440MOrjySEQHU', + author: 'keanureeves' + }, + { + messageId: 'lmOGGYUWZyB3xG38T7lG', + author: 'keanureeves', + message: 'f', + createdAt: '2019-11-08T22:32:28.424Z' + }, + { + message: 'g', + createdAt: '2019-11-08T22:32:37.632Z', + messageId: '64swTj7yiFy7SF6BPbki', + author: 'keanureeves' + } + ], + recentMessage: 'g', + recentMessageTimestamp: '2019-11-08T22:32:37.632Z', + dmId: 'avGcIs4PFCJhc4EDqAfe' + } + ] + }; + // const resp = {"data": null} + this.setState({ dmData: resp.data }); + } - showAlert = (event) => { - // alert(event.target.dataset) - let paper; - if (event.target.parentNode.dataset.key === undefined) { - paper = event.target.parentNode.parentNode.dataset; - } else { - paper = event.target.parentNode.dataset; - } - this.setState({ - selectedMessage: paper.key - }) - } + // Handles selecting different DM channels + handleClickChannel = (event) => { + this.setState({ + hasChannelSelected: true + }); + let dmChannelKey; - render() { - const { classes } = this.props; + // Determine which DM channel was clicked by finding the key + // An if statement is needed because the user could click the card or the typography + if (event.target.parentNode.parentNode.parentNode.dataset.key === undefined) { + // They clicked text + dmChannelKey = event.target.parentNode.parentNode.parentNode.parentNode.dataset.key; + } else { + // They clicked the background/card + dmChannelKey = event.target.parentNode.parentNode.parentNode.dataset.key; + } - const selected = true; + // Save the entire DM channel in the state so that it is easier to load the messages + this.state.dmData.forEach((channel) => { + if (channel.dmId === dmChannelKey) { + this.setState({ + selectedChannel: channel + }); + } + }); + }; - let dmListMarkup = ( - - - {this.state.selectedMessage === "0" ? - - - keanureeves - This is the most recent message - - - : - - - keanureeves - This is the most recent message - - } - - - {this.state.selectedMessage === "1" ? - - - keanureeves - This is the most recent message - - - : - - - keanureeves - This is the most recent message - - } - - - {this.state.selectedMessage === "2" ? - - - keanureeves - This is the most recent message - - - : - - - keanureeves - This is the most recent message - - } - - - - ) + formatDateToString(dateString) { + let newDate = new Date(Date.parse(dateString)); + return newDate.toDateString(); + } - let messagesMarkup = ( - - - - hello - Tues 3:26pm - - - - - Hey, what's up? - Tues 3:26pm - - - - - not much. just chillin' - Tues 3:27pm - - - - - yayayay yay ayay ya ys ydyyasydasy yd yas dyas ydyasy dyasydy asyd yay ydysyd yaysdy yasy dyas ydysyd yasy dasy dyaysydya sydyasyd yasyd yasyd yasydyasdy yas ys ysdyydayaysyd ysdyasyd ysdyy yasyd asydyasy dyasydy - Tues 9:35pm - - - - ) + formatDateToTimeDiff(dateString) { + return dayjs(dateString).fromNow(); + } - return ( - - - - {dmListMarkup} - - - - {selected && - - {messagesMarkup} - } - {!selected && - Select a DM on the left} - - - - - - ) - } + handleOpenAddDMPopover = (event) => { + this.setState({ + anchorEl: event.currentTarget + }); + }; + + handleCloseAddDMPopover = () => { + this.setState({ + anchorEl: null, + createDMUsername: '', + checkingUsername: false, + usernameValid: false + }); + }; + + handleChangeAddDMUsername = (event) => { + this.setState({ + checkingUsername: true, + createDMUsername: event.target.value + }); + }; + + render() { + const { classes } = this.props; + dayjs.extend(relativeTime); + + // Used for the add button on the dmList + const open = Boolean(this.state.anchorEl); + const id = open ? 'simple-popover' : undefined; + + let dmListMarkup = this.state.dmData ? ( + this.state.dmData.map((channel) => ( + + + + + + + {channel.recipient} + + + {channel.recentMessage ? channel.recentMessage : 'No messages'} + + + + + {channel.recentMessageTimestamp ? ( + this.formatDateToTimeDiff(channel.recentMessageTimestamp) + ) : null} + + + + + + )) + ) : ( +

You don't have any DMs yet

+ ); + + let messagesMarkup = + this.state.selectedChannel !== null ? this.state.selectedChannel.messages.length > 0 ? ( + this.state.selectedChannel.messages.map((messageObj) => ( + + + {messageObj.message} + + {this.formatDateToString(messageObj.createdAt)} + + + + )) + ) : ( +

No DMs here

+ ) : ( +

Select a DM channel

+ ); + + let addDMMarkup = ( +
+ + + + + + + + + + Who would you like to start a DM with? + + + + + {this.state.checkingUsername && ( + + ) // Won't accept classes style for some reason + } + {!this.state.usernameValid && + !this.state.checkingUsername && } + {this.state.usernameValid && + !this.state.checkingUsername && ( + + )} + + + + + + + +
+ ); + + return ( + + + + + + {dmListMarkup} + + {addDMMarkup} + + + + + + + {this.state.hasChannelSelected && ( + + + + {messagesMarkup} + + + + + + + + + + )} + {!this.state.hasChannelSelected && + this.state.dmData && Select a DM on the left} + + + + + ); + } } directMessages.propTypes = { - classes: PropTypes.object.isRequired -} + classes: PropTypes.object.isRequired, + getDirectMessages: PropTypes.func.isRequired, + user: PropTypes.object.isRequired, + UI: PropTypes.object.isRequired +}; const mapStateToProps = (state) => ({ - user: state.user, + user: state.user, + UI: state.UI, + directMessages: state.directMessages }); -// export default directMessages -export default connect(mapStateToProps)(withStyles(styles)(directMessages)); +const mapActionsToProps = { + getDirectMessages +}; + +export default connect(mapStateToProps, mapActionsToProps)(withStyles(styles)(directMessages));