diff options
Diffstat (limited to 'src/Chat.js')
-rw-r--r-- | src/Chat.js | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/Chat.js b/src/Chat.js new file mode 100644 index 0000000..175797a --- /dev/null +++ b/src/Chat.js @@ -0,0 +1,164 @@ +import React, { Component } from "react"; +import { w3cwebsocket as W3CWebSocket } from "websocket"; +import { Header, List, Input } from "semantic-ui-react"; +import Moment from "react-moment"; +import "moment/locale/es"; + +class Chat extends Component { + constructor(props) { + super(props); + this.state = { + chat: [], + chatMessage: "", + chatUserCount: 0, + isChatOnline: false + }; + this.client = {}; + this.chatColors = [ + "grey", + "red", + "pink", + "orange", + "yellow", + "green", + "teal", + "blue", + "purple", + "black" + ]; + this.handleOnChange = this.handleOnChange.bind(this); + this.sendMessage = this.sendMessage.bind(this); + } + + handleOnChange(e, data) { + this.setState({ chatMessage: data.value }); + } + + translateColon(msg) { + return msg ? msg.replace(/%3A/g, ":") : ""; + } + + addMessage(message, color, own = false, sender = "") { + var ts = new Date(); + this.setState( + prevState => ({ + chat: [ + ...prevState.chat, + { content: message, color: color, own, timestamp: ts, author: sender } + ], + chatMessage: "" + }), + () => { + let chatContainer = document.getElementById("chatContainer"); + if (chatContainer != null) { + chatContainer.scrollTop = chatContainer.scrollHeight; + } + } + ); + } + + componentWillMount() { + this.client = new W3CWebSocket( + "wss://radio.bienvenidoainternet.org/daemon/" + ); + this.client.onopen = () => { + this.setState({ isChatOnline: true }); + }; + this.client.onmessage = message => { + this.processChatMessage(message.data); + }; + this.client.onerror = () => { + this.setState({ isChatOnline: false }); + this.addMessage("Ha ocurrido un error conectándose al chat.", "red"); + }; + } + + sendMessage() { + const { chatMessage } = this.state; + this.client.send("MSG:1:" + chatMessage); + this.addMessage(chatMessage, "black", true); + this.setState({ chatMessage: "" }); + } + + processChatMessage(line) { + console.log("<< " + line); + const args = line.split(":"); + switch (args[0]) { + case "MSG": + this.addMessage(this.translateColon(args[2]), this.chatColors[args[1]]); + break; + case "FMSG": + this.addMessage( + this.translateColon(args[3]), + this.chatColors[args[2]], + false, + args[1] + ); + break; + case "WELCOME": + this.addMessage("Conectado al chat, " + args[1], "green"); + break; + case "COUNT": + this.setState({ chatUserCount: args[1] }); + break; + case "FLOOD": + this.addMessage( + "Error: Estas enviando mensajes demasido rápido!", + "red" + ); + break; + default: + console.error("[Chat] Unsupported command " + args[0]); + break; + } + } + + render() { + const { chat, chatMessage, chatUserCount, isChatOnline } = this.state; + return ( + <> + <Header as="h3"> + Chat + <Header.Subheader>{`Usuarios en el chat: ${chatUserCount}`}</Header.Subheader> + </Header> + <div id="chatContainer"> + <List> + {chat.map((message, i) => ( + <List.Item key={i}> + [<Moment format="HH:mm:ss" date={message.timestamp} />]{" "} + <span className={`ui text ${message.color}`}> + {message.content} + </span> + </List.Item> + ))} + </List> + </div> + <Input + fluid + size="mini" + action={{ + content: "Enviar", + onClick: () => { + this.sendMessage(); + }, + disabled: !isChatOnline + }} + placeholder="" + value={chatMessage} + onChange={this.handleOnChange} + style={{ marginTop: "0.75em" }} + maxLength={128} + onKeyUp={e => { + let char = e.which || e.keyCode; + if (char === 13) { + this.sendMessage(); + } + }} + disabled={!isChatOnline} + /> + </> + ); + } +} + +export default Chat; |