import { CSSProperties, useEffect, useMemo, useState } from 'react'; import './TVMode.css'; import { ButtonType, buttonTypeList, WGPPState } from './types'; const TVMode = () => { const [state, setState] = useState>({}); const [socket, setSocket] = useState(); 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 = useMemo(() => buttonTypeList.reduce((acc, v) => (state?.votes?.[v] ?? 0) + acc, 0), [state]); const voteList = useMemo(() => buttonTypeList .map(b => [b, state?.votes?.[b] ?? 0] as [ButtonType, number]) //.sort((a, b) => b[1] - a[1]) , [state]); return
{state === undefined ? Loading... :
{state.mode}
next:  {state.nextMode}
{Math.round(state.timeUntilNextMode ?? 0)}s ⏱️
{voteList.flatMap(([b, numVotes], index) => { const percentage = numVotes === 0 ? 0 : Math.round(numVotes / totalCount * 100); return
{b}
{percentage === 0 ? "" : `${percentage}%`}
; })}
Current state:
            {JSON.stringify(state, null, 4)}
          
}
; } export default TVMode;