Browse Source

Fix styling of RoomChat, add real room joining mechanism.

pull/1/head
Titouan Rigoudy 9 years ago
parent
commit
2ef2f63705
8 changed files with 150 additions and 48 deletions
  1. +2
    -1
      package.json
  2. +8
    -2
      src/actions/RoomActions.js
  3. +29
    -0
      src/components/RoomChatMessageList.js
  4. +0
    -3
      src/components/RoomList.js
  5. +58
    -27
      src/containers/RoomChat.js
  6. +7
    -6
      src/containers/RoomsPane.js
  7. +17
    -8
      src/reducers/rooms.js
  8. +29
    -1
      src/styles/styles.scss

+ 2
- 1
package.json View File

@ -28,7 +28,8 @@
"redux-thunk": "~2.0.1",
"redux-logger": "~2.6.1",
"redux-promise": "~0.5.1",
"immutable": "~3.7.6"
"immutable": "~3.7.6",
"react-immutable-proptypes": "~1.7.0"
},
"devDependencies": {
"babel-cli": "6.5.1",


+ 8
- 2
src/actions/RoomActions.js View File

@ -11,7 +11,13 @@ import ControlRequest from "../utils/ControlRequest";
export default ({
getRoomList: () => SocketActions.send(ControlRequest.roomList()),
join: (room) => SocketActions.send(ControlRequest.joinRoom(room)),
join: (room) => (dispatch) => {
dispatch({
type: ROOM_JOIN,
payload: room
});
dispatch(SocketActions.send(ControlRequest.joinRoom(room)));
},
select: (room) => ({
type: ROOM_SELECT,
@ -19,7 +25,6 @@ export default ({
}),
say: (room, message) => (dispatch) => {
dispatch(SocketActions.send(ControlRequest.sayRoom(room, message)));
dispatch({
type: ROOM_SAY,
payload: {
@ -27,5 +32,6 @@ export default ({
message
}
});
dispatch(SocketActions.send(ControlRequest.sayRoom(room, message)));
}
});

+ 29
- 0
src/components/RoomChatMessageList.js View File

@ -0,0 +1,29 @@
import React, { PropTypes } from "react";
import ImmutablePropTypes from "react-immutable-proptypes";
const RoomChatMessageList = ({ messages }) => {
// Append all messages in the chat room.
const children = [];
let i = 0;
for (const { user_name, message } of messages) {
children.push(
<li key={i} className="room-chat-message">
{user_name}: {message}
</li>
);
i++;
}
return (
<div id="room-chat-messages">
<ul>{children}</ul>
</div>
);
};
RoomChatMessageList.propTypes = {
messages: ImmutablePropTypes.list.isRequired
};
export default RoomChatMessageList;

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

@ -20,9 +20,6 @@ class RoomList extends React.Component {
for (const [room_name, room_data] of rooms) {
const onClick = (event) => {
roomActions.select(room_name);
if (!room_data.joined) {
roomActions.join(room_name);
}
};
children.push(


+ 58
- 27
src/containers/RoomChat.js View File

@ -1,42 +1,73 @@
import React, { PropTypes } from "react";
import { connect } from "react-redux";
import RoomActions from "../actions/RoomActions";
import RoomChatForm from "../components/RoomChatForm";
import RoomChatMessageList from "../components/RoomChatMessageList";
const RoomChat = ({ name, data, roomActions }) => {
if (!name) {
return <div id="room-chat">Select a room</div>;
const ID = "room-chat";
const ID_HEADER = "room-chat-header";
class RoomChat extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.join_if_non_member(this.props);
}
componentWillReceiveProps(props) {
this.join_if_non_member(props);
}
join_if_non_member(props) {
const { name, room, roomActions } = props;
if (room && room.membership == "NonMember") {
roomActions.join(name);
}
}
// 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>
render_only_header(string) {
return (
<div id={ID}>
<div id={ID_HEADER}>
{string}
</div>
</div>
);
i++;
}
return (
<div id="room-chat">
<div id="room-chat-header">{name}</div>
<div id="room-chat-messages">
<ul>{children}</ul>
render() {
const { 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");
}
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}`);
}
// room.membership == "Member"
return (
<div id="room-chat">
<div id="room-chat-header">{name}</div>
<RoomChatMessageList messages={room.messages} />
<RoomChatForm name={name} say={roomActions.say} />
</div>
<RoomChatForm
name={name}
say={roomActions.say}
/>
</div>
);
};
);
}
}
RoomChat.propTypes = {
data: PropTypes.object,
room: PropTypes.object,
name: PropTypes.string,
roomActions: PropTypes.object.isRequired
};


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

@ -14,17 +14,18 @@ class RoomsPane extends React.Component {
}
render() {
const { actions, rooms, selected } = this.props;
return (
<div id="rooms-pane">
<RoomList
rooms={this.props.rooms}
roomActions={this.props.actions.room}
selected={this.props.selected}
rooms={rooms}
roomActions={actions.room}
selected={selected}
/>
<RoomChat
name={this.props.selected}
data={this.props.rooms.get(this.props.selected)}
roomActions={this.props.actions.room}
name={selected}
room={rooms.get(selected)}
roomActions={actions.room}
/>
</div>
);


+ 17
- 8
src/reducers/rooms.js View File

@ -43,14 +43,24 @@ const reduceRoomList = (old_rooms, room_list) => {
return new_rooms;
};
const reduceReceiveMessage = (rooms, payload) => {
switch (payload.variant) {
const reduceReceiveMessage = (rooms, { variant, data }) => {
switch (variant) {
case "JoinRoomResponse":
{
const { room_name } = data;
const room = rooms.get(room_name);
return rooms.set(room_name, {
...room,
membership: "Member"
});
}
case "RoomListResponse":
return reduceRoomList(rooms, payload.data.rooms);
return reduceRoomList(rooms, data.rooms);
case "SayRoomResponse":
{
const { room_name, user_name, message } = payload.data;
const { room_name, user_name, message } = data;
const room_data = rooms.get(room_name);
if (!room_data) {
console.log(`Error: room "${room_name} not found`);
@ -88,10 +98,9 @@ export default (state = initialState, action) => {
case ROOM_JOIN:
{
const rooms = state.rooms.merge({
[payload]: {
joined: true
}
const rooms = state.rooms.set(payload, {
...state.rooms.get(payload),
membership: "Joining"
});
return {
...state,


+ 29
- 1
src/styles/styles.scss View File

@ -58,7 +58,6 @@ main {
#room-chat {
border: solid grey 0.1em;
padding: 2em;
}
#room-list {
@ -71,6 +70,35 @@ main {
#room-chat {
flex: 3;
display: flex;
flex-flow: column;
}
#room-chat-header {
text-align: center;
font-size: 1.3em;
padding: 0.8em;
border: solid grey 0.1em;
}
#room-chat-messages {
flex: 1;
}
#room-chat-form {
width: 100%;
border: solid grey 0.1em;
}
#room-chat-form form {
width: 100%;
display: flex;
flex-flow: row;
}
#room-chat-form input {
flex: 1;
padding: 0.8em;
}
#room-list-header {


Loading…
Cancel
Save