reward distribution fixed
This commit is contained in:
parent
a230c97078
commit
4c75d08d4a
|
|
@ -30,6 +30,114 @@ interface Opponent {
|
|||
x_profile_url: string;
|
||||
}
|
||||
|
||||
const GameHistoryItem = ({ game, user, gameImages, defaultPFP, failedImages, setFailedImages, handleViewTxClick }: {
|
||||
game: GameHistory,
|
||||
user: any,
|
||||
gameImages: { [key: string]: string },
|
||||
defaultPFP: string,
|
||||
failedImages: Set<string>,
|
||||
setFailedImages: React.Dispatch<React.SetStateAction<Set<string>>>,
|
||||
handleViewTxClick: (address: string) => void
|
||||
}) => {
|
||||
const [opponent, setOpponent] = useState<any>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchOpponent = async () => {
|
||||
const opponentId = game.master_id == user.id ? game.client_id : game.master_id;
|
||||
try {
|
||||
const response = await axios.get(`${API_URL}get_user_by_id.php?id=${opponentId}`);
|
||||
setOpponent(response.data);
|
||||
} catch (err) {
|
||||
console.error("Failed to fetch opponent info:", err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
fetchOpponent();
|
||||
}, [game, user.id]);
|
||||
|
||||
const isUserMaster = game.master_id == user.id;
|
||||
const userScore = isUserMaster ? game.master_score : game.client_score;
|
||||
const opponentScore = isUserMaster ? game.client_score : game.master_score;
|
||||
let didUserWin = false;
|
||||
if(game.winner == "master"){
|
||||
didUserWin = game.master_id == user.id;
|
||||
} else if(game.winner == "client"){
|
||||
didUserWin = game.client_id == user.id;
|
||||
}
|
||||
console.log(`isUserMaster: ${isUserMaster}, game.winner: ${game.winner}, didUserWin: ${didUserWin}`);
|
||||
const wagerAmount = parseFloat(game.wager);
|
||||
const outcomeText = didUserWin
|
||||
? `+${(wagerAmount / 1e8) * 2 * WAGER_PRIZE_MULT} SOL`
|
||||
: `-${(wagerAmount / 1e8)} SOL`;
|
||||
|
||||
if (loading) return <div className="animate-pulse">Loading...</div>;
|
||||
|
||||
const profileUrl = opponent?.x_profile_url || (opponent?.username ? `${API_URL}profile_picture/${opponent.username}.jpg` : "/duelfiassets/default-avatar.png");
|
||||
const gameImageUrl = gameImages[game.game] || "/duelfiassets/default-game-thumbnail.png";
|
||||
|
||||
return (
|
||||
<div className="relative border border-[rgb(30,30,30)] rounded-xl p-3 flex gap-3 items-center group">
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-semibold text-white">
|
||||
{opponent?.username || "Unknown Opponent"}
|
||||
</p>
|
||||
<p className="text-xs text-gray-400">
|
||||
Score: {userScore} - {opponentScore}
|
||||
</p>
|
||||
<p className="text-xs text-gray-400">
|
||||
{new Date(game.ended_time).toLocaleString(undefined, {
|
||||
year: 'numeric',
|
||||
month: 'numeric',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric'
|
||||
})}
|
||||
</p>
|
||||
<p className={`text-sm font-semibold ${didUserWin ? "text-green-500" : "text-gray-500"}`}>
|
||||
{didUserWin ? "You won" : "You lost"}
|
||||
</p>
|
||||
<p className={`text-xs ${didUserWin ? "text-green-500" : "text-red-500"}`}>
|
||||
{outcomeText}
|
||||
</p>
|
||||
</div>
|
||||
<Image
|
||||
src={failedImages.has(profileUrl) ? defaultPFP : profileUrl}
|
||||
alt="Profile"
|
||||
width={40}
|
||||
height={40}
|
||||
className="w-10 h-10 rounded-full border border-gray-700 object-cover"
|
||||
onError={(e) => {
|
||||
// @ts-expect-error - Type mismatch expected
|
||||
e.target.src = defaultPFP;
|
||||
setFailedImages(prev => new Set(prev).add(profileUrl));
|
||||
}}
|
||||
/>
|
||||
<Image
|
||||
src={failedImages.has(gameImageUrl) ? "/duelfiassets/default-game-thumbnail.png" : gameImageUrl}
|
||||
alt="Game Thumbnail"
|
||||
width={64}
|
||||
height={64}
|
||||
className="w-16 h-16 rounded-md object-cover ml-4"
|
||||
onError={(e) => {
|
||||
// @ts-expect-error - Type mismatch expected
|
||||
e.target.src = "/duelfiassets/default-game-thumbnail.png";
|
||||
setFailedImages(prev => new Set(prev).add(gameImageUrl));
|
||||
}}
|
||||
/>
|
||||
<div className="absolute top-0 right-0 h-full w-28 bg-blue-500 text-white flex items-center justify-center opacity-0 group-hover:opacity-100 group-hover:translate-x-0 transition-all">
|
||||
<button
|
||||
onClick={() => handleViewTxClick(game.address)}
|
||||
className="px-4 py-2 text-sm font-semibold"
|
||||
>
|
||||
View TX
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default function PrivyButton() {
|
||||
const { login, logout, user, linkTwitter, unlinkTwitter } = usePrivy();
|
||||
const { fundWallet } = useFundWallet();
|
||||
|
|
@ -527,97 +635,18 @@ export default function PrivyButton() {
|
|||
<div className="space-y-4 max-h-96 overflow-y-auto">
|
||||
{gamesHistory
|
||||
.sort((a, b) => new Date(b.ended_time).getTime() - new Date(a.ended_time).getTime())
|
||||
.map((game, idx) => {
|
||||
const isUserMaster = game.master_id === user.id;
|
||||
const userScore = isUserMaster
|
||||
? game.master_score
|
||||
: game.client_score;
|
||||
const opponentScore = isUserMaster
|
||||
? game.client_score
|
||||
: game.master_score;
|
||||
const opponentId = isUserMaster
|
||||
? game.client_id
|
||||
: game.master_id;
|
||||
const didUserWin =
|
||||
(isUserMaster && game.winner === "master") ||
|
||||
(!isUserMaster && game.winner === "client");
|
||||
|
||||
const opponent = opponentInfo[opponentId];
|
||||
const profileUrl =
|
||||
opponent?.x_profile_url ||
|
||||
(opponent?.username
|
||||
? `${API_URL}profile_picture/${opponent.username}.jpg`
|
||||
: "/duelfiassets/default-avatar.png");
|
||||
|
||||
const gameImageUrl = gameImages[game.game] || "/duelfiassets/default-game-thumbnail.png";
|
||||
|
||||
const wagerAmount = parseFloat(game.wager);
|
||||
const outcomeText = didUserWin
|
||||
? `+${(wagerAmount / 1e8) * 2 * WAGER_PRIZE_MULT} SOL`
|
||||
: `-${(wagerAmount / 1e8)} SOL`;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={idx}
|
||||
className="relative border border-[rgb(30,30,30)] rounded-xl p-3 flex gap-3 items-center group"
|
||||
>
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-semibold text-white">
|
||||
{opponent?.username || "Unknown Opponent"}
|
||||
</p>
|
||||
<p className="text-xs text-gray-400">
|
||||
Score: {userScore} - {opponentScore}
|
||||
</p>
|
||||
<p className="text-xs text-gray-400">
|
||||
{new Date(game.ended_time).toLocaleString()}
|
||||
</p>
|
||||
<p
|
||||
className={`text-sm font-semibold ${
|
||||
didUserWin ? "text-green-500" : "text-gray-500"
|
||||
}`}
|
||||
>
|
||||
{didUserWin ? "You won" : "You lost"}
|
||||
</p>
|
||||
<p className={`text-xs ${didUserWin ? "text-green-500" : "text-red-500"}`}>
|
||||
{outcomeText}
|
||||
</p>
|
||||
</div>
|
||||
<Image
|
||||
src={failedImages.has(profileUrl) ? defaultPFP : profileUrl}
|
||||
alt="Profile"
|
||||
width={40}
|
||||
height={40}
|
||||
className="w-10 h-10 rounded-full border border-gray-700 object-cover"
|
||||
onError={(e) => {
|
||||
// @ts-expect-error - Type mismatch expected
|
||||
e.target.src = defaultPFP;
|
||||
setFailedImages(prev => new Set(prev).add(profileUrl));
|
||||
}}
|
||||
/>
|
||||
<Image
|
||||
src={failedImages.has(gameImageUrl) ? "/duelfiassets/default-game-thumbnail.png" : gameImageUrl}
|
||||
alt="Game Thumbnail"
|
||||
width={64}
|
||||
height={64}
|
||||
className="w-16 h-16 rounded-md object-cover ml-4"
|
||||
onError={(e) => {
|
||||
// @ts-expect-error - Type mismatch expected
|
||||
e.target.src = "/duelfiassets/default-game-thumbnail.png";
|
||||
setFailedImages(prev => new Set(prev).add(gameImageUrl));
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="absolute top-0 right-0 h-full w-28 bg-blue-500 text-white flex items-center justify-center opacity-0 group-hover:opacity-100 group-hover:translate-x-0 transition-all">
|
||||
<button
|
||||
onClick={() => handleViewTxClick(game.address)}
|
||||
className="px-4 py-2 text-sm font-semibold"
|
||||
>
|
||||
View TX
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
.map((game, idx) => (
|
||||
<GameHistoryItem
|
||||
key={idx}
|
||||
game={game}
|
||||
user={user}
|
||||
gameImages={gameImages}
|
||||
defaultPFP={defaultPFP}
|
||||
failedImages={failedImages}
|
||||
setFailedImages={setFailedImages}
|
||||
handleViewTxClick={handleViewTxClick}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user