diff --git a/client/modules/User/UserActions.js b/client/modules/User/UserActions.js index 135d7ad..2b0a876 100644 --- a/client/modules/User/UserActions.js +++ b/client/modules/User/UserActions.js @@ -9,6 +9,8 @@ export const AUTHENTICATE_SESSION = 'AUTHENTICATE_SESSION'; export const FAILED_AUTHENTICATION = 'FAILED_AUTHENTICATION'; export const CREATE_GROUP = 'CREATE_GROUP'; export const SET_CURRENT_STUDY_GROUP = 'SET_CURRENT_STUDY_GROUP'; +export const PREPARE_CHAT_MESSAGES = 'PREPARE_CHAT_MESSAGES'; +export const PREPARE_CHAT_MESSAGE = 'PREPARE_CHAT_MESSAGE'; // Auth Pages export const DASHBOARD_PAGE = 'DASHBOARD_PAGE'; @@ -154,9 +156,29 @@ export function createStudyGroupRequest(user,studyGroup) { }; } -export function setCurrentStudyGroup(studyGroup) { +export function setCurrentStudyGroup(studyGroupIndex) { return { type: SET_CURRENT_STUDY_GROUP, - studyGroup, + studyGroupIndex, + }; +} + +export function prepareChatMessages(messages) { + return { + type: PREPARE_CHAT_MESSAGES, + messages, + }; +} + +export function prepareChatMessage(message) { + return { + type: PREPARE_CHAT_MESSAGE, + message, + }; +} + +export function switchChat(studyGroupIndex, studyGroup) { + return (dispatch) => { + return callApi(`message/${studyGroup.guid}`).then(res => dispatch(prepareChatMessages(res.messages))); }; } diff --git a/client/modules/User/UserReducer.js b/client/modules/User/UserReducer.js index 7d8aea9..e79995c 100644 --- a/client/modules/User/UserReducer.js +++ b/client/modules/User/UserReducer.js @@ -1,7 +1,10 @@ -import { ADD_USER, UPDATE_USER, LOGIN_USER, AUTHENTICATE_SESSION, FAILED_AUTHENTICATION, LOGOUT_USER, SET_CURRENT_STUDY_GROUP } from './UserActions'; +import { ADD_USER, UPDATE_USER, LOGIN_USER, AUTHENTICATE_SESSION, FAILED_AUTHENTICATION, LOGOUT_USER, SET_CURRENT_STUDY_GROUP, PREPARE_CHAT_MESSAGES, PREPARE_CHAT_MESSAGE } from './UserActions'; + +import { getColorFromUserIndex } from './components/ChatComponent/ChatComponent'; +import React from 'react'; // Initial State -const initialState = { data: [], user: null, currentStudyGroup: null }; +const initialState = { data: [], user: null, currentStudyGroup: -1, chat: { messages: [] } }; const UserReducer = (state = initialState, action) => { switch (action.type) { @@ -12,12 +15,16 @@ const UserReducer = (state = initialState, action) => { case UPDATE_USER : return { user: action.user, + currentStudyGroup: state.currentStudyGroup, + chat: state.chat, }; case LOGIN_USER: { const user = (action.response.statusCode === 200) ? action.response.user : null; return { user, + currentStudyGroup: state.currentStudyGroup, + chat: state.chat, }; } case AUTHENTICATE_SESSION: { @@ -25,22 +32,50 @@ const UserReducer = (state = initialState, action) => { return { user, + currentStudyGroup: state.currentStudyGroup, + chat: state.chat, }; } case FAILED_AUTHENTICATION: { return { user: null, + currentStudyGroup: -1, + chat: initialState.chat, }; } case LOGOUT_USER: { return { user: null, + currentStudyGroup: -1, + chat: initialState.chat, }; } case SET_CURRENT_STUDY_GROUP: { return { user: state.user, // Not sure if this is necessary - currentStudyGroup: action.studyGroup, + currentStudyGroup: action.studyGroupIndex, + chat: state.chat, + }; + } + case PREPARE_CHAT_MESSAGES: { + const messages = []; + + for (let i = 0; i < action.messages.length; i++) { + messages.push(
{`${action.messages[i].author}: ${action.messages[i].messageContent}`}
); + } + + return { + user: state.user, + currentStudyGroup: state.currentStudyGroup, + chat: { messages }, + }; + } + case PREPARE_CHAT_MESSAGE: { + state.chat.messages.push(
{`${action.message.user}: ${action.message.message}`}
); + return { + user: state.user, + currentStudyGroup: state.currentStudyGroup, + chat: state.chat, }; } default: diff --git a/client/modules/User/components/ChatComponent/ChatComponent.js b/client/modules/User/components/ChatComponent/ChatComponent.js index 2e70b6a..b9daf51 100644 --- a/client/modules/User/components/ChatComponent/ChatComponent.js +++ b/client/modules/User/components/ChatComponent/ChatComponent.js @@ -21,39 +21,61 @@ const COLORS = [ ]; // Ensure we have a color for every user, if we are out of colors just wrap back around. -function getColorFromUserIndex(index) { +export function getColorFromUserIndex(index) { return COLORS[index % COLORS.length]; } export class ChatComponent extends Component { constructor(props) { super(props); - this.state = { messages: [] }; - this.populateMessages = this.populateMessages.bind(this); + this.state = { value: '' }; this.socket = null; + this.sendMessage = this.sendMessage.bind(this); + this.handleChange = this.handleChange.bind(this); + this.handleKeyDown = this.handleKeyDown.bind(this); + this.onMessageReceive = this.onMessageReceive.bind(this); } componentWillMount() { console.log('Will Mount'); - console.log(this.props.users); this.socket = io.connect(); - this.populateMessages(); + this.socket.emit('UserSignedIn', `${this.props.users.user.firstName} ${this.props.users.user.lastName}`); + this.socket.on('UpdateMessages', this.onMessageReceive); + + this.props.setChat(0); } componentWillUpdate(nextProps, nextState) { - console.log('Will Update'); - this.populateMessages(); + } componentWillUnmount() { console.log('Will Unmount'); + this.socket.disconnect(); + } + + onMessageReceive(data) { + this.props.prepareChatMessage(data); + } + + handleChange(event) { + this.setState({ value: event.target.value }); + } + + handleKeyDown(event) { + if (event.keyCode === 13 && !event.shiftKey) { + this.sendMessage(); + event.preventDefault(); + } } - populateMessages() { - this.state.messages = []; - // Test messages for now - for (let i = 0; i < 100; i++) { - this.state.messages.push(
Hello
); + sendMessage() { + if (this.state.value !== '') { + this.socket.emit('SaveMessage', { + message: this.state.value, + studyGroup: this.props.users.user.studyGroups[this.props.users.currentStudyGroup].guid, + }); + this.state.value = ''; } } @@ -63,11 +85,11 @@ export class ChatComponent extends Component { return (
- {this.state.messages} + {this.props.users.chat.messages}
- - + +
); diff --git a/client/modules/User/components/UserInfoComponent/UserInfoComponent.js b/client/modules/User/components/UserInfoComponent/UserInfoComponent.js index 601c8f9..04488f7 100644 --- a/client/modules/User/components/UserInfoComponent/UserInfoComponent.js +++ b/client/modules/User/components/UserInfoComponent/UserInfoComponent.js @@ -7,7 +7,7 @@ import UserStudyGroupComponent from '../UserStudyGroupComponent/UserStudyGroupCo import styles from './UserInfoComponent.css'; function UserInfoComponent(props) { - if (Object.keys(props.users).length === 1) { // wait props.users not to be null + if (props.users.user !== null) { // wait props.users not to be null return (
diff --git a/client/modules/User/components/UserStudyGroupComponent/UserStudyGroupComponent.js b/client/modules/User/components/UserStudyGroupComponent/UserStudyGroupComponent.js index 7bf0e44..64e9330 100644 --- a/client/modules/User/components/UserStudyGroupComponent/UserStudyGroupComponent.js +++ b/client/modules/User/components/UserStudyGroupComponent/UserStudyGroupComponent.js @@ -7,18 +7,19 @@ import styles from './UserStudyGroupComponent.css'; function UserStudyGroupComponent(props){ const arr = [ - {'name': "Dream Team Study"}, // Mock data (study groups) - {'name': "SOEN 341 Study Group"}, - {'name': "COMP 346 Exam Study"}, - {'name': "Team \"Mandy's Salad\" Discussion"} + { name: 'Dream Team Study' }, // Mock data (study groups) + { name: 'SOEN 341 Study Group' }, + { name: 'COMP 346 Exam Study' }, + { name: 'Team "Mandy\'s Salad" Discussion' }, ]; - if((props.users.user.studyGroups).length !== 0){ + + if (props.users.user !== null) { return (

Study Groups

diff --git a/client/modules/User/pages/UserDashboardPage/UserDashboardPage.js b/client/modules/User/pages/UserDashboardPage/UserDashboardPage.js index 9b55ba5..fa42db6 100644 --- a/client/modules/User/pages/UserDashboardPage/UserDashboardPage.js +++ b/client/modules/User/pages/UserDashboardPage/UserDashboardPage.js @@ -6,11 +6,15 @@ import { bindActionCreators } from 'redux'; import UserInfoComponent from '../../components/UserInfoComponent/UserInfoComponent'; import ChatComponent from '../../components/ChatComponent/ChatComponent'; -import { authenticateSessionRequest } from '../../UserActions'; +import { authenticateSessionRequest, switchChat, setCurrentStudyGroup, prepareChatMessage } from '../../UserActions'; import styles from './UserDashboardPage.css'; class UserDashboardPage extends Component { + constructor(props) { + super(props); + this.setChat = this.setChat.bind(this); + } componentWillMount() { // If I do not have any user data attempt to authenticate using cookie if (this.props.users.user == null) { @@ -18,12 +22,17 @@ class UserDashboardPage extends Component { } } + setChat(studyGroupIndex) { + this.props.setCurrentStudyGroup(studyGroupIndex); + this.props.switchChat(studyGroupIndex, this.props.users.user.studyGroups[studyGroupIndex]); + } + render() { if (this.props.users.user != null) { return (
- - + +
); } @@ -34,7 +43,7 @@ class UserDashboardPage extends Component { // Bind actions to props function mapDispatchToProps(dispatch) { - return bindActionCreators({ authenticateSessionRequest }, dispatch); + return bindActionCreators({ authenticateSessionRequest, switchChat, setCurrentStudyGroup, prepareChatMessage }, dispatch); } // map Users from store to Props @@ -45,6 +54,9 @@ function mapStateToProps({ users }) { // Warning issued if prop not provided UserDashboardPage.propTypes = { authenticateSessionRequest: PropTypes.func.isRequired, + setCurrentStudyGroup: PropTypes.func.isRequired, + switchChat: PropTypes.func.isRequired, + prepareChatMessage: PropTypes.func.isRequired, users: PropTypes.object, };