100 lines
3.3 KiB
TypeScript
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 >
|
||
|
);
|
||
|
}
|