Ready.tsx 2.01 KB
import React, { useCallback, useContext, useEffect, useState } from 'react';
import { useLocation } from 'react-router';
import SocketContext from '../../contexts/SocketContext';
import { MessageType, RawMessage } from '../common/types';
import { User } from './types';

interface ReadyLocation {
  state: { username: string }
}

interface ReadyProps {
  users: User[];
}

export const Ready: React.FC<ReadyProps> = ({ users }) => {
  const socket = useContext(SocketContext);
  const location: ReadyLocation = useLocation();
  
  const [ isAdmin, setIsAdmin ] = useState(false);
  const [ isReady, setIsReady ] = useState(false);
  const [ isAllReady, setIsAllReady ] = useState(false);

  useEffect(() => {
    const me = users.find(x => x.username === location.state.username);
    setIsAdmin(me?.admin || false);
    setIsReady(me?.ready || false);

    var test = users.length > 1;
    users.forEach(x => test = test && (x.ready || x.admin));
    setIsAllReady(test);
  });

  const handleReady = useCallback(() => {
    if (isAdmin && isAllReady) {
      const rawMessage: RawMessage = {
        type: MessageType.ROOM_START,
        message: {}
      }
      socket.emit('msg', rawMessage, () => {});
    } else {
      const rawMessage: RawMessage = {
        type: MessageType.ROOM_READY,
        message: { ready: !isReady }
      }
      socket.emit('msg', rawMessage, () => {});
    }
  }, [isAdmin, isReady, isAllReady]);

  return (
    <button className={`${isAdmin ? isAllReady ? 'bg-green-500 active:bg-green-600' : 'bg-gray-400'
                            : isReady ? 'bg-green-600'
                            : 'bg-green-500 active:bg-green-600'} 
                            text-white font-bold uppercase
                            px-7 py-3 m-8 rounded shadow
                            outline-none focus:outline-none hover:shadow-md
                            ease-linear transition-all duration-100`}
                    type="button"
                    onClick={() => handleReady()}>{isAdmin ? 'Start' : 'Ready'}</button>
  );
}