Skip to content

Commit 3f455f4

Browse files
committed
Refactorized React client side into folders, added chat with pubnub-react npm module
1 parent bc697c4 commit 3f455f4

File tree

11 files changed

+213
-36
lines changed

11 files changed

+213
-36
lines changed

client/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"version": "0.1.0",
44
"private": true,
55
"dependencies": {
6+
"pubnub-react": "^1.0.1",
67
"react": "^15.6.1",
78
"react-dom": "^15.6.1",
89
"react-scripts": "1.0.11"

client/public/index.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
-->
1111
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
1212
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
13+
14+
15+
<!-- Import Google Icon Font -->
16+
<link rel="stylsheet" href="//fonts.googleapis.com/icon?family=Material+Icons" />
17+
<!-- Import materialize.css -->
18+
<link type="text/css" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css" media="screen,projection" />
19+
1320
<!--
1421
Notice the use of %PUBLIC_URL% in the tags above.
1522
It will be replaced with the URL of the `public` folder during the build.
@@ -36,5 +43,6 @@
3643
To begin the development, run `npm start` or `yarn start`.
3744
To create a production bundle, use `npm run build` or `yarn build`.
3845
-->
46+
3947
</body>
4048
</html>

client/src/App.js

Lines changed: 0 additions & 32 deletions
This file was deleted.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import * as React from 'react';
2+
3+
const ChatHistory = (props) => {
4+
5+
// we’ll use the curly braces to output the result of the array map, since we’ll
6+
// be returning JSX in our array map.Wrap the <li> so that it looks like so:
7+
//It’s important to add a ‘key’ attribute to the list item.
8+
// Whenever you repeat values in JSX, React needs a unique identifier so that it can apply updates as needed to that DOM element.
9+
// Since our messages have a timestamp down to the millisecond, this should be adequate.
10+
11+
12+
return (
13+
<ul className="collection">
14+
{ props.history.map((messageObj) => {
15+
let imgURL = '//robohash.org/' + messageObj.Who +'?set=set2&bgset=bg2&size=70x70';
16+
let messageDate = new Date(messageObj.When);
17+
let messageDateTime = messageDate.toLocaleDateString() +' at ' + messageDate.toLocaleTimeString();
18+
return (
19+
<li className="collection-item avatar" key={ messageObj.When }>
20+
<img src={ imgURL } alt={ messageObj.Who } className="circle" />
21+
<div className="title">Anonymous robot #{ messageObj.Who }</div>
22+
<div>{ messageObj.What }</div>
23+
<div className="message-date">{ messageDateTime }</div>
24+
</li>
25+
); })
26+
}
27+
</ul>
28+
);
29+
30+
}
31+
32+
export default ChatHistory;

client/src/components/ChatInput.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import * as React from 'react';
2+
3+
export default class ChatInput extends React.Component {
4+
5+
constructor(props){
6+
super(props);
7+
8+
this.onSubmit = (e) => {
9+
e.preventDefault();
10+
// Check if the message is empty
11+
const message = this.refs.txtMessage.value;
12+
if (message.length === 0) {
13+
return;
14+
}
15+
// Build a message object and send it
16+
const messageObj = {
17+
Who: this.props.userID,
18+
What: message,
19+
When: new Date().valueOf(),
20+
};
21+
this.props.sendMessage(messageObj);
22+
23+
// Clear the input field and set focus
24+
this.refs.txtMessage.value = '';
25+
this.refs.txtMessage.focus();
26+
};
27+
this.userID=props.userID;
28+
this.imgURL = '//robohash.org/' + props.userID + '?set=set2&bgset=bg2&size=70x70';
29+
30+
}
31+
32+
33+
34+
componentDidMount() {
35+
this.refs.txtMessage.focus();
36+
}
37+
38+
39+
render() {
40+
return (
41+
<footer className="teal">
42+
<form className="container" onSubmit={ this.onSubmit }>
43+
<div className="row">
44+
<div className="input-field col s10">
45+
<i className="prefix mdi-communication-chat" />
46+
<input type="text" ref="txtMessage" placeholder="Type your message" />
47+
<span className="chip left">
48+
<img src={ this.imgURL } alt="Robot 1"/>
49+
<span>Anonymous robot #{ this.userID }</span>
50+
</span>
51+
</div>
52+
<div className="input-field col s2">
53+
<button type="submit" className="waves-effect waves-light btn-floating btn-large">
54+
<i className="mdi-content-send" />
55+
</button>
56+
</div>
57+
</div>
58+
</form>
59+
</footer>
60+
);
61+
}
62+
}
File renamed without changes.

client/src/containers/App.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import React from 'react';
2+
import ChatInput from '../components/ChatInput';
3+
import ChatHistory from '../components/ChatHistory';
4+
import PubNubReact from 'pubnub-react';
5+
import './App.css';
6+
7+
class App extends React.Component {
8+
constructor(props){
9+
super(props);
10+
this.state = {
11+
userID: Math.round(Math.random() * 1000000).toString(),
12+
history: [],
13+
};
14+
15+
this.PubNubReact = new PubNubReact({
16+
publishKey: 'pub-c-16087bca-e20e-4ab4-9047-725901d50ffe',
17+
subscribeKey: 'sub-c-070667ae-8848-11e7-953d-ce3f2a1d1460'
18+
});
19+
20+
this.sendMessage = (message) => {
21+
// for now this will let us know things work. `console` will give us a
22+
// warning though
23+
console.log('sendMessage', message);
24+
this.PubNubReact.publish({
25+
channel: 'ReactChat',
26+
message: message,
27+
});
28+
}
29+
this.replyMessage = (message) => {
30+
fetch('/chat')
31+
.then(res => res.json())
32+
.then(users => console.log({ users }));
33+
console.log('replyMessage', message);
34+
// this.PubNubReact.publish({
35+
// channel: 'ReactChat',
36+
// message: message,
37+
// });
38+
}
39+
40+
}
41+
42+
componentWillMount() {
43+
this.PubNubReact.init(this);
44+
this.PubNubReact.subscribe({
45+
channels: ['ReactChat'],
46+
withPresence: true
47+
});
48+
49+
this.PubNubReact.getMessage('ReactChat', (message) => {
50+
console.log("message is:", message);
51+
this.setState({
52+
history: this.state.history.concat(message.message)
53+
})
54+
console.log(this.state.history);
55+
});
56+
57+
}
58+
59+
componentDidMount() {
60+
61+
fetch('/users')
62+
.then(res => res.json())
63+
.then(users => console.log({ users }));
64+
65+
66+
}
67+
68+
render() {
69+
return (
70+
<div>
71+
<ChatHistory history={ this.state.history } />
72+
<ChatInput userID={ this.state.userID } sendMessage={ this.sendMessage } replyMessage={this.replyMessage}/>
73+
</div>
74+
);
75+
}
76+
}
77+
78+
export default App;
File renamed without changes.

client/src/index.css

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,31 @@
1-
body {
2-
margin: 0;
1+
/* Application specific CSS */
2+
3+
/* ChatInput styles */
4+
footer {
5+
color: white;
6+
position: fixed;
37
padding: 0;
4-
font-family: sans-serif;
8+
bottom: 0;
9+
left: 0;
10+
width: 100%;
11+
height: 130px;
12+
}
13+
footer .input-field input,
14+
button {
15+
border-color: #FFFFFF;
16+
}
17+
.chip {
18+
font-style: italic;
19+
}
20+
21+
/* ChatHistory styles */
22+
.collection {
23+
margin-bottom:130px;
24+
margin-top: -1px;
25+
}
26+
.message-date {
27+
color: #585858;
28+
}
29+
body {
30+
background: #EEEEEE;
531
}

client/src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import ReactDOM from 'react-dom';
33
import './index.css';
4-
import App from './App';
4+
import App from './containers/App';
55
import registerServiceWorker from './registerServiceWorker';
66

77
ReactDOM.render(<App />, document.getElementById('root'));

0 commit comments

Comments
 (0)