Browse Source

Display messages in a modern way.

pull/1/head
Titouan Rigoudy 9 years ago
parent
commit
79226dc594
5 changed files with 97 additions and 26 deletions
  1. +23
    -12
      src/components/RoomChatMessageList.js
  2. +1
    -1
      src/components/SolsticeApp.js
  3. +15
    -4
      src/containers/RoomChat.js
  4. +13
    -6
      src/containers/RoomsPane.js
  5. +45
    -3
      src/styles/styles.scss

+ 23
- 12
src/components/RoomChatMessageList.js View File

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


+ 1
- 1
src/components/SolsticeApp.js View File

@ -23,7 +23,7 @@ const SolsticeApp = (props) => {
<div id={ID}> <div id={ID}>
<Header /> <Header />
<main> <main>
<RoomsPane actions={actions}/>
<RoomsPane roomActions={actions.room}/>
</main> </main>
<Footer actions={actions} /> <Footer actions={actions} />
</div> </div>


+ 15
- 4
src/containers/RoomChat.js View File

@ -1,4 +1,5 @@
import React, { PropTypes } from "react"; import React, { PropTypes } from "react";
import ImmutablePropTypes from "react-immutable-proptypes";
import RoomChatForm from "../components/RoomChatForm"; import RoomChatForm from "../components/RoomChatForm";
import RoomChatMessageList from "../components/RoomChatMessageList"; import RoomChatMessageList from "../components/RoomChatMessageList";
@ -37,7 +38,7 @@ class RoomChat extends React.Component {
} }
render() { render() {
const { name, room, roomActions } = this.props;
const { login_user_name, name, room, roomActions } = this.props;
// If no room is selected, just tell the user to select one. // If no room is selected, just tell the user to select one.
if (!name || !room) { if (!name || !room) {
@ -59,7 +60,10 @@ class RoomChat extends React.Component {
return ( return (
<div id="room-chat"> <div id="room-chat">
<div id="room-chat-header">{name}</div> <div id="room-chat-header">{name}</div>
<RoomChatMessageList messages={room.messages} />
<RoomChatMessageList
login_user_name={login_user_name}
messages={room.messages}
/>
<RoomChatForm name={name} say={roomActions.say} /> <RoomChatForm name={name} say={roomActions.say} />
</div> </div>
); );
@ -67,9 +71,16 @@ class RoomChat extends React.Component {
} }
RoomChat.propTypes = { RoomChat.propTypes = {
room: PropTypes.object,
login_user_name: PropTypes.string.isRequired,
name: PropTypes.string, name: PropTypes.string,
roomActions: PropTypes.object.isRequired
room: PropTypes.shape({
membership: PropTypes.string.isRequired,
messages: ImmutablePropTypes.list.isRequired
}),
roomActions: PropTypes.shape({
join: PropTypes.func.isRequired,
say: PropTypes.func.isRequired
}).isRequired
}; };
export default RoomChat; export default RoomChat;

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

@ -1,6 +1,7 @@
import React, { PropTypes } from "react"; import React, { PropTypes } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { bindActionCreators } from "redux"; import { bindActionCreators } from "redux";
import ImmutablePropTypes from "react-immutable-proptypes";
import RoomList from "../components/RoomList"; import RoomList from "../components/RoomList";
@ -14,18 +15,19 @@ class RoomsPane extends React.Component {
} }
render() { render() {
const { actions, rooms, selected } = this.props;
const { login_user_name, rooms, roomActions, selected } = this.props;
return ( return (
<div id="rooms-pane"> <div id="rooms-pane">
<RoomList <RoomList
rooms={rooms} rooms={rooms}
roomActions={actions.room}
roomActions={roomActions}
selected={selected} selected={selected}
/> />
<RoomChat <RoomChat
login_user_name={login_user_name}
name={selected} name={selected}
room={rooms.get(selected)} room={rooms.get(selected)}
roomActions={actions.room}
roomActions={roomActions}
/> />
</div> </div>
); );
@ -33,12 +35,17 @@ class RoomsPane extends React.Component {
} }
RoomsPane.propTypes = { RoomsPane.propTypes = {
actions: PropTypes.object.isRequired,
rooms: PropTypes.object.isRequired,
login_user_name: PropTypes.string.isRequired,
rooms: ImmutablePropTypes.orderedMap.isRequired,
roomActions: PropTypes.object.isRequired,
selected: PropTypes.string selected: PropTypes.string
}; };
const mapStateToProps = (state) => state.rooms;
const mapStateToProps = (state) => ({
login_user_name: state.login.username,
rooms: state.rooms.rooms,
selected: state.rooms.selected
});
export default connect( export default connect(
mapStateToProps, mapStateToProps,


+ 45
- 3
src/styles/styles.scss View File

@ -41,6 +41,9 @@ header h1 {
footer { footer {
display: flex; display: flex;
padding: 0.5em;
width: 100%;
box-sizing: border-box;
} }
main { main {
@ -69,20 +72,59 @@ main {
} }
#room-chat { #room-chat {
flex: 3;
height: 100%;
width: 75%;
display: flex; display: flex;
flex-flow: column; flex-flow: column;
justify-content: space-between;
} }
#room-chat-header { #room-chat-header {
flex: 1;
text-align: center; text-align: center;
font-size: 1.3em; font-size: 1.3em;
padding: 0.8em; padding: 0.8em;
border: solid grey 0.1em; border: solid grey 0.1em;
} }
#room-chat-messages {
flex: 1;
#room-chat-message-list {
display: block;
height: 84%;
width: 100%;
box-sizing: border-box;
margin: 0;
padding: 1em;
overflow: auto;
list-style: none;
}
.room-chat-message {
display: flex;
flex-flow: column;
align-items: flex-start;
}
.room-chat-message-me {
align-items: flex-end;
}
.room-chat-message-user {
font-weight: bold;
color: blue;
}
.room-chat-message-text {
padding: 0.5em 0.7em;
margin: 0.2em 0.5em;
border-radius: 0.8em;
background-color: lightgrey;
}
.room-chat-message-me > .room-chat-message-text {
background-color: blue;
color: white;
} }
#room-chat-form { #room-chat-form {


Loading…
Cancel
Save