Skip to content

Commit

Permalink
Merge pull request #58 from JetonDAO/fix/avatars
Browse files Browse the repository at this point in the history
fix avatars
  • Loading branch information
arssly authored Oct 15, 2024
2 parents 1e7d93f + a1ec4c6 commit 22e48cd
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 36 deletions.
2 changes: 1 addition & 1 deletion apps/web/src/app/games/[id]/components/DownloadModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function DownloadModal() {
if (isLoading)
return (
<Modal closeButton={false} className="w-96 h-52 animate-grow-in">
<div className="flex text-nowrap text-sm flex-col items-center gap-1 text-white text-center">
<div className="flex text-sm flex-col items-center gap-1 text-white text-center">
{percentage ? (
<>
Downloading assets
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/games/[id]/components/PlayerActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export default function PlayerActions() {
actions.map((action) => (
<button
key={action}
className={`capitalize focus:outline-[#b87d5b] z-20 relative nes-btn is-warning disabled:hover:cursor-not-allowed w-full py-2 sm:py-4 text-[10px] sm:text-base text-white flex hover:brightness-90 ${
className={`capitalize text-center focus:outline-[#b87d5b] z-20 relative nes-btn is-warning disabled:hover:cursor-not-allowed w-full py-2 sm:py-4 text-[10px] sm:text-base text-white flex hover:brightness-90 ${
isActionQueued && queuedAction === action ? "cursor-pointer" : ""
}`}
onClick={() => handlePlayerAction(action)}
Expand Down
11 changes: 6 additions & 5 deletions apps/web/src/app/games/[id]/components/Pot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,19 @@ export default function Pot({ players }: { players: (UIPlayer | null)[] }) {
const [betting, setBetting] = useState(false);
const pot = useSelector(selectPot$());
const gameStatus = useSelector(selectGameStatus$());
const raisedSeats = mockPlayers.reduce<number[]>((acc, curr, i) => {
const raisedSeats = players.reduce<number[]>((acc, curr, i) => {
if (
curr.roundAction?.action === BettingActions.CALL ||
curr.roundAction?.action === BettingActions.RAISE
curr &&
(curr.roundAction?.action === BettingActions.CALL ||
curr.roundAction?.action === BettingActions.RAISE)
) {
acc.push(i + 1);
}
return acc;
}, []);

const winnerSeats = mockPlayers?.reduce<number[]>((acc, curr, i) => {
if (curr.winAmount && curr.winAmount > 0) {
const winnerSeats = players?.reduce<number[]>((acc, curr, i) => {
if (curr?.winAmount && curr.winAmount > 0) {
acc.push(i + 1);
}
return acc;
Expand Down
18 changes: 13 additions & 5 deletions apps/web/src/app/games/[id]/components/PrivateCards.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { GameStatus } from "@jeton/ts-sdk";
import { useSelector } from "@legendapp/state/react";
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 { mockPrivateCards } from "@src/lib/constants/mocks";
import React, { useEffect, useMemo, useRef, useState } from "react";
import { selectGameStatus$ } from "../state/selectors/gameSelectors";
import Card from "./Card";

export default function PrivateCards({
playersPrivateCards,
}: {
playersPrivateCards: Record<number /* seat number start from */, number[]> | null;
}) {
const [receivedCards, setReceivedCards] = useState(true);
const gameStatus = useSelector(selectGameStatus$());
const [receivedCards, setReceivedCards] = useState(false);
const [revealedCards, setRevealedCards] = useState(false);
const [dealCards, setDealCards] = useState<number[]>([]);
const dealCardEffect = useAudio(dealCardSound, "effect");
Expand Down Expand Up @@ -38,10 +42,14 @@ export default function PrivateCards({
}, [seats, dealCardEffect]);

useEffect(() => {
setTimeout(() => {
setRevealedCards(true);
}, 3000);
}, []);
if (gameStatus === GameStatus.ShowDown) {
setReceivedCards(true);

setTimeout(() => {
setRevealedCards(true);
}, 600);
}
});

return (
<>
Expand Down
47 changes: 27 additions & 20 deletions apps/web/src/app/games/[id]/components/Seat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import Avatar9 from "@src/assets/images/avatars/avatar-9.png";
import Avatar10 from "@src/assets/images/avatars/avatar-10.png";
import WinnerStuff from "@src/assets/images/champagne-pixel-animated.gif";
import Chip from "@src/assets/images/chips/chip.png";
import { mockPlayers } from "@src/lib/constants/mocks";
import Image from "next/image";
import Image, { type StaticImageData } from "next/image";
import { useEffect, useMemo, useRef, useState } from "react";
import {
selectAwaitingBetFrom$,
Expand All @@ -25,6 +24,7 @@ import {
import type { UIPlayer } from "../state/state";
import DealerBadge from "./DealerBadge";

// Define the avatars array as a constant
const avatars = [
Avatar1,
Avatar2,
Expand All @@ -38,18 +38,19 @@ const avatars = [
Avatar10,
];

function assignUniqueAvatars(players: (UIPlayer | null)[]): Record<string, string> {
// Function to assign unique avatars to players
function assignUniqueAvatars(players: (UIPlayer | null)[]): Record<string, StaticImageData> {
const availableAvatars = [...avatars];
const assignedAvatars: Record<string, string> = {};
const assignedAvatars: Record<string, StaticImageData> = {};

players.forEach((player) => {
if (!player) return;
if (!assignedAvatars[player.id]) {
const avatarIndex = hashPlayerIDToAvatar(player.id, availableAvatars.length);

const assignedAvatar = String(availableAvatars[avatarIndex]);
const assignedAvatar = availableAvatars[avatarIndex];

assignedAvatars[player.id] = assignedAvatar;
assignedAvatars[player.id] = assignedAvatar ?? Avatar1;

availableAvatars.splice(avatarIndex, 1);
}
Expand All @@ -58,6 +59,7 @@ function assignUniqueAvatars(players: (UIPlayer | null)[]): Record<string, strin
return assignedAvatars;
}

// Function to hash player IDs and assign avatar
function hashPlayerIDToAvatar(id: string, avatarCount: number): number {
let hash = 0;
for (let i = 0; i < id.length; i++) {
Expand All @@ -75,54 +77,58 @@ export default function Seat({
}) {
const mounted = useRef(false);

// Selectors from the state
const players = useSelector(selectGamePlayers$());
const shufflingPlayer = useSelector(selectShufflingPlayer$());
const awaitingBetFrom = useSelector(selectAwaitingBetFrom$());
const isPlayerTurn = awaitingBetFrom?.id === player.id;
const dealer = useSelector(selectDealer$());
const gameStatus = useSelector(selectGameStatus$());
const [lastAction, setLastAction] = useState("");

const [lastAction, setLastAction] = useState<string>("");
const isWinner = player.winAmount && player.winAmount > 0;

// Use `useMemo` to assign avatars
const assignedAvatars = useMemo(() => (players ? assignUniqueAvatars(players) : {}), [players]);

const playerAvatar = assignedAvatars[player.id];
const playerAvatar = assignedAvatars[player.id] ?? Avatar1;

const isMainPlayerCards = useMemo(() => {
return seatNumber === 1;
}, [seatNumber]);

useEffect(() => {
if (mounted.current) return;

mounted.current = true;
}, []);

// Reset last action based on game status
useEffect(() => {
console.log("status: ", gameStatus);

if (
gameStatus === GameStatus.DrawRiver ||
gameStatus === GameStatus.DrawFlop ||
gameStatus === GameStatus.DrawTurn
gameStatus === GameStatus.DrawTurn ||
isPlayerTurn
) {
setLastAction("");
}
}, [gameStatus]);
}, [gameStatus, isPlayerTurn]);

// Update last action for the player
useEffect(() => {
if (player.roundAction) {
const { action, amount } = player.roundAction;
setLastAction(`${action} ${amount}`);
}
});
}, [player.roundAction]);

return (
<div
className={`seat-position items-center flex z-30 shrink-0 md:w-28 xl:w-36 w-6 grow-0 duration-1000 ${
className={`seat-position items-center flex z-30 shrink-0 md:w-28 xl:w-36 w-6 grow-0 duration-1000 ${
shufflingPlayer?.id === player.id
? "seat-dealer scale-110"
: `seat-${seatNumber} ${2 > Math.random() ? "z-[501]" : ""} ${
player.status === PlayerStatus.sittingOut ? "opacity-80" : ""
}`
: `seat-${seatNumber} ${player.status === PlayerStatus.sittingOut ? "opacity-80" : ""}`
}`}
style={{ animationDelay: `${seatNumber * 100 + 100}ms` }}
>
Expand All @@ -133,7 +139,7 @@ export default function Seat({
>
<Image
draggable={false}
src={playerAvatar ?? ""}
src={playerAvatar} // playerAvatar is always a valid image
alt="avatar"
className={`aspect-square object-contain bg-black/70 h-full animate-grow-in grow-0 rounded-full shrink-0 border-2 md:border-8 ${
shufflingPlayer?.id === player.id ? "scale-125 animate-bounce delay-1000" : ""
Expand All @@ -147,7 +153,7 @@ export default function Seat({
}}
/>
<div className="bg-black/70 shrink-0 flex-col sm:border border-amber-300 rounded-sm line-clamp-1 relative flex justify-center text-[6px] text-white text-center shadow-2xl md:text-sm px-1 divide-y divide-white/50">
<span>{seatNumber === 1 ? "me" : player.id.slice(2, 8)} </span>
<span>{seatNumber === 1 ? "me" : player.id.slice(2, 8)}</span>
<span className="flex items-center justify-center">
<Image src={Chip} alt="chip" className="w-6 sm:block hidden" />
{player.balance}
Expand All @@ -160,7 +166,7 @@ export default function Seat({
className={`absolute top-0 -right-5 sm:-right-14 animate-grow-in ${
isWinner ? "animate-tada" : ""
}`}
alt="chicken winner"
alt="winner badge"
src={WinnerStuff}
/>
)}
Expand All @@ -183,6 +189,7 @@ export default function Seat({
</div>
</>
)}

{dealer?.id === player.id && <DealerBadge />}
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/games/[id]/components/ShufflingCards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const ShufflingCards = () => {
{angles.map((angle, index) => (
<div
key={angle}
className={`w-24 h-32 mx-2 rounded-lg bg-[url("/images/card-back.png")] bg-no-repeat bg-contain justify-center absolute animate-cardLoop`}
className={`md:w-16 md:h-24 2xl:w-24 2xl:h-32 mx-2 rounded-lg bg-[url("/images/card-back.png")] bg-no-repeat bg-contain justify-center absolute animate-cardLoop`}
style={{
transformOrigin: "20% 80%",
zIndex: positions[index]?.zIndex,
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
.chips,
.cards {
position: absolute;
will-change: transform;
}

@media (min-width: 768px) {
Expand Down
4 changes: 2 additions & 2 deletions apps/web/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ module.exports = {
"100%": { transform: "scale3d(1, 1, 1)" },
},
cardAnimation: {
"0%, 100%": { transform: "rotate(0deg)" },
"0%, 100%": { transform: "rotate(0deg) rotateY(0deg)" },
"30%": { transform: "rotate(360deg)" },
"50%": { transform: "rotateY(180deg)" },
"70%": { transform: "rotate(360deg)" },
"70%": { transform: "rotate(360deg) " },
},
deal: {
"0%": {
Expand Down
2 changes: 1 addition & 1 deletion packages/tailwindcss-config/base-tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ const config = {
"slide-in": "slideIn 1s ease-out",
"grow-in": "growIn 0.5s ease-out",
"flip-y": "flip 1s",
fading: "fading 2s infinite",
fading: "fading 1.5s",
headShake: "headShake 1s ease-in-out .5s",
},
},
Expand Down

0 comments on commit 22e48cd

Please sign in to comment.