diff --git a/src/actions/RoomActions.js b/src/actions/RoomActions.js index 4fb64f9..2a6d243 100644 --- a/src/actions/RoomActions.js +++ b/src/actions/RoomActions.js @@ -1,5 +1,6 @@ import { ROOM_JOIN, + ROOM_LEAVE, ROOM_MESSAGE, ROOM_SELECT } from "../constants/ActionTypes"; @@ -11,27 +12,37 @@ import ControlRequest from "../utils/ControlRequest"; export default ({ getRoomList: () => SocketActions.send(ControlRequest.roomList()), - join: (room) => (dispatch) => { + join: (room_name) => (dispatch) => { dispatch({ type: ROOM_JOIN, - payload: room + payload: room_name }); - dispatch(SocketActions.send(ControlRequest.roomJoin(room))); + dispatch(SocketActions.send(ControlRequest.roomJoin(room_name))); }, - select: (room) => ({ + leave: (room_name) => (dispatch) => { + dispatch({ + type: ROOM_LEAVE, + payload: room_name + }); + dispatch(SocketActions.send(ControlRequest.roomLeave(room_name))); + }, + + select: (room_name) => ({ type: ROOM_SELECT, - payload: room + payload: room_name }), - sendMessage: (room, message) => (dispatch) => { + sendMessage: (room_name, message) => (dispatch) => { dispatch({ type: ROOM_MESSAGE, payload: { - room_name: room, + room_name, message } }); - dispatch(SocketActions.send(ControlRequest.roomMessage(room, message))); + dispatch(SocketActions.send( + ControlRequest.roomMessage(room_name, message) + )); } }); diff --git a/src/components/RoomChatHeader.js b/src/components/RoomChatHeader.js new file mode 100644 index 0000000..7e50dca --- /dev/null +++ b/src/components/RoomChatHeader.js @@ -0,0 +1,43 @@ +import React, { PropTypes } from "react"; +import ImmutablePropTypes from "react-immutable-proptypes"; + +const ID = "room-chat-header"; + +const RoomChatHeader = ({ membership, room_name, roomActions }) => { + switch (membership) { + case "Member": + { + const onClick = (event) => { + roomActions.leave(room_name); + roomActions.select(null); + event.preventDefault(); + }; + return ( +
+ {room_name} + +
+ ); + } + + case "NonMember": + return
Not a member of {room_name}
; + + case "Joining": + return
Joining {room_name}
; + + case "Leaving": + return
Leaving {room_name}
; + } +}; + +RoomChatHeader.propTypes = { + membership: PropTypes.string.isRequired, + room_name: PropTypes.string.isRequired, + roomActions: PropTypes.shape({ + leave: PropTypes.func.isRequired, + select: PropTypes.func.isRequired + }).isRequired +}; + +export default RoomChatHeader; diff --git a/src/constants/ActionTypes.js b/src/constants/ActionTypes.js index 67421e3..b87281b 100644 --- a/src/constants/ActionTypes.js +++ b/src/constants/ActionTypes.js @@ -10,4 +10,5 @@ export const SOCKET_SEND_MESSAGE = "SOCKET_SEND_MESSAGE"; // Room actions export const ROOM_SELECT = "ROOM_SELECT"; export const ROOM_JOIN = "ROOM_JOIN"; +export const ROOM_LEAVE = "ROOM_LEAVE"; export const ROOM_MESSAGE = "ROOM_MESSAGE"; diff --git a/src/containers/RoomChat.js b/src/containers/RoomChat.js index 24671b2..70c1633 100644 --- a/src/containers/RoomChat.js +++ b/src/containers/RoomChat.js @@ -2,10 +2,10 @@ import React, { PropTypes } from "react"; import ImmutablePropTypes from "react-immutable-proptypes"; import RoomChatForm from "../components/RoomChatForm"; +import RoomChatHeader from "../components/RoomChatHeader"; import RoomChatMessageList from "../components/RoomChatMessageList"; const ID = "room-chat"; -const ID_HEADER = "room-chat-header"; class RoomChat extends React.Component { constructor(props) { @@ -27,39 +27,34 @@ class RoomChat extends React.Component { } } - render_only_header(string) { - return ( -
-
- {string} -
-
- ); - } - render() { const { login_user_name, name, room, roomActions } = this.props; // If no room is selected, just tell the user to select one. if (!name || !room) { - return this.render_only_header("Select a room"); + return
Select a room
; } - switch (room.membership) { - case "NonMember": - return this.render_only_header(`Not a member of ${name}`); - - case "Joining": - return this.render_only_header(`Joining ${name}`); - - case "Leaving": - return this.render_only_header(`Leaving ${name}`); + if (room.membership != "Member") { + return ( +
+ +
+ ); } // room.membership == "Member" return ( -
-
{name}
+
+ { }); } + case "RoomLeaveResponse": + { + const room_name = data; + const room = rooms.get(room_name); + return rooms.set(room_name, { + ...room, + membership: "NonMember" + }); + } + case "RoomListResponse": return reduceRoomList(rooms, data.rooms); @@ -108,6 +119,18 @@ export default (state = initialState, action) => { }; } + case ROOM_LEAVE: + { + const rooms = state.rooms.set(payload, { + ...state.rooms.get(payload), + membership: "Leaving" + }); + return { + ...state, + rooms + }; + } + default: return state; } diff --git a/src/utils/ControlRequest.js b/src/utils/ControlRequest.js index 79af814..332b457 100644 --- a/src/utils/ControlRequest.js +++ b/src/utils/ControlRequest.js @@ -4,9 +4,14 @@ export default { fields: [] }), - roomJoin: (room) => ({ + roomJoin: (room_name) => ({ variant: "RoomJoinRequest", - fields: [room] + fields: [room_name] + }), + + roomLeave: (room_name) => ({ + variant: "RoomLeaveRequest", + fields: [room_name] }), roomList: () => ({