Browse Source

Make entire rooms state immutable.

pull/1/head
Titouan Rigoudy 9 years ago
parent
commit
d04a768037
5 changed files with 47 additions and 64 deletions
  1. +5
    -7
      src/components/Room.js
  2. +1
    -2
      src/components/RoomChatHeader.js
  3. +4
    -4
      src/components/RoomList.js
  4. +18
    -15
      src/containers/RoomsPane.js
  5. +19
    -36
      src/reducers/rooms.js

+ 5
- 7
src/components/Room.js View File

@ -1,9 +1,9 @@
import React, { PropTypes } from "react"; import React, { PropTypes } from "react";
import { Link } from "react-router"; import { Link } from "react-router";
const Room = ({ name, room }) => {
const Room = ({ name, membership, userCount }) => {
const classes = ["room"]; const classes = ["room"];
if (room.membership == "Member") {
if (membership == "Member") {
classes.push("room-joined"); classes.push("room-joined");
} }
@ -16,17 +16,15 @@ const Room = ({ name, room }) => {
className={classes.join(" ")} className={classes.join(" ")}
> >
<span className="room-name">{name}</span> <span className="room-name">{name}</span>
<span className="room-user-count">({room.user_count})</span>
<span className="room-user-count">({userCount})</span>
</Link> </Link>
); );
}; };
Room.propTypes = { Room.propTypes = {
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
room: PropTypes.shape({
membership: PropTypes.string.isRequired,
user_count: PropTypes.number.isRequired
})
membership: PropTypes.string.isRequired,
userCount: PropTypes.number.isRequired
}; };
export default Room; export default Room;

+ 1
- 2
src/components/RoomChatHeader.js View File

@ -58,8 +58,7 @@ RoomChatHeader.propTypes = {
showUsers: PropTypes.bool showUsers: PropTypes.bool
}), }),
roomActions: PropTypes.shape({ roomActions: PropTypes.shape({
leave: PropTypes.func.isRequired,
select: PropTypes.func.isRequired
leave: PropTypes.func.isRequired
}).isRequired, }).isRequired,
router: PropTypes.object.isRequired router: PropTypes.object.isRequired
}; };


+ 4
- 4
src/components/RoomList.js View File

@ -13,7 +13,7 @@ class RoomList extends React.Component {
} }
render() { render() {
const { selected, roomMap, roomActions } = this.props;
const { roomMap, roomActions } = this.props;
const children = []; const children = [];
@ -22,7 +22,8 @@ class RoomList extends React.Component {
<li key={roomName}> <li key={roomName}>
<Room <Room
name={roomName} name={roomName}
room={roomData}
membership={roomData.get("membership")}
userCount={roomData.get("user_count")}
/> />
</li> </li>
); );
@ -41,8 +42,7 @@ RoomList.propTypes = {
roomMap: PropTypes.object.isRequired, roomMap: PropTypes.object.isRequired,
roomActions: PropTypes.shape({ roomActions: PropTypes.shape({
getList: PropTypes.func.isRequired getList: PropTypes.func.isRequired
}).isRequired,
selected: PropTypes.string
}).isRequired
}; };
export default RoomList; export default RoomList;

+ 18
- 15
src/containers/RoomsPane.js View File

@ -23,20 +23,24 @@ class RoomsPane extends React.Component {
if (params && params.roomName) { if (params && params.roomName) {
roomName = decodeURIComponent(atob(params.roomName)); roomName = decodeURIComponent(atob(params.roomName));
const { membership, messages, showUsers } = roomMap.get(roomName);
const room = {
name: roomName,
membership,
messages,
showUsers
};
roomChat = (
<RoomChat
loginUserName={loginUserName}
room={room}
roomActions={roomActions}
/>
);
const roomData = roomMap.get(roomName);
if (roomData) {
const room = {
name: roomName,
membership: roomData.get("membership"),
messages: roomData.get("messages"),
showUsers: roomData.get("showUsers")
};
roomChat = (
<RoomChat
loginUserName={loginUserName}
room={room}
roomActions={roomActions}
/>
);
}
} }
return ( return (
@ -44,7 +48,6 @@ class RoomsPane extends React.Component {
<RoomList <RoomList
roomMap={roomMap} roomMap={roomMap}
roomActions={roomActions} roomActions={roomActions}
selected={roomName}
/> />
<div id="room-selected-pane"> <div id="room-selected-pane">
{roomChat} {roomChat}


+ 19
- 36
src/reducers/rooms.js View File

@ -32,16 +32,19 @@ const reduceRoomList = (state, roomList) => {
let newRoomMap = Immutable.OrderedMap(); let newRoomMap = Immutable.OrderedMap();
for (const [ roomName, newRoomData ] of roomList) { for (const [ roomName, newRoomData ] of roomList) {
// Transform room_data.messages to an immutable list.
newRoomData.messages = Immutable.List(newRoomData.messages);
// Get the old room data. // Get the old room data.
const roomData = roomMap.get(roomName);
let roomData = roomMap.get(roomName);
if (roomData) {
// Scrap the old message list, we only want the new message list.
roomData.remove("messages");
} else {
// If the room did not exist, make up an empty one.
roomData = Immutable.Map();
}
// Merge the old data and the new data, overwriting with new data if // Merge the old data and the new data, overwriting with new data if
// conflicting. // conflicting.
const mergedRoomData = {
...roomData,
...newRoomData
};
const mergedRoomData = roomData.merge(newRoomData);
// Insert that in the new room map.
newRoomMap = newRoomMap.set(roomName, mergedRoomData); newRoomMap = newRoomMap.set(roomName, mergedRoomData);
} }
@ -53,24 +56,17 @@ const reduceRoomList = (state, roomList) => {
const reduceReceiveMessageRoom = (roomData, { variant, data }) => { const reduceReceiveMessageRoom = (roomData, { variant, data }) => {
switch (variant) { switch (variant) {
case "RoomJoinResponse": case "RoomJoinResponse":
return {
...roomData,
membership: "Member"
};
return roomData.set("membership", "Member");
case "RoomLeaveResponse": case "RoomLeaveResponse":
return {
...roomData,
membership: "NonMember"
};
return roomData.set("membership", "NonMember");
case "RoomMessageResponse": case "RoomMessageResponse":
{ {
const { user_name, message } = data; const { user_name, message } = data;
return {
...roomData,
messages: roomData.messages.push({ user_name, message })
};
const messages = roomData.get("messages")
.push({user_name, message});
return roomData.set("messages", messages);
} }
} }
}; };
@ -83,7 +79,6 @@ const reduceReceiveMessage = (state, message) => {
case "RoomMessageResponse": case "RoomMessageResponse":
{ {
const { room_name } = data; const { room_name } = data;
const roomMap = state.get("roomMap");
return state.updateIn(["roomMap", data.room_name], (roomData) => { return state.updateIn(["roomMap", data.room_name], (roomData) => {
if (roomData) { if (roomData) {
return reduceReceiveMessageRoom(roomData, message); return reduceReceiveMessageRoom(roomData, message);
@ -105,28 +100,16 @@ const reduceReceiveMessage = (state, message) => {
const reduceRoom = (roomData, { type, payload }) => { const reduceRoom = (roomData, { type, payload }) => {
switch (type) { switch (type) {
case ROOM_JOIN: case ROOM_JOIN:
return {
...roomData,
membership: "Joining"
};
return roomData.set("membership", "Joining");
case ROOM_LEAVE: case ROOM_LEAVE:
return {
...roomData,
membership: "Leaving"
};
return roomData.set("membership", "Leaving");
case ROOM_SHOW_USERS: case ROOM_SHOW_USERS:
return {
...roomData,
showUsers: true
};
return roomData.set("showUsers", true);
case ROOM_HIDE_USERS: case ROOM_HIDE_USERS:
return {
...roomData,
showUsers: false
};
return roomData.set("showUsers", false);
} }
}; };


Loading…
Cancel
Save