docbrown/app/javascript/chat/chat.jsx
Mac Siri 8003191a4e Create Chat app (#175)
* Setup Pusher gem

* Create ChatChannel and Message model

* Create ChatChannelController

* Add back fix-db-schema-conflicts gem

* Add pusher-js package

* Add validations on Message & ChatChannel models

* Update Route

* Create MessageController

* Update ChatChannelController

* Create Chat app WIP

* Extract messenger render to Message Component

* Implement live chat WIP

* Implement live chat WIP (2)

* Add style and scrollToBottom feature for chat

* Create getUserDataAndCsrfToken function

* Add feature toggle to the new live chat

* Clean up ChatChannelsController & create spec

* Update ChatChannel spec

* Update Message spec

* Create MessagesController spec & refactor

* Clean up Chat app

* Fix lint

* Add character limit to Message
2018-04-04 14:19:57 -07:00

97 lines
2.4 KiB
JavaScript

import { h, Component } from 'preact';
import PropTypes from 'prop-types';
import { getAllMessages, sendMessage } from './actions';
import { scrollToBottom } from './util';
import Compose from './compose';
import Message from './message';
import setupPusher from './pusher';
class Chat extends Component {
constructor(props) {
super(props);
this.receiveAllMessages = this.receiveAllMessages.bind(this);
this.receiveNewMessage = this.receiveNewMessage.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.handleMessageSubmit = this.handleMessageSubmit.bind(this);
this.handleSubmitOnClick = this.handleSubmitOnClick.bind(this);
this.handleFailure = this.handleFailure.bind(this);
this.state = {
messages: [],
};
}
componentDidMount() {
getAllMessages(this.receiveAllMessages);
setupPusher(this.props.pusherKey, this.receiveNewMessage);
}
componentDidUpdate() {
scrollToBottom();
}
receiveAllMessages(res) {
this.setState({ messages: res.messages });
}
receiveNewMessage(message) {
const newMessages = this.state.messages.slice();
newMessages.push(message);
this.setState({ messages: newMessages });
}
handleKeyDown(e) {
if (e.keyCode === 13) {
e.preventDefault();
this.handleMessageSubmit(e.target.value);
e.target.value = '';
}
}
handleMessageSubmit(message) {
sendMessage(message, null, this.handleFailure);
}
handleSubmitOnClick(e) {
e.preventDefault();
const message = document.getElementById('messageform').value;
sendMessage(message, null, this.handleFailure);
document.getElementById('messageform').value = '';
}
handleFailure(err) {
console.error(err);
}
renderMessage() {
return this.state.messages.map(message => (
<Message
user={message.username}
message={message.message}
timeStamp={message.timestamp}
color={message.color}
/>
));
}
render() {
return (
<div className="chatchannel">
<div className="chatchannel__messages" id="messagelist">
{ this.renderMessage() }
</div>
<div className="chatchannel__form">
<Compose
handleKeyDown={this.handleKeyDown}
handleSubmitOnClick={this.handleSubmitOnClick}
/>
</div>
</div>
);
}
}
Chat.propTypes = {
pusherKey: PropTypes.number.isRequired,
};
export default Chat;