import React, { useEffect, useState } from 'react' import { API, graphqlOperation } from 'aws-amplify' import { Heading, Grid, View, useTheme, Button, Flex, TextField } from '@aws-amplify/ui-react'; import { useNavigate } from "react-router-dom"; import * as customStatements from '../graphql/custom-statements' import * as mutations from '../graphql/mutations' import * as graphqlSubscriptionStatements from '../graphql/subscriptions' import { CORE_OVERVIEW_ID, CARS, RACE_STATES } from '../utils/constants' import { getOrCreateUserId } from "../utils/localStorageFunctions" import { getPlayerByUUIDClaim, getClaim } from '../utils/helpers' import Modal from '../web-components/modal'; export default function RaceLobby() { const [race, setRace] = useState() const [playerClaimedByUser, setPlayerClaimed] = useState() const [modalVisible, setModalVisible] = useState(false) const [username, setUsername] = useState("") const [claimingPlayerId, setClaimingPlayerId] = useState() const uuid = getOrCreateUserId() const navigate = useNavigate(); var subscriptions = [] useEffect(() => { setUp(uuid) return () => { for (const subscription of subscriptions) { subscription.unsubscribe() } }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const setUp = async (uuid) => { const raceId = await fetchCurrentRace(uuid) console.log(raceId) if (raceId !== null) { subscriptions = await createSubscriptions(uuid, fetchCurrentRace, raceId) } console.log(subscriptions) } const controllerRedirect = (raceId, carId) => { navigate(`/race/${raceId}/car/${carId}/controller/`) } const fetchCurrentRace = async (uuid) => { try { const overviewData = await API.graphql(graphqlOperation(customStatements.customGetOverview, { id: CORE_OVERVIEW_ID })) const currentRace = overviewData.data.getOverview.currentRace const claimedPlayer = getPlayerByUUIDClaim(currentRace.players.items, uuid) if (claimedPlayer !== undefined) { setPlayerClaimed(claimedPlayer) setUsername(claimedPlayer.claims.items[0].username) } if (currentRace.currentRaceState !== RACE_STATES.LOBBY && claimedPlayer) { controllerRedirect(currentRace.id, claimedPlayer.car.id) } setRace(currentRace) return currentRace.id } catch (err) { console.error(err) return null } } const createSubscriptions = async (uuid, updateFunction, raceId) => { const updateClaimSubscription = await API.graphql(graphqlOperation(customStatements.customOnUpdatePlayerClaim)).subscribe({ next: ({ _, value }) => { console.log("Updated Claim: ", value); updateFunction(uuid) }, error: error => console.warn(error) }); const createClaimSubscription = await API.graphql(graphqlOperation(customStatements.customOnCreatePlayerClaim)).subscribe({ next: ({ _, value }) => { console.log("New Claim: ", value); updateFunction(uuid) }, error: error => console.warn(error) }); const updateRaceSubscription = await API.graphql({ query: graphqlSubscriptionStatements.onUpdateRaceById, variables: { id: raceId } }).subscribe({ next: ({ _, value }) => { console.log("Updated Race: ", value); updateFunction(uuid) }, error: error => console.warn(error) }); return [ updateClaimSubscription, createClaimSubscription, updateRaceSubscription ] } const { tokens } = useTheme(); const CarBoxContent = (claimedInfo, available) => { if (!available) { return Not available } const toClaimText = playerClaimedByUser ? "" : Click to claim const text = claimedInfo ? `☑️ Claimed by: ${claimedInfo.username} ${claimedInfo.uuid === uuid ? "(you)" : ""}` : toClaimText return ( {text} ) } const setPlayerName = async () => { const claimingNew = playerClaimedByUser?.id === undefined const playerItemId = claimingNew ? claimingPlayerId : playerClaimedByUser.id const mutation = claimingNew ? mutations.createPlayerClaim : mutations.updatePlayerClaim var inputObject = { id: playerItemId, uuid, username, playerClaimsId: playerItemId } await API.graphql(graphqlOperation(mutation, { input: inputObject })) setModalVisible(false) } const handleBoxClick = async (playerItem, claimable) => { if (playerClaimedByUser !== undefined) { if (playerClaimedByUser.id === playerItem.id) { setModalVisible(true) } } else if (claimable === true) { setClaimingPlayerId(playerItem.id) setModalVisible(true) } } if (race?.currentRaceState && race.currentRaceState !== RACE_STATES.LOBBY) { return ( <> Race currently in progress ... ) } return ( <> Join race {race && CARS.map(item => { const playerItem = race.players.items.find(player => player.car.id === String(item.value)) const claimedInfo = getClaim(playerItem) const available = item.claimable const claimed = claimedInfo !== null const claimable = available && !claimed const intensity = claimable ? 60 : 20 return ( handleBoxClick(playerItem, claimable)} > Car: {item.value} - {item.color} {CarBoxContent(claimedInfo, available)} ) }) } setModalVisible(false)} visible={modalVisible}> setUsername(event.target.value)} isRequired={true} maxLength={10} minLength={3} width={'100%'} /> ) }