Browse Source

Add RoomChatForm and make chat work :)

pull/1/head
Titouan Rigoudy 9 years ago
parent
commit
46f30ddf79
8 changed files with 131 additions and 52 deletions
  1. +15
    -6
      src/actions/RoomActions.js
  2. +0
    -22
      src/actions/RoomActionsFactory.js
  3. +0
    -1
      src/components/ConnectForm.js
  4. +33
    -0
      src/components/RoomChatForm.js
  5. +0
    -1
      src/components/RoomList.js
  6. +36
    -6
      src/containers/RoomChat.js
  7. +7
    -2
      src/containers/RoomsPane.js
  8. +40
    -14
      src/reducers/rooms.js

+ 15
- 6
src/actions/RoomActions.js View File

@ -1,6 +1,7 @@
import {
ROOM_SELECT,
ROOM_JOIN
ROOM_JOIN,
ROOM_SAY,
ROOM_SELECT
} from "../constants/ActionTypes";
import SocketActions from "./SocketActions";
@ -10,13 +11,21 @@ import ControlRequest from "../utils/ControlRequest";
export default ({
getRoomList: () => SocketActions.send(ControlRequest.roomList()),
join: (room) => SocketActions.send(ControlRequest.joinRoom(room)),
select: (room) => ({
type: ROOM_SELECT,
payload: room
}),
join: (room) => ({
type: ROOM_JOIN,
paylod: room
})
say: (room, message) => (dispatch) => {
dispatch(SocketActions.send(ControlRequest.sayRoom(room, message)));
dispatch({
type: ROOM_SAY,
payload: {
room_name: room,
message
}
});
}
});

+ 0
- 22
src/actions/RoomActionsFactory.js View File

@ -1,22 +0,0 @@
import {
ROOM_SELECT,
ROOM_JOIN
} from "../constants/ActionTypes";
import SocketActions from "./SocketActions";
import ControlRequest from "../utils/ControlRequest";
export default ({
getRoomList: () => SocketActions.send(ControlRequest.roomList()),
select: (room) => ({
type: ROOM_SELECT,
payload: room
}),
join: (room) => ({
type: ROOM_JOIN,
paylod: room
})
});

+ 0
- 1
src/components/ConnectForm.js View File

@ -3,7 +3,6 @@ import {reduxForm} from "redux-form";
import SocketStatusPane from "./SocketStatusPane";
import { STATE_CLOSED } from "../constants/socket";
import ControlRequest from "../utils/ControlRequest";
const ConnectForm = (props) => {
const { fields: { url }, handleSubmit, socket, actions } = props;


+ 33
- 0
src/components/RoomChatForm.js View File

@ -0,0 +1,33 @@
import React, {PropTypes} from "react";
import {reduxForm} from "redux-form";
const RoomChatForm = (props) => {
const { fields: { message }, handleSubmit, name, say } = props;
const onSubmit = handleSubmit((values) => {
say(name, values.message);
});
return (
<div id="room-chat-form">
<form onSubmit={onSubmit}>
<input type="text" defaultValue="Type a message..."
{...message} />
<button type="submit">Send</button>
</form>
</div>
);
};
RoomChatForm.propTypes = {
fields: PropTypes.object.isRequired,
handleSubmit: PropTypes.func.isRequired,
name: PropTypes.string,
say: PropTypes.func.isRequired
};
export default reduxForm({
form: "chat",
fields: ["message"]
})(RoomChatForm);

+ 0
- 1
src/components/RoomList.js View File

@ -17,7 +17,6 @@ class RoomList extends React.Component {
const children = [];
console.log(`Selected: "${selected}"`);
for (const [room_name, room_data] of rooms) {
const onClick = (event) => {
roomActions.select(room_name);


+ 36
- 6
src/containers/RoomChat.js View File

@ -1,14 +1,44 @@
import React, { PropTypes } from "react";
import { connect } from "react-redux";
const RoomChat = ({ name }) => {
return <div id="room-chat">{name}</div>;
import RoomActions from "../actions/RoomActions";
import RoomChatForm from "../components/RoomChatForm";
const RoomChat = ({ name, data, roomActions }) => {
if (!name) {
return <div id="room-chat">Select a room</div>;
}
// Append all messages in the chat room.
const children = [];
let i = 0;
for (const { user_name, message } of data.messages) {
children.push(
<li key={i} class="message">
{user_name}: {message}
</li>
);
i++;
}
return (
<div id="room-chat">
<div id="room-chat-header">{name}</div>
<div id="room-chat-messages">
<ul>{children}</ul>
</div>
<RoomChatForm
name={name}
say={roomActions.say}
/>
</div>
);
};
RoomChat.propTypes = {
name: PropTypes.string
data: PropTypes.object,
name: PropTypes.string,
roomActions: PropTypes.object.isRequired
};
export default connect(
(state) => ({ name: state.rooms.selected })
)(RoomChat);
export default RoomChat;

+ 7
- 2
src/containers/RoomsPane.js View File

@ -21,7 +21,11 @@ class RoomsPane extends React.Component {
roomActions={this.props.actions.room}
selected={this.props.selected}
/>
<RoomChat />
<RoomChat
name={this.props.selected}
data={this.props.rooms.get(this.props.selected)}
roomActions={this.props.actions.room}
/>
</div>
);
}
@ -29,7 +33,8 @@ class RoomsPane extends React.Component {
RoomsPane.propTypes = {
actions: PropTypes.object.isRequired,
rooms: PropTypes.object.isRequired
rooms: PropTypes.object.isRequired,
selected: PropTypes.string
};
const mapStateToProps = (state) => state.rooms;


+ 40
- 14
src/reducers/rooms.js View File

@ -2,6 +2,7 @@ import Immutable from "immutable";
import {
ROOM_JOIN,
ROOM_SAY,
ROOM_SELECT,
SOCKET_RECEIVE_MESSAGE
} from "../constants/ActionTypes";
@ -11,6 +12,19 @@ const initialState = {
selected: null
};
const reduceRoom = (old_room, new_room) => {
if (!old_room) {
return {
messages: Immutable.List(),
...new_room
};
}
return {
...old_room,
...new_room
};
};
const reduceRoomList = (old_rooms, room_list) => {
// First sort the room list by room name
room_list.sort((room_pair_1, room_pair_2) => {
@ -28,28 +42,34 @@ const reduceRoomList = (old_rooms, room_list) => {
let new_rooms = Immutable.OrderedMap();
for (const [ room_name, room_data ] of room_list) {
const old_data = old_rooms.get(room_name);
if (old_data) {
new_rooms = new_rooms.set(room_name, {
...old_data,
...room_data
});
} else {
new_rooms = new_rooms.set(room_name, room_data);
}
const new_data = reduceRoom(old_data, room_data);
new_rooms = new_rooms.set(room_name, new_data);
}
return new_rooms;
};
const reduceReceiveMessage = (state, payload) => {
const reduceReceiveMessage = (rooms, payload) => {
switch (payload.variant) {
case "RoomListResponse":
return {
...state,
rooms: reduceRoomList(state.rooms, payload.data.rooms)
return reduceRoomList(rooms, payload.data.rooms);
case "SayRoomResponse":
{
const { room_name, user_name, message } = payload.data;
const room_data = rooms.get(room_name);
if (!room_data) {
console.log(`Error: room "${room_name} not found`);
return rooms;
}
const new_room_data = {
...room_data,
messages: room_data.messages.push({ user_name, message })
};
return rooms.set(room_name, new_room_data);
}
default:
return state;
return rooms;
}
};
@ -57,7 +77,13 @@ export default (state = initialState, action) => {
const { type, payload } = action;
switch (type) {
case SOCKET_RECEIVE_MESSAGE:
return reduceReceiveMessage(state, payload);
return {
...state,
rooms: reduceReceiveMessage(state.rooms, payload)
};
case ROOM_SAY:
return state;
case ROOM_SELECT:
return {


Loading…
Cancel
Save