diff --git a/package.json b/package.json index ef9fa82..e751a55 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,11 @@ "version": "0.1.0", "private": true, "dependencies": { + "lodash": "^4.17.11", + "moment": "^2.24.0", "react": "^16.2.0", "react-dom": "^16.2.0", + "react-moment": "^0.8.4", "react-scripts": "1.1.0" }, "scripts": { @@ -13,4 +16,4 @@ "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" } -} \ No newline at end of file +} diff --git a/src/App.css b/src/App.css index 43515ed..d1d9390 100644 --- a/src/App.css +++ b/src/App.css @@ -35,3 +35,21 @@ body, .textInput input { width: 100%; } + +.message { + border: 2px solid #dedede; + background-color: #f1f1f1; + border-radius: 5px; + padding: 5px; + margin: 5px; +} + +.message.error { + font-weight: bold; + color: #f00; +} + +.message.command { + font-weight: bold; + color: #008000; +} \ No newline at end of file diff --git a/src/App.js b/src/App.js index 932a66d..1689714 100644 --- a/src/App.js +++ b/src/App.js @@ -1,17 +1,79 @@ import React, { Component } from "react"; +import moment from "moment"; +import * as _ from "lodash"; + import MessageBar from "./MessageBar"; import ChatArea from "./ChatArea"; import "./App.css"; +const TIME_FORMAT = 'YYYY-MM-DD hh:mm:ss'; +export const MESSAGE_TYPE = { + NORMAL: '', + COMMAND: 'command', + ERROR: 'error' +}; + class App extends Component { - render() { - return ( -
- - -
- ); + + constructor(props) { + super(props); + + this.sendMessage = this.sendMessage.bind(this); + + this.state = { + messages: [], + starWarsCharacters: [], + messageBarDisabled: false, + }; + } + + sendMessage(message) { + message = _.trim(message); + + if (_.startsWith(message, '/')) { + if (message === '/time') { + this._pushMessage(moment().format(TIME_FORMAT), MESSAGE_TYPE.COMMAND); + } else if (_.startsWith(message, '/starwars ') && (_.size(message) > 10)) { + const searchString = _.trimStart(message, '/starwars '); + + fetch(`https://swapi.co/api/people/?search=${searchString}`) + .then(res => res.json()) + .then( + (result) => { + if (_.size(message.results) > 0) { + this._pushMessage(result.results[0].name, MESSAGE_TYPE.COMMAND) + } else { + this._pushMessage(`No character matches "${searchString}"!`, MESSAGE_TYPE.ERROR) + } + }, + + (error) => { + const message = _.get(error, ['detail'], 'Some things went wrong!'); + this._pushMessage(message, MESSAGE_TYPE.ERROR); + } + ); + } else if (message === '/goodbye') { + this._pushMessage('Goodbye!', MESSAGE_TYPE.COMMAND, { messageBarDisabled: true }); + } else { + this._pushMessage(`Your command "${message}" does not exist!`, MESSAGE_TYPE.ERROR); + } + } else if (!_.isEmpty(message)) { + this._pushMessage(message, MESSAGE_TYPE.NORMAL); } + } + + _pushMessage(message, type, extraState = {}) { + this.setState({ messages: [...this.state.messages, { message, type }], ...extraState }); + } + + render() { + return ( +
+ + +
+ ); + } } export default App; diff --git a/src/ChatArea.js b/src/ChatArea.js index c4e314c..ea9d8d3 100644 --- a/src/ChatArea.js +++ b/src/ChatArea.js @@ -2,7 +2,13 @@ import React, { Component } from "react"; class ChatArea extends Component { render() { - return
; + return ( +
+ {this.props.messages.map((message, i) => ( +
{message.message}
+ ))} +
+ ); } } diff --git a/src/MessageBar.js b/src/MessageBar.js index 05a6028..1da18bb 100644 --- a/src/MessageBar.js +++ b/src/MessageBar.js @@ -3,14 +3,37 @@ import TextInput from "./TextInput"; import SendButton from "./SendButton"; class MessageBar extends Component { - render() { - return ( -
- - -
- ); - } + + constructor(props) { + super(props); + + this.onTextInputChange = this.onTextInputChange.bind(this); + this.onSubmit = this.onSubmit.bind(this); + this.state = { + message: '', + }; + } + + onTextInputChange(e) { + this.setState({ message: e.target.value }); + } + + onSubmit(e) { + e.preventDefault(); + this.props.sendMessage(this.state.message); + this.setState({ message: '' }); + } + + render() { + return ( +
+
+ + +
+
+ ); + } } export default MessageBar; diff --git a/src/SendButton.js b/src/SendButton.js index dd4ae98..bc8a076 100644 --- a/src/SendButton.js +++ b/src/SendButton.js @@ -2,7 +2,7 @@ import React, { Component } from "react"; class SendButton extends Component { render() { - return ; + return ; } } diff --git a/src/TextInput.js b/src/TextInput.js index 4b2acd0..7ddfb0f 100644 --- a/src/TextInput.js +++ b/src/TextInput.js @@ -4,7 +4,7 @@ class MessageBar extends Component { render() { return (
- +
); } diff --git a/yarn.lock b/yarn.lock index 696d7d4..8292afc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3962,6 +3962,11 @@ lodash.uniq@^4.5.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" +lodash@^4.17.11: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + loglevel@^1.4.1: version "1.6.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa" @@ -4162,6 +4167,11 @@ mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.0, mkdi dependencies: minimist "0.0.8" +moment@^2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -5149,6 +5159,11 @@ react-error-overlay@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-4.0.0.tgz#d198408a85b4070937a98667f500c832f86bd5d4" +react-moment@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/react-moment/-/react-moment-0.8.4.tgz#18eb59e1541c8b216353e23c21e9db50e42e2edb" + integrity sha512-QhI19OcfhiAn60/O6bMR0w8ApXrPFCjv6+eV0I/P9/AswzjgEAx4L7VxMBCpS/jrythLa12Q9v88req+ys4YpA== + react-scripts@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-1.1.0.tgz#0c94b2b2e14cff2dad8919397901b5edebeba511"