-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c475b34
commit 1effb1d
Showing
13 changed files
with
425 additions
and
254 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { useSelector } from "@legendapp/state/react"; | ||
import chips from "@src/assets/images/chips/chips-3-stacks.png"; | ||
import Image from "next/image"; | ||
import { useEffect, useState } from "react"; | ||
import { selectPot$ } from "../state/selectors/gameSelectors"; | ||
|
||
export default function Pot() { | ||
const [started, setStarted] = useState(false); | ||
const pot = useSelector(selectPot$()); | ||
const raisedSeats = [2, 3, 6, 8]; | ||
|
||
useEffect(() => { | ||
setTimeout(() => { | ||
setStarted(true); | ||
}, 4000); | ||
}); | ||
|
||
return ( | ||
<> | ||
<div | ||
className={`text-white items-center bg-black/20 px-4 py-1 mt-2 absolute pot ${ | ||
started ? "animate-headShake " : "" | ||
}`} | ||
> | ||
${pot} | ||
</div> | ||
{raisedSeats.map((seat) => { | ||
return ( | ||
<Image | ||
key={seat} | ||
className={`absolute duration-700 ${ | ||
started ? "pot animate-fading opacity-0" : `seat-${seat} opacity-0` | ||
}`} | ||
width={32} | ||
height={32} | ||
alt="chips" | ||
src={chips} | ||
/> | ||
); | ||
})} | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import dealCardSound from "@src/assets/audio/effects/card-place.mp3"; | ||
import { useAudio } from "@src/hooks/useAudio"; | ||
import { CARDS_MAP } from "@src/lib/constants/cards"; | ||
import { useEffect, useMemo, useRef, useState } from "react"; | ||
import Card from "./Card"; | ||
export default function PrivateCards({ | ||
playersPrivateCards, | ||
}: { | ||
playersPrivateCards: Record<number /* seat number start from */, number[]>; | ||
}) { | ||
const [startRevealing, setStartRevealing] = useState(false); | ||
const [revealedCards, setRevealedCards] = useState(false); | ||
const [dealedCards, setDealedCards] = useState<number[]>([]); | ||
const dealCardEffect = useAudio(dealCardSound, "effect"); | ||
|
||
const mounted = useRef(false); | ||
|
||
const seats = useMemo(() => { | ||
return Object.keys(playersPrivateCards).map((seat) => Number(seat)); | ||
}, [playersPrivateCards]); | ||
|
||
useEffect(() => { | ||
if (mounted.current) return; | ||
|
||
mounted.current = true; | ||
|
||
seats.forEach((seat, index) => { | ||
setTimeout(() => { | ||
dealCardEffect.play(); | ||
setDealedCards((prev) => [...prev, seat]); | ||
}, index * 200); | ||
}); | ||
}, [seats, dealCardEffect]); | ||
|
||
return ( | ||
<> | ||
{seats.map((seat, i) => { | ||
return ( | ||
<div | ||
className={`flex grow-0 cards shrink-0 w-max duration-700 transition-all cards-${seat} ${ | ||
dealedCards.includes(seat) ? "" : "cards-center" | ||
} `} | ||
key={seat} | ||
> | ||
{revealedCards ? ( | ||
<> | ||
{playersPrivateCards[seat]?.map( | ||
(cardName, i) => | ||
CARDS_MAP[cardName] && ( | ||
<Card | ||
className={`w-16 h-24 animate-flip-y grow-0 shrink-0 ${ | ||
revealedCards ? "" : "" | ||
}`} | ||
key={cardName} | ||
cardName={CARDS_MAP[cardName]} | ||
/> | ||
), | ||
)} | ||
</> | ||
) : ( | ||
<div className="relative"> | ||
<div | ||
className={`w-14 h-20 rounded-lg animate-deal bg-[url("/images/card-back.png")] bg-no-repeat bg-contain justify-center grow-0 shrink-0 duration-[600ms] transition-all ${ | ||
revealedCards ? "" : "" | ||
}`} | ||
style={{ | ||
transform: startRevealing ? "rotateY(90deg)" : "", | ||
transformStyle: "preserve-3d", | ||
}} | ||
/> | ||
<div | ||
className={`w-14 h-20 rounded-lg animate-deal absolute bg-[url("/images/card-back.png")] bg-no-repeat bg-contain justify-center grow-0 shrink-0 duration-[600ms] left-0 top-0 transition-all ${ | ||
dealedCards.includes(seat) ? "!left-7" : "" | ||
}`} | ||
style={{ | ||
transform: startRevealing ? "rotateY(90deg)" : "", | ||
transformStyle: "preserve-3d", | ||
}} | ||
/> | ||
</div> | ||
// <UnrevealedCards startRevealing={startRevealing} /> | ||
)} | ||
</div> | ||
); | ||
})} | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { CARDS_MAP } from "@src/lib/constants/cards"; | ||
import Card from "./Card"; | ||
|
||
export default function PublicCards({ cards }: { cards: number[] }) { | ||
return ( | ||
<div className="flex"> | ||
{cards.map((cardIndex) => { | ||
const cardName = CARDS_MAP[cardIndex]; | ||
return ( | ||
cardName && ( | ||
<Card | ||
className="xl:w-24 2xl:w-28 animate-deal w-12 sm:w-16" | ||
key={cardName} | ||
cardName={cardName} | ||
/> | ||
) | ||
); | ||
})} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,76 +1,22 @@ | ||
"use client"; | ||
import TableBackground from "@src/assets/images/table.png"; | ||
import Image from "next/image"; | ||
import type { ReactNode } from "react"; | ||
|
||
import { useWallet } from "@aptos-labs/wallet-adapter-react"; | ||
import { GameEventTypes } from "@jeton/ts-sdk"; | ||
import FullPageLoading from "@jeton/ui/FullPageLoading"; | ||
import { useSelector } from "@legendapp/state/react"; | ||
import { useRouter } from "next/navigation"; | ||
import { type FC, useEffect, useState } from "react"; | ||
import { initGame, setTableId } from "../state/actions/gameActions"; | ||
import { | ||
selectGamePlayers$, | ||
selectGameStatus$, | ||
selectIsGameLoading$, | ||
selectShufflingPlayer$, | ||
} from "../state/selectors/gameSelectors"; | ||
import { useSubscribeToGameEvent } from "./useSubscribeToGameEvent"; | ||
|
||
type TableComponentProps = { | ||
id: string; | ||
}; | ||
|
||
export const TableComponent: FC<TableComponentProps> = ({ id }) => { | ||
const [toffState, setToffState] = useState(false); | ||
const players = useSelector(selectGamePlayers$()); | ||
const gameStatus = useSelector(selectGameStatus$()); | ||
const shufflingPlayer = useSelector(selectShufflingPlayer$()); | ||
const [{ percentage }] = useSubscribeToGameEvent(GameEventTypes.DOWNLOAD_PROGRESS) || [ | ||
{ percentage: undefined }, | ||
]; | ||
const router = useRouter(); | ||
const { | ||
connected, | ||
isLoading: isWalletLoading, | ||
signMessage, | ||
signAndSubmitTransaction, | ||
account, | ||
} = useWallet(); | ||
|
||
useEffect(() => { | ||
if (!isWalletLoading && !connected && toffState) { | ||
router.push("/"); | ||
} else if (!isWalletLoading && !connected) { | ||
setTimeout(() => setToffState(true), 100); | ||
} | ||
}, [isWalletLoading, connected, router, toffState]); | ||
|
||
useEffect(() => { | ||
if (!isWalletLoading && account) { | ||
initGame(account.address, signMessage, signAndSubmitTransaction); | ||
} | ||
setTableId(id); | ||
}, [id, signMessage, signAndSubmitTransaction, isWalletLoading, account]); | ||
export function Table({ children }: { children: ReactNode }) { | ||
return ( | ||
<div className="flex justify-center items-center w-full h-full animate-grow-in"> | ||
<div className="h-full-z-40 md:scale-x-100 max-w-[70dvh] md:scale-y-100 md:scale-100 w-full md:max-w-[90dvw] xl:max-w-[90dvw] md:max-h-[80dvh] duration-500 scale-x-150 scale-y-150 sm:scale-y-125 relative md:right-0 flex items-center justify-center"> | ||
<Image | ||
draggable={false} | ||
priority | ||
className="object-fill w-full h-full rotate-90 md:rotate-0 md:max-h-[80dvh]" | ||
src={TableBackground} | ||
alt="table" | ||
style={{ imageRendering: "pixelated" }} | ||
/> | ||
|
||
const isLoading = useSelector(selectIsGameLoading$()) || isWalletLoading; | ||
if (isLoading) | ||
return ( | ||
<div> | ||
{percentage && <p>downloading... {percentage}%</p>} | ||
<FullPageLoading /> | ||
{children} | ||
</div> | ||
); | ||
|
||
return ( | ||
<div> | ||
<p>game state is ${gameStatus}</p> | ||
<p>this is the actual game page</p> | ||
<p>players are: </p> | ||
{players?.map((p) => ( | ||
<div key={p.id}> | ||
<p> player id: {p.id}</p> | ||
{p === shufflingPlayer && <span style={{ color: "red" }}>shuffling</span>} | ||
</div> | ||
))} | ||
</div> | ||
); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export default function WaitingIndicator() { | ||
return ( | ||
<div className="text-white flex text-xl animate-fadeIn px-2 py-1"> | ||
Waiting for players <div className="animate-bounce">.</div> | ||
<div className="animate-bounce delay-300">.</div> | ||
<div className="animate-bounce delay-700">.</div> | ||
</div> | ||
); | ||
} |
Oops, something went wrong.