diff --git a/src/navbar/index.tsx b/src/navbar/index.tsx index 902a214..dcaa96b 100644 --- a/src/navbar/index.tsx +++ b/src/navbar/index.tsx @@ -1,5 +1,5 @@ import React, { useRef, useEffect, useState } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { shallowEqual, useDispatch, useSelector } from "react-redux"; import Clock from "react-live-clock"; import Stopwatch from "react-stopwatch"; @@ -161,31 +161,6 @@ export function NavBarMyRadio() { } export function NavBarMain() { - const dispatch = useDispatch(); - const broadcastState = useSelector((state: RootState) => state.broadcast); - const settings = useSelector((state: RootState) => state.settings); - const playerState = useSelector((state: RootState) => state.mixer.players); - - let playerPFLs: boolean[] = []; - playerState.forEach((player) => { - playerPFLs.push(player.pfl); - }); - const isPFL = useSelector((state) => playerPFLs).some((x) => x === true); - - const [connectButtonAnimating, setConnectButtonAnimating] = useState(false); - - const prevRegistrationStage = useRef(broadcastState.stage); - useEffect(() => { - if (broadcastState.stage !== prevRegistrationStage.current) { - setConnectButtonAnimating(false); - } - prevRegistrationStage.current = broadcastState.stage; - }, [broadcastState.stage]); - - const { planSaveError, planSaving } = useSelector( - (state: RootState) => state.showplan - ); - 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 dispatch = useDispatch(); + return ( + <> + {enableRecording && (
  • { - setConnectButtonAnimating(true); - switch (broadcastState.stage) { - case "NOT_REGISTERED": - dispatch(BroadcastState.goOnAir()); - break; - case "REGISTERED": - dispatch(BroadcastState.cancelTimeslot()); - break; - } - }} + className={ + "btn rounded-0 pt-2 pb-1 nav-item nav-link " + + (recordingState === "CONNECTED" + ? "btn-outline-danger active" + : "btn-outline-light") + } + onClick={() => + dispatch( + recordingState === "NOT_CONNECTED" + ? BroadcastState.startRecording() + : BroadcastState.stopRecording() + ) + } > - {connectButtonAnimating ? ( - <> - - - + {" "} + {recordingState === "CONNECTED" ? ( + { + return {formatted}; + }} + /> ) : ( - <> - - {broadcastState.stage === "NOT_REGISTERED" && "Register"} - {broadcastState.stage === "REGISTERED" && "Stop"} - + "Record" )}
  • - {settings.enableRecording && ( -
  • - dispatch( - broadcastState.recordingState === "NOT_CONNECTED" - ? BroadcastState.startRecording() - : BroadcastState.stopRecording() - ) - } - > - {" "} - {broadcastState.recordingState === "CONNECTED" ? ( - { - return {formatted}; - }} - /> - ) : ( - "Record" - )} -
  • - )} -
  • dispatch(OptionsMenuState.open())} - > - Options -
  • - {settings.proMode && isPFL && ( -
  • dispatch(setChannelPFL(-1, false))} - > - Clear PFL -
  • - )} + )} + + ); +} +function OptionsButton() { + const dispatch = useDispatch(); + return ( +
  • dispatch(OptionsMenuState.open())} + > + Options +
  • + ); +} -
  • +function MeterBridge() { + const dispatch = useDispatch(); + const proMode = useSelector((state: RootState) => state.settings.proMode); + const playerPFLs = useSelector( + (state: RootState) => state.mixer.players.map((x) => x.pfl), + shallowEqual + ); + const isPFL = useSelector((state) => playerPFLs).some((x) => x === true); + + return ( + <> + {proMode && isPFL && ( +
  • dispatch(setChannelPFL(-1, false))} + > + Clear PFL +
  • + )} + +
  • + {isPFL && ( -
  • - + )} + {!isPFL && ( + + )} + ); }