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",
timestamp = ""
) {
let ts;
if (timestamp) {
ts = new Date(parseInt(timestamp));
console.log(ts);
} else {
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 "HMSG":
console.log(line);
this.addMessage(
this.translateColon(args[3]),
args[2],
false,
"",
"grey",
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");
this.client.send("HISTORY:10");
break;
case "COUNT":
this.setState({ chatUserCount: args[1] });
break;
case "FLOOD":
this.addMessage(
"Error: Estas enviando mensajes demasido rápido!",
"red"
);
break;
case "HISTORY_OK":
/* Renard: z411: que hago con el HISTORY_OK?
Renard: me lo meto en la raja?
z411: bien adentro */
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;