aboutsummaryrefslogblamecommitdiff
path: root/src/App.js
blob: 50177ed7f8af36376cfd019dec3ebf898a648af0 (plain) (tree)
1
2
3
4
5
6
7
8
9
                                         






            
          

           

                                          

                                      
                          
 






                             



                             
                       
      
                         
                         

   
                       
                                       


                                         








                                          
                 























                                                                       





































                                                                             
                           
                                              
                                                       























                                                                                                    












                                                                     



                                          

                                                  
                


                                    



























                                                                   
                                     








                                                                                                    
                                  




                                          
                                                      





                                              
                                                   










               

                       
                    



                                                   











                                                                 






















































                                                                          
                                                

                                                                              


                                                                           


































                                                                            
                        














                                             
import React, { Component } from "react";
import {
  Container,
  Header,
  Icon,
  Grid,
  Segment,
  List,
  Message,
  Dropdown,
  Loader
} from "semantic-ui-react";
import "fomantic-ui-css/semantic.min.css";
import "./App.css";
import StreamInfo from "./StreamInfo";
import Chat from "./Chat";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      ready: false,
      response: {},
      history: [],
      infoUpdate: {},
      currentSong: "",
      streamsAvailable: [],
      multipleSources: false,
      selectedStream: 0
    };
    this.streamCount = 0;
    this.streamName = "";
  }

  checkStream(source) {
    const prevCount = this.streamCount;
    if (source !== undefined) {
      if (Array.isArray(source)) {
        this.streamCount = source.length;
      } else {
        this.streamCount = 1;
      }
    } else {
      this.streamCount = 0;
    }
    return prevCount === this.streamCount;
  }

  debug(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;
    }
  }

  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.debug(result);
        const source = result.icestats.source;
        const countChanged = !this.checkStream(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}`
                })
              );
            }
            let prevSelectedStream = this.state.selectedStream;
            if (countChanged) {
              let prevStream = source.find(
                s => s.server_name === this.streamName
              );
              prevSelectedStream = source.indexOf(prevStream);
              if (prevSelectedStream === -1) {
                prevSelectedStream = 0; // TODO: Mostrar mensaje
              }
              if (this.state.selectedStream !== prevSelectedStream) {
                this.refreshPlayer();
              }
            }
            this.setState(
              {
                response: result.icestats,
                streamsAvailable: streams,
                multipleSources: multipleStreams,
                selectedStream: prevSelectedStream
              },
              () => {
                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;
            this.checkStream(source);
            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}`
                })
              );
              this.debug(streams);
              this.setState({
                multipleSources: true,
                streamsAvailable: streams,
                ready: true
              });
              this.streamName = source[0].server_name;
            } else if (source !== undefined) {
              this.setState({
                multipleSources: false,
                selectedStream: 0,
                ready: true
              });
              this.streamName = source.server_name;
            }
          }
        )
      );
  }

  render() {
    const {
      ready,
      response,
      history,
      streamsAvailable,
      multipleSources,
      selectedStream
    } = this.state;
    const isOnline = response.source !== undefined;

    if (!ready) {
      return (
        <Container style={{ paddingTop: "50px" }}>
          <Segment
            textAlign="center"
            style={{ paddingTop: "25px", paddingBottom: "25px" }}
          >
            <Loader active inline>
              Obteniendo información del servidor de IceCast ...
            </Loader>
          </Segment>
        </Container>
      );
    }

    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}
                          value={selectedStream}
                          onChange={(e, d) =>
                            this.setState({ selectedStream: d.value }, () => {
                              this.streamName = this.state.response.source[
                                d.value
                              ].server_name;
                              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}>
                <Chat />
              </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;