broadcast/ui/src/Radio.tsx

100 lines
3.3 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import useWebSocket from 'react-use-websocket';
import { RadioState, ConnectionState } from './types';
import {
requestToStart,
requestToStop,
} from './radioAPI';
import styles from './Radio.module.scss';
const getWSUrl = async () => {
const proto = (window.location.protocol === "http:") ? "ws" : "wss"
const wsUrl = process.env.WS_ADDR ?
process.env.WS_ADDR :
proto + "://" + window.location.host + window.location.pathname + "liveness";
console.log("WS ADDR: %s", wsUrl);
return wsUrl;
};
export function RadioToggler() {
const [loading, setLoading] = useState(false);
const [radioState, setRadioState] = useState<RadioState|undefined>(undefined);
const [connectionState, setConnectionState] = useState(ConnectionState.DISCONNECTED);
const { lastJsonMessage } = useWebSocket(getWSUrl,
{
onOpen: () => setConnectionState(ConnectionState.CONNECTED),
onClose: () => setConnectionState(ConnectionState.DISCONNECTED),
});
const onButtonClick = async () => {
if (radioState === RadioState.STARTED) {
setLoading(true);
const stopped = await requestToStop();
if (stopped) {
setRadioState(RadioState.STOPPED);
}
setLoading(false);
} else if (radioState === RadioState.STOPPED) {
setLoading(true);
const started = await requestToStart();
if (started) {
setRadioState(RadioState.STARTED);
}
setLoading(false);
}
};
const setRadioStateFromWS = (message: any) => {
switch (message.status) {
case "STARTED":
setRadioState(RadioState.STARTED);
break;
case "STOPPED":
setRadioState(RadioState.STOPPED);
break;
default:
setRadioState(undefined);
break;
}
};
useEffect(() => {
if (lastJsonMessage != null) {
if (!loading && lastJsonMessage.hasOwnProperty('status')) {
setRadioStateFromWS(lastJsonMessage);
}
}
}, [lastJsonMessage]);
let buttonStatus = "";
let circleStyle = styles.circleDisconnected;
if (loading) {
buttonStatus = "Attesa";
circleStyle = styles.circleLoading;
} else if (connectionState && connectionState !== ConnectionState.DISCONNECTED) {
switch (radioState) {
case RadioState.STARTED:
buttonStatus = "ON AIR";
circleStyle = styles.circleStarted;
break;
case RadioState.STOPPED:
buttonStatus = "SPENTA";
circleStyle = styles.circleStopped;
break;
}
}
return (
<div>
<div className={styles.buttonWrap} aria-label="toggle-radio-state">
<div
className={styles.clicker}
onClick={onButtonClick}
>{buttonStatus}</div>
<div className={circleStyle}></div>
</div>
</div >
);
}