import { CSSProperties, useEffect, useState } from 'react'; import './TVMode.css'; import './Client.css'; import { buttonTypeList, WGPPState } from './types'; const TVMode = () => { const [state, setState] = useState>({}); const [socket, setSocket] = useState(); const [endTime, setEndTime] = useState(0); const [secondsRemaining, setSecondsRemaining] =useState(0); useEffect(() => { setEndTime(Date.now() + (state?.timeUntilNextMode??15) * 1000); const interval = setInterval(() => { const remaining = Math.round((endTime - Date.now())/1000); setSecondsRemaining(remaining < 0 ? 0 : remaining); }, 500); return () => clearInterval(interval); }, [endTime, state?.timeUntilNextMode]); useEffect(() => { const url = new URL(`api/client`, window.location.href); url.protocol = url.protocol.replace("http", "ws"); const sock = new WebSocket(url.href); sock.onmessage = (e) => { const newState = JSON.parse(e.data) as Partial; // Merge old and new state setState(oldState => ({ ...oldState , ...newState })); } setSocket(sock); return () => { sock.close(); setSocket(undefined); }; }, []) const totalCount = buttonTypeList.reduce((acc, v) => (state?.votes?.[v]??0) + acc, 0); return
{state === undefined ? Loading... :
{state.mode}
next: {state.nextMode} {Math.round(state.timeUntilNextMode ?? 0)}s ⏱️
{buttonTypeList.map((b, index) =>
{b} {state?.votes?.[b] ? Math.round(state?.votes?.[b] ?? 0 / totalCount / 100) : ""}
)}
Current state:
            {JSON.stringify(state, null, 4)}
          
}
; } export default TVMode;