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;