aboutsummaryrefslogtreecommitdiff
path: root/src/App.js
diff options
context:
space:
mode:
authorLibravatar Renard 2020-03-08 18:04:24 -0300
committerLibravatar Renard 2020-03-08 18:04:24 -0300
commitd647b3e6628d76dbe207ce5991335c30787a8a6d (patch)
tree7881d6a43398a01b20a7e60c2e21b8d3b082b87c /src/App.js
downloadbairadio-app-d647b3e6628d76dbe207ce5991335c30787a8a6d.tar.gz
bairadio-app-d647b3e6628d76dbe207ce5991335c30787a8a6d.tar.xz
bairadio-app-d647b3e6628d76dbe207ce5991335c30787a8a6d.zip
First commit
Diffstat (limited to 'src/App.js')
-rw-r--r--src/App.js467
1 files changed, 467 insertions, 0 deletions
diff --git a/src/App.js b/src/App.js
new file mode 100644
index 0000000..3260705
--- /dev/null
+++ b/src/App.js
@@ -0,0 +1,467 @@
+import React, { Component } from "react";
+import { render } from "react-dom";
+import {
+ Container,
+ Header,
+ Icon,
+ Grid,
+ Segment,
+ List,
+ Input,
+ Message,
+ Dropdown
+} from "semantic-ui-react";
+import "fomantic-ui-css/semantic.min.css";
+import { w3cwebsocket as W3CWebSocket } from "websocket";
+import Moment from "react-moment";
+import "moment/locale/es";
+import "./App.css";
+import StreamInfo from "./StreamInfo";
+
+const client = new W3CWebSocket("wss://radio.bienvenidoainternet.org/daemon/");
+const chatColors = [
+ "grey",
+ "red",
+ "pink",
+ "orange",
+ "yellow",
+ "green",
+ "teal",
+ "blue",
+ "purple",
+ "black"
+];
+class App extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ ready: false,
+ response: {},
+ history: [],
+ chat: [],
+ chatMessage: "",
+ infoUpdate: {},
+ currentSong: "",
+ streamsAvailable: [],
+ multipleSources: false,
+ selectedStream: 0,
+ chatUserCount: 0,
+ isChatOnline: false
+ };
+ this.handleOnChange = this.handleOnChange.bind(this);
+ this.sendMessage = this.sendMessage.bind(this);
+ this.streamCount = 0;
+ }
+
+ checkStream(result) {
+ const prevCount = this.streamCount;
+ if (result.source !== undefined) {
+ if (Array.isArray(result)) {
+ this.streamCount = result.length;
+ } else {
+ this.streamCount = 1;
+ }
+ } else {
+ this.streamCount = 0;
+ }
+ return prevCount === this.streamCount;
+ }
+
+ 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;
+ }
+ }
+ );
+ }
+
+ log(object) {
+ if (process.env.NODE_ENV === "development") {
+ console.log(object);
+ }
+ }
+
+ refreshPlayer() {
+ let audio = document.getElementById("player");
+ if (audio !== null) {
+ audio.pause();
+ audio.load();
+ audio.play();
+ }
+ }
+
+ addToHistory(song) {
+ this.setState(prevState => ({
+ history: [...prevState.history, song]
+ }));
+ let historyContainer = document.getElementById("historyContainer");
+ if (historyContainer != null) {
+ historyContainer.scrollTop = historyContainer.scrollHeight;
+ }
+ }
+
+ sendMessage() {
+ const { chatMessage } = this.state;
+ client.send("MSG:1:" + chatMessage);
+ this.addMessage(chatMessage, "black", true);
+ this.setState({ chatMessage: "" });
+ }
+
+ componentWillMount() {
+ client.onopen = () => {
+ //console.info("[Chat] Connected to BaiTV Chat!");
+ this.setState({ isChatOnline: true });
+ };
+ client.onmessage = message => {
+ //console.info("[Chat] Message: " + message.data);
+ this.processChatMessage(message.data);
+ };
+ client.onerror = () => {
+ this.setState({ isChatOnline: false });
+ this.addMessage("Ha ocurrido un error conectándose al chat.", "red");
+ //console.error("[Chat] Ha ocurrido un error");
+ };
+ }
+
+ translateColon(msg) {
+ return msg ? msg.replace(/%3A/g, ":") : "";
+ }
+
+ processChatMessage(line) {
+ console.log("<< " + line);
+ const args = line.split(":");
+ switch (args[0]) {
+ case "MSG":
+ this.addMessage(this.translateColon(args[2]), chatColors[args[1]]);
+ break;
+ case "FMSG":
+ this.addMessage(
+ this.translateColon(args[3]),
+ 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;
+ }
+ }
+
+ handleOnChange(e, data) {
+ this.setState({ chatMessage: data.value });
+ }
+
+ compareSongs() {
+ const {
+ currentSong,
+ multipleSources,
+ selectedStream,
+ response
+ } = this.state;
+ const currentStream = multipleSources
+ ? response.source[selectedStream]
+ : response.source;
+
+ if (`${currentStream.artist} - ${currentStream.title}` !== currentSong) {
+ this.addToHistory(currentSong);
+ this.setState({
+ currentSong: `${currentStream.artist} - ${currentStream.title}`
+ });
+ }
+ }
+
+ updateInfo() {
+ const {
+ currentSong,
+ multipleSources,
+ selectedStream,
+ response
+ } = this.state;
+ const currentStream = multipleSources
+ ? response.source[selectedStream]
+ : response.source;
+ if (currentSong === "") {
+ this.setState({
+ currentSong: `${currentStream.artist} - ${currentStream.title}`
+ });
+ }
+
+ fetch("https://bienvenidoainternet.org:8443/status-json.xsl")
+ .then(response => response.json())
+ .then(result => {
+ this.log(result);
+ this.checkStream(result);
+ const source = result.icestats.source;
+ if (source !== undefined) {
+ let multipleStreams = Array.isArray(source);
+ if (!multipleStreams && Array.isArray(this.state.response.source)) {
+ this.setState(
+ {
+ response: result.icestats,
+ streamsAvailable: [],
+ multipleSources: multipleStreams,
+ selectedStream: 0
+ },
+ () => this.compareSongs()
+ );
+ this.refreshPlayer();
+ } else {
+ let streams = [];
+ if (Array.isArray(source)) {
+ source.map((stream, index) =>
+ streams.push({
+ key: index,
+ value: index,
+ text: `[${stream.listeners}] ${stream.server_name} - ${stream.server_description}`
+ })
+ );
+ }
+ this.setState(
+ {
+ response: result.icestats,
+ streamsAvailable: streams,
+ multipleSources: multipleStreams
+ },
+ () => this.compareSongs()
+ );
+ }
+ } else {
+ // No hay streams disponibles
+ this.setState(
+ {
+ response: result.icestats,
+ multipleSources: true,
+ streamsAvailable: {},
+ selectedStream: 0
+ },
+ () => this.compareSongs()
+ );
+ }
+ });
+ }
+
+ componentDidMount() {
+ fetch("https://bienvenidoainternet.org:8443/status-json.xsl")
+ .then(response => response.json())
+ .then(result =>
+ this.setState(
+ {
+ response: result.icestats,
+ infoUpdate: setInterval(() => this.updateInfo(), 10000)
+ },
+ () => {
+ const { source } = this.state.response;
+ if (source !== undefined && Array.isArray(source)) {
+ let streams = [];
+ source.map((stream, index) =>
+ streams.push({
+ key: index,
+ value: index,
+ text: `[${stream.listeners}] ${stream.server_name} - ${stream.server_description}`
+ })
+ );
+ console.log(streams);
+ this.setState({
+ multipleSources: true,
+ streamsAvailable: streams,
+ ready: true
+ });
+ } else if (source !== undefined) {
+ this.setState({
+ multipleSources: false,
+ selectedStream: 0,
+ ready: true
+ });
+ }
+ }
+ )
+ );
+ }
+
+ render() {
+ const {
+ ready,
+ response,
+ history,
+ chat,
+ chatMessage,
+ streamsAvailable,
+ multipleSources,
+ selectedStream,
+ chatUserCount,
+ isChatOnline
+ } = this.state;
+ const isOnline = response.source !== undefined;
+
+ if (!ready) {
+ return "Loading";
+ }
+
+ const currentStream = multipleSources
+ ? response.source[selectedStream]
+ : response.source;
+
+ const currentStreamURL = currentStream.listenurl.replace(
+ "http://bienvenidoainternet.org:8000",
+ "https://bienvenidoainternet.org:8443"
+ );
+
+ return (
+ <Container style={{ paddingTop: "50px" }}>
+ <Segment style={{ padding: "2em" }}>
+ <Grid stackable>
+ <Grid.Row columns={2}>
+ <Grid.Column>
+ <Header as="h2">
+ <Icon name="broadcast tower" />
+ <Header.Content>
+ BaiRadio
+ <Header.Subheader>
+ {ready ? response.server_id : "Sin información"}
+ </Header.Subheader>
+ </Header.Content>
+ </Header>
+ </Grid.Column>
+
+ <Grid.Column floated="right">
+ <audio
+ xmlns="http://www.w3.org/1999/xhtml"
+ controls="controls"
+ preload="none"
+ autoPlay
+ id="player"
+ >
+ <source src={currentStreamURL} type="application/ogg" />
+ </audio>
+ </Grid.Column>
+ </Grid.Row>
+
+ <Grid.Row divided columns={2}>
+ <Grid.Column width={6}>
+ {isOnline ? (
+ <>
+ {multipleSources && (
+ <>
+ <label className="dropdownLabel">
+ Transmisiones disponibles:
+ </label>
+ <Dropdown
+ defaultValue={0}
+ fluid
+ selection
+ options={streamsAvailable}
+ onChange={(e, d) =>
+ this.setState({ selectedStream: d.value }, () => {
+ let audio = document.getElementById("player");
+ if (audio !== null) {
+ audio.pause();
+ audio.load();
+ audio.play();
+ }
+ })
+ }
+ />
+ </>
+ )}
+
+ <Header as="h3">Información de la transmisión</Header>
+ <StreamInfo stream={currentStream} />
+ </>
+ ) : (
+ <Message negative>
+ <Message.Header>Oops</Message.Header>
+ Actualmente no hay nadie transmitiendo en Bai Radio
+ </Message>
+ )}
+
+ <Header as="h3">Historial de canciones</Header>
+ <div id="historyContainer">
+ <List>
+ {history.map((song, i) => (
+ <List.Item key={i}>
+ <List.Icon name="music" />
+ <List.Content>{song}</List.Content>
+ </List.Item>
+ ))}
+ </List>
+ </div>
+ </Grid.Column>
+ <Grid.Column width={10}>
+ <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}
+ />
+ </Grid.Column>
+ </Grid.Row>
+ </Grid>
+ </Segment>
+ <Container textAlign="center">
+ <span className="ui text grey">
+ Bienvenido a Internet 2010 - 2020
+ </span>
+ </Container>
+ </Container>
+ );
+ }
+}
+
+export default App;