import React, { useRef, useEffect, useState } from "react"; import { shallowEqual, useDispatch, useSelector } from "react-redux"; import { FaCircle, FaRegClock, FaRegUser, FaBroadcastTower, FaSpinner, FaExclamationTriangle, FaCog, FaHeadphonesAlt, } from "react-icons/fa"; import { RootState } from "../rootReducer"; import * as BroadcastState from "../broadcast/state"; import appLogo from "../assets/images/webstudio.svg"; import myradioLogo from "../assets/images/myradio.svg"; import { MYRADIO_NON_API_BASE } from "../api"; import "./navbar.scss"; import { closeAlert } from "./state"; import { ConnectionStateEnum } from "../broadcast/streamer"; import { VUMeter } from "../optionsMenu/helpers/VUMeter"; import { getShowplan, setItemPlayed } from "../showplanner/state"; import * as OptionsMenuState from "../optionsMenu/state"; import { setChannelPFL } from "../mixer/state"; import { secToHHMM, useInterval } from "../lib/utils"; import { Timelord } from "./timelord"; function nicifyConnectionState(state: ConnectionStateEnum): string { switch (state) { case "CONNECTED": return "Connected!"; case "CONNECTING": return "Connecting to server..."; case "CONNECTION_LOST": return "Connection lost!"; case "CONNECTION_LOST_RECONNECTING": return "Connection lost. Reconnecting..."; case "NOT_CONNECTED": return "Not Connected"; case "LIVE": return "Live!"; default: console.warn("unhandled", state); return state as string; } } export function NavBarMyRadio() { const dispatch = useDispatch(); const sessionState = useSelector((state: RootState) => state.session); const redirect_url = encodeURIComponent(window.location.toString()); return ( <>
University Radio York Logo Web Studio Logo MyRadio Logo
); } export function NavBarMain() { return ( <> ); } function SavingAlert() { const { planSaveError, planSaving } = useSelector( (state: RootState) => state.showplan ); return ( <> {planSaving && (
  • Saving show plan...
  • )} {planSaveError && (
  • {planSaveError}
  • )} ); } function RegisterButton() { const dispatch = useDispatch(); const broadcastState = useSelector((state: RootState) => state.broadcast); const [connectButtonAnimating, setConnectButtonAnimating] = useState(false); const prevRegistrationStage = useRef(broadcastState.stage); useEffect(() => { if (broadcastState.stage !== prevRegistrationStage.current) { setConnectButtonAnimating(false); } prevRegistrationStage.current = broadcastState.stage; }, [broadcastState.stage]); return ( <>
  • {nicifyConnectionState(broadcastState.connectionState)}
  • { setConnectButtonAnimating(true); switch (broadcastState.stage) { case "NOT_REGISTERED": dispatch(BroadcastState.goOnAir()); break; case "REGISTERED": dispatch(BroadcastState.cancelTimeslot()); break; } }} > {connectButtonAnimating ? ( <> ) : ( <> {broadcastState.stage === "NOT_REGISTERED" && "Register"} {broadcastState.stage === "REGISTERED" && "Stop"} )}
  • ); } function RecordingButton() { const recordingState = useSelector( (state: RootState) => state.broadcast.recordingState ); const enableRecording = useSelector( (state: RootState) => state.settings.enableRecording ); const [count, setCount] = useState(0); // Make a persistant recording counter. useInterval(() => { if (recordingState !== "CONNECTED") { setCount(0); } else { setCount((c) => c + 1); } }, 1000); const dispatch = useDispatch(); return ( <> {enableRecording && (
  • dispatch( recordingState === "NOT_CONNECTED" ? BroadcastState.startRecording() : BroadcastState.stopRecording() ) } > {" "} {recordingState === "CONNECTED" ? secToHHMM(count) : "Record"}
  • )} ); } function OptionsButton() { const dispatch = useDispatch(); return (
  • dispatch(OptionsMenuState.open())} > Options
  • ); } function MeterBridge() { const dispatch = useDispatch(); const playerPFLs = useSelector( (state: RootState) => state.mixer.players.map((x) => x.pfl), shallowEqual ); const isPFL = useSelector((state) => playerPFLs).some((x) => x === true); return ( <> {isPFL && (
  • dispatch(setChannelPFL(-1, false))} > Clear PFL
  • )}
  • {isPFL && ( )} {!isPFL && ( )}
  • ); } function AlertBar() { const state = useSelector((state: RootState) => state.navbar.currentAlert); const timeoutRef = useRef(null); const dispatch = useDispatch(); useEffect(() => { if (timeoutRef.current !== null) { clearTimeout(timeoutRef.current); } if (typeof state?.closure === "number") { timeoutRef.current = setTimeout(() => { dispatch(closeAlert()); }, state.closure); } }, [dispatch, state]); return (
    {state?.content} {state?.closure !== null && ( )}
    ); } export function CombinedNavAlertBar() { return ( <>
    Hover for MyRadio Menu
    ); }