aboutsummaryrefslogblamecommitdiff
path: root/src/Chat.js
blob: 41171835b8546fdc308a0cec0d5d07d5f8545998 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13

                                                         
                                                                  









                                  

                           

























                                                         
                                                                         




                            







                             
         



























                                                                            

                                  


                             

                                                                    



                                       


                                 
                                                               









                                       
                                                                             
















                                                               





















                                                                      







                                                                                        








                                                             
























                                            









                                                                       





                    
import React, { Component } from "react";
import { w3cwebsocket as W3CWebSocket } from "websocket";
import { Header, List, Input, Checkbox } 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,
      filterMessages: 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, stream, own = false, sender = "", color = "grey") {
    var ts = new Date();
    this.setState(
      prevState => ({
        chat: [
          ...prevState.chat,
          {
            content: message,
            stream: stream,
            own,
            timestamp: ts,
            author: sender,
            color: color
          }
        ]
      }),
      () => {
        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;
    const { stream } = this.props;
    console.log(stream);
    if (chatMessage === "") {
      return;
    }
    this.client.send(`MSG:${stream.server_name}:${chatMessage}`);
    this.addMessage(chatMessage, stream.server_name, true, "black");
    this.setState({ chatMessage: "" });
  }

  processChatMessage(line) {
    const args = line.split(":");
    switch (args[0]) {
      case "MSG":
        this.addMessage(this.translateColon(args[2]), 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], "", false, "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,
      filterMessages
    } = this.state;
    const { stream } = this.props;

    const MessageItem = ({ message, index }) => {
      return (
        <List.Item key={index}>
          [<Moment format="HH:mm:ss" date={message.timestamp} />]{" "}
          <span className={`ui text ${message.color}`}>
            {`${message.stream && "[" + message.stream + "]"} ${
              message.content
            }`}
          </span>
        </List.Item>
      );
    };

    return (
      <>
        <Header as="h3">
          Chat
          <Header.Subheader>{`Usuarios en el chat: ${chatUserCount}`}</Header.Subheader>
        </Header>
        <div id="chatContainer">
          <List>
            {chat.map((message, i) =>
              filterMessages ? (
                message.stream === stream.server_name && (
                  <MessageItem message={message} index={i} />
                )
              ) : (
                <MessageItem message={message} index={i} />
              )
            )}
          </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}
        />
        <Checkbox
          checked={filterMessages}
          label="Filtrar mensajes de usuarios escuchando stream actual"
          onClick={() => {
            this.setState(prevState => ({
              filterMessages: !prevState.filterMessages
            }));
          }}
          style={{ marginTop: "0.5em" }}
        />
      </>
    );
  }
}

export default Chat;