Skip to content

Instantly share code, notes, and snippets.

@covelitein
Created August 17, 2023 16:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save covelitein/94d4ca91ae92c2bfe081fb9613da8941 to your computer and use it in GitHub Desktop.
Save covelitein/94d4ca91ae92c2bfe081fb9613da8941 to your computer and use it in GitHub Desktop.
p2e
import { EmojtCha } from 'emojtcha-react'
import { useState, useEffect } from 'react'
import ChatButton from './ChatButton'
import GameInfo from './GameInfo'
import { toast } from 'react-toastify'
import { payout, recordScore } from '../services/blockchain'
import { useNavigate } from 'react-router-dom'
import { setGlobalState } from '../store'
export default function Game({ game, isPlayed }) {
const numEmojtChas = game.challenges
const navigate = useNavigate()
const [validationStates, setValidationStates] = useState(
Array(numEmojtChas).fill(false)
)
const [revealedIndex, setRevealedIndex] = useState(0)
const [startTime, setStartTime] = useState(null)
const [endTime, setEndTime] = useState(null)
const [timerStarted, setTimerStarted] = useState(false)
const handleSelect = (index, isSelected) => {
const newValidationStates = [...validationStates]
newValidationStates[index] = isSelected
setValidationStates(newValidationStates)
if (isSelected && revealedIndex < numEmojtChas - 1) {
setRevealedIndex(revealedIndex + 1)
} else if (isSelected && revealedIndex === numEmojtChas - 1) {
setEndTime(new Date())
}
}
const resetGame = () => {
setValidationStates(Array(numEmojtChas).fill(false))
setRevealedIndex(0)
setStartTime(null)
setEndTime(null)
setTimerStarted(false)
}
const allCaptchasPassed = validationStates.every((state) => state)
useEffect(() => {
if (revealedIndex === 0 && timerStarted) {
setStartTime(new Date())
}
}, [revealedIndex, timerStarted])
const calculateElapsedTime = () => {
if (startTime && endTime) {
const elapsedMilliseconds = endTime - startTime
const elapsedSeconds = Math.floor(elapsedMilliseconds / 1000)
return elapsedSeconds
}
return 0
}
const submitScore = async () => {
await toast.promise(
new Promise(async (resolve, reject) => {
await recordScore(game.id, calculateElapsedTime())
.then((tx) => {
console.log(tx)
resolve(tx)
navigate('/mygames')
})
.catch((err) => {
reject(err)
})
}),
{
pending: 'Approve transaction...',
success: 'Score submittion successful 👌',
error: 'Encountered error 🤯',
}
)
}
const handlePayout = async () => {
await toast.promise(
new Promise(async (resolve, reject) => {
await payout(game.id)
.then((tx) => {
console.log(tx)
resolve(tx)
})
.catch((err) => {
reject(err)
})
}),
{
pending: 'Approve transaction...',
success: 'Paid out successful 👌',
error: 'Encountered error 🤯',
}
)
}
return (
<div className="min-h-screen flex flex-col justify-center items-center">
{timerStarted &&
validationStates.map((isValidationPassed, index) => (
<div
key={index}
className={`${
index === revealedIndex ? 'block' : 'hidden'
} p-4 border rounded shadow bg-white`}
>
<h1 className="text-xl font-semibold text-center mb-2">
Emoji {isValidationPassed ? 'passed' : 'not passed'}
</h1>
<div className="flex justify-center items-center h-32">
<EmojtCha
drawCount={6}
onSelect={(isSelected) => handleSelect(index, isSelected)}
/>
</div>
</div>
))}
{!timerStarted && (
<div className="flex flex-col justify-center items-center space-y-4 px-5">
<GameInfo game={game} />
<div className="flex justify-center items-center space-x-2">
{Date.now() > game.startDate &&
Date.now() < game.endDate &&
game.acceptees >= game.numberOfWinners + 1 &&
!isPlayed && (
<button
className="bg-blue-700 text-white py-2 px-4 rounded
hover:bg-blue-600 duration-200 transition-all shadow-md shadow-black"
onClick={() => setTimerStarted(true)}
>
Play
</button>
)}
{Date.now() > game.endDate && (
<>
<button
className="bg-green-700 text-white py-2 px-4 rounded
hover:bg-green-600 duration-200 transition-all shadow-md shadow-black"
onClick={() => setGlobalState('resultModal', 'scale-100')}
>
Result
</button>
{!game.paidOut && (
<button
className="bg-orange-700 text-white py-2 px-4 rounded
hover:bg-orange-600 duration-200 transition-all shadow-md shadow-black"
onClick={handlePayout}
>
Payout
</button>
)}
</>
)}
<ChatButton gid={game?.id} />
</div>
</div>
)}
{allCaptchasPassed && (
<div className="mt-4 p-4 border rounded shadow bg-white">
{/* <p className="text-lg text-center mb-2">
Time taken: {calculateElapsedTime()} seconds
</p> */}
<div className="flex justify-between items-center space-x-2">
<button
className="bg-green-500 text-white py-2 px-4 rounded
hover:bg-green-700 mt-2 w-full shadow-md shadow-black"
onClick={submitScore}
>
Submit
</button>
<button
className="bg-red-500 text-white py-2 px-4 rounded
hover:bg-red-700 mt-2 w-full shadow-md shadow-black"
onClick={resetGame}
>
Restart
</button>
</div>
</div>
)}
</div>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment