From d112e58eb65bd2f8c09466be7ebf747f9a2a5563 Mon Sep 17 00:00:00 2001 From: eviterin Date: Sat, 2 Mar 2024 18:09:00 +0100 Subject: [PATCH] Readded code that was lost due to poor rebasing. Applied formatting fixes and ran eslint. --- packages/contracts/src/Game.sol | 2 +- packages/contracts/src/Inventory.sol | 18 +- packages/contracts/src/test/Integration.t.sol | 4 +- packages/contracts/src/test/Inventory.t.sol | 2 +- packages/webapp/src/actions/getDeck.ts | 316 +++++++++--------- packages/webapp/src/actions/setDeck.ts | 182 +++++----- .../src/components/collection/deckList.tsx | 135 ++++---- .../src/components/collection/deckPanel.tsx | 13 +- packages/webapp/src/pages/collection.tsx | 284 ++++++++-------- 9 files changed, 480 insertions(+), 476 deletions(-) diff --git a/packages/contracts/src/Game.sol b/packages/contracts/src/Game.sol index e057950d..01d991dc 100644 --- a/packages/contracts/src/Game.sol +++ b/packages/contracts/src/Game.sol @@ -549,7 +549,7 @@ contract Game { uint256[] storage cards = gdata.cards; pdata.deckStart = uint8(cards.length); inventory.checkDeck(msg.sender, deckID); - uint256[] memory deck = inventory.getDeck(msg.sender, deckID); + uint256[] memory deck = inventory.getDeckCards(msg.sender, deckID); for (uint256 i = 0; i < deck.length; i++) { cards.push(deck[i]); diff --git a/packages/contracts/src/Inventory.sol b/packages/contracts/src/Inventory.sol index d92fcc49..379bc239 100644 --- a/packages/contracts/src/Inventory.sol +++ b/packages/contracts/src/Inventory.sol @@ -331,7 +331,7 @@ contract Inventory is Ownable { // --------------------------------------------------------------------------------------------- // Returns the list of cards in the given deck of the given player. - function getDeck(address player, uint8 deckID) + function getDeckCards(address player, uint8 deckID) external view exists(player, deckID) @@ -342,16 +342,18 @@ contract Inventory is Ownable { // --------------------------------------------------------------------------------------------- + // Returns the decks of a given player. + function getAllDecks(address player) external view returns (Deck[] memory) { + return decks[player]; + } + + // --------------------------------------------------------------------------------------------- + // Returns the list of cards in the given deck of the given player. - function getDeckReal(address player, uint8 deckID) - external - view - exists(player, deckID) - returns (Deck memory) - { + function getDeck(address player, uint8 deckID) external view exists(player, deckID) returns (Deck memory) { return decks[player][deckID]; } - + // --------------------------------------------------------------------------------------------- // Returns the decks of a given player. diff --git a/packages/contracts/src/test/Integration.t.sol b/packages/contracts/src/test/Integration.t.sol index a9faa00e..942e2415 100644 --- a/packages/contracts/src/test/Integration.t.sol +++ b/packages/contracts/src/test/Integration.t.sol @@ -71,8 +71,8 @@ contract Integration is Test { game.createGame(2); // IDs don't start at 1 because the deploy script currently airdrops some addresses, might change. - inventory.getDeck(player2, 0); // player1 has card id of 49-72 inclusive - inventory.getDeck(player2, 0); // player2 has card id of 73-96 inclusive + inventory.getDeckCards(player2, 0); // player1 has card id of 49-72 inclusive + inventory.getDeckCards(player2, 0); // player2 has card id of 73-96 inclusive vm.startPrank(player1); game.joinGame(gameID, DECK_ID, SALT_HASH, JOIN_DATA); diff --git a/packages/contracts/src/test/Inventory.t.sol b/packages/contracts/src/test/Inventory.t.sol index 4f69de8a..cee36d17 100644 --- a/packages/contracts/src/test/Inventory.t.sol +++ b/packages/contracts/src/test/Inventory.t.sol @@ -33,7 +33,7 @@ contract InventoryTest is Test { // expect revert if player's deck contains a card with more than `MAX_CARD_COPY` copies. function testCheckDeckExceedsMaxCopy() public { uint8 deckId = 0; - uint256 randomCard = inventory.getDeck(player1, deckId)[2]; + uint256 randomCard = inventory.getDeckCards(player1, deckId)[2]; // increase card `randomCard` copies to 4 vm.startPrank(player1); diff --git a/packages/webapp/src/actions/getDeck.ts b/packages/webapp/src/actions/getDeck.ts index 524f16b3..0162501f 100644 --- a/packages/webapp/src/actions/getDeck.ts +++ b/packages/webapp/src/actions/getDeck.ts @@ -1,158 +1,158 @@ -import { defaultErrorHandling } from "src/actions/errors" -import { contractWriteThrowing } from "src/actions/libContractWrite" -import { Address } from "src/chain" -import { deployment } from "src/deployment" -import { inventoryABI } from "src/generated" - -// ================================================================================================= - -export type GetDeckArgs = { - playerAddress: Address - onSuccess: () => void -} - -export type GetDeckAtArgs = { - playerAddress: Address - onSuccess: () => void - index: number -} - -// ------------------------------------------------------------------------------------------------- - -/** - * Fetches all decks of the given player by sending the `getAllDecks` transaction. - * - * Returns `true` iff the transaction is successful. - */ -export async function getAllDecks(args: GetDeckArgs): Promise { - try { - return await getAllDecksImpl(args) - } catch (err) { - defaultErrorHandling("getAllDecks", err) - return false - } -} - -/** - * Fetches the deck of the given player of a given ID by sending the `getDeckReal` transaction. - * - * Returns `true` iff the transaction is successful. - */ -export async function getDeck(args: GetDeckAtArgs): Promise { - try { - return await getDeckImpl(args) - } catch (err) { - defaultErrorHandling("getDeck", err) - return false - } -} - -// ------------------------------------------------------------------------------------------------- - -/** - * Fetches deck count of the given player by sending the `getNumDecks` transaction. - * - * Returns `true` iff the transaction is successful. - */ -export async function getNumDecks(args: GetDeckArgs): Promise { - try { - return await getNumDecksImpl(args) - } catch (err) { - defaultErrorHandling("getNumDecks", err) - return false - } -} - -// ------------------------------------------------------------------------------------------------- - -/** - * Fetches deck count of the given player by sending the `getNumDecks` transaction. - * - * Returns `true` iff the transaction is successful. - */ -export async function getDeckNames(args: GetDeckArgs): Promise { - try { - return await getDeckNamesImpl(args) - } catch (err) { - defaultErrorHandling("getDeckNames", err) - return false - } -} - -// ------------------------------------------------------------------------------------------------- - -async function getAllDecksImpl(args: GetDeckArgs): Promise { - try { - const result = await contractWriteThrowing({ - contract: deployment.Inventory, - abi: inventoryABI, - functionName: "getAllDecks", - args: [args.playerAddress], - }) - - args.onSuccess() - return result - } catch (error) { - console.error("Error fetching decks:", error) - return null - } - } - -// ------------------------------------------------------------------------------------------------- - -async function getDeckImpl(args: GetDeckAtArgs): Promise { - try { - const result = await contractWriteThrowing({ - contract: deployment.Inventory, - abi: inventoryABI, - functionName: "getDeckReal", - args: [args.playerAddress, args.index], - }) - - args.onSuccess() - return result - } catch (error) { - console.error("Error fetching deck:", error) - return null - } -} - -// ------------------------------------------------------------------------------------------------- - -async function getNumDecksImpl(args: GetDeckArgs): Promise { - try { - const result = await contractWriteThrowing({ - contract: deployment.Inventory, - abi: inventoryABI, - functionName: "getNumDecks", - args: [args.playerAddress], - }) - - args.onSuccess() - return result - } catch (error) { - console.error("Error fetching decks:", error) - return null - } -} - -// ------------------------------------------------------------------------------------------------- - -async function getDeckNamesImpl(args: GetDeckArgs): Promise { - try { - const result = await contractWriteThrowing({ - contract: deployment.Inventory, - abi: inventoryABI, - functionName: "getDeckNames", - args: [args.playerAddress], - }) - - args.onSuccess() - return result - } catch (error) { - console.error("Error fetching decks:", error) - return null - } -} - -// ================================================================================================= \ No newline at end of file +import { defaultErrorHandling } from "src/actions/errors" +import { contractWriteThrowing } from "src/actions/libContractWrite" +import { Address } from "src/chain" +import { deployment } from "src/deployment" +import { inventoryABI } from "src/generated" + +// ================================================================================================= + +export type GetDeckArgs = { + playerAddress: Address + onSuccess: () => void +} + +export type GetDeckAtArgs = { + playerAddress: Address + onSuccess: () => void + index: number +} + +// ------------------------------------------------------------------------------------------------- + +/** + * Fetches all decks of the given player by sending the `getAllDecks` transaction. + * + * Returns `true` iff the transaction is successful. + */ +export async function getAllDecks(args: GetDeckArgs): Promise { + try { + return await getAllDecksImpl(args) + } catch (err) { + defaultErrorHandling("getAllDecks", err) + return false + } +} + +/** + * Fetches the deck of the given player of a given ID by sending the `getDeckReal` transaction. + * + * Returns `true` iff the transaction is successful. + */ +export async function getDeck(args: GetDeckAtArgs): Promise { + try { + return await getDeckImpl(args) + } catch (err) { + defaultErrorHandling("getDeck", err) + return false + } +} + +// ------------------------------------------------------------------------------------------------- + +/** + * Fetches deck count of the given player by sending the `getNumDecks` transaction. + * + * Returns `true` iff the transaction is successful. + */ +export async function getNumDecks(args: GetDeckArgs): Promise { + try { + return await getNumDecksImpl(args) + } catch (err) { + defaultErrorHandling("getNumDecks", err) + return false + } +} + +// ------------------------------------------------------------------------------------------------- + +/** + * Fetches deck count of the given player by sending the `getNumDecks` transaction. + * + * Returns `true` iff the transaction is successful. + */ +export async function getDeckNames(args: GetDeckArgs): Promise { + try { + return await getDeckNamesImpl(args) + } catch (err) { + defaultErrorHandling("getDeckNames", err) + return false + } +} + +// ------------------------------------------------------------------------------------------------- + +async function getAllDecksImpl(args: GetDeckArgs): Promise { + try { + const result = await contractWriteThrowing({ + contract: deployment.Inventory, + abi: inventoryABI, + functionName: "getAllDecks", + args: [args.playerAddress], + }) + + args.onSuccess() + return result + } catch (error) { + console.error("Error fetching decks:", error) + return null + } +} + +// ------------------------------------------------------------------------------------------------- + +async function getDeckImpl(args: GetDeckAtArgs): Promise { + try { + const result = await contractWriteThrowing({ + contract: deployment.Inventory, + abi: inventoryABI, + functionName: "getDeckReal", + args: [args.playerAddress, args.index], + }) + + args.onSuccess() + return result + } catch (error) { + console.error("Error fetching deck:", error) + return null + } +} + +// ------------------------------------------------------------------------------------------------- + +async function getNumDecksImpl(args: GetDeckArgs): Promise { + try { + const result = await contractWriteThrowing({ + contract: deployment.Inventory, + abi: inventoryABI, + functionName: "getNumDecks", + args: [args.playerAddress], + }) + + args.onSuccess() + return result + } catch (error) { + console.error("Error fetching decks:", error) + return null + } +} + +// ------------------------------------------------------------------------------------------------- + +async function getDeckNamesImpl(args: GetDeckArgs): Promise { + try { + const result = await contractWriteThrowing({ + contract: deployment.Inventory, + abi: inventoryABI, + functionName: "getDeckNames", + args: [args.playerAddress], + }) + + args.onSuccess() + return result + } catch (error) { + console.error("Error fetching decks:", error) + return null + } +} + +// ================================================================================================= diff --git a/packages/webapp/src/actions/setDeck.ts b/packages/webapp/src/actions/setDeck.ts index 01f8ffdb..c114aeae 100644 --- a/packages/webapp/src/actions/setDeck.ts +++ b/packages/webapp/src/actions/setDeck.ts @@ -1,92 +1,90 @@ -import { defaultErrorHandling } from "src/actions/errors" -import { contractWriteThrowing } from "src/actions/libContractWrite" -import { Address } from "src/chain" -import { deployment } from "src/deployment" -import { inventoryABI } from "src/generated" -import { checkFresh, freshWrap } from "src/store/checkFresh" -import { Deck } from "src/store/types" - -// ================================================================================================= - -export type SaveArgs = { - deck: Deck - playerAddress: Address - onSuccess: () => void -} - -export type ModifyArgs = { - deck: Deck - playerAddress: Address - index: number - onSuccess: () => void -} - - -// ------------------------------------------------------------------------------------------------- - -/** - * Saves a deck created by the player by sending the `saveDeck` transaction. - * - * Returns `true` iff the transaction is successful. - */ -export async function save(args: SaveArgs): Promise { - try { - return await saveImpl(args) - } catch (err) { - return defaultErrorHandling("save", err) - } -} - -/** - * Modifies a deck owned by the player by sending the `modifyDeck` transaction. - * - * Returns `true` iff the transaction is successful. - */ -export async function modify(args: ModifyArgs): Promise { - try { - return await modifyImpl(args) - } catch (err) { - return defaultErrorHandling("modify", err) - } -} - -// ------------------------------------------------------------------------------------------------- - -async function saveImpl(args: SaveArgs): Promise { - const cardBigInts = args.deck.cards.map(card => card.id) - - checkFresh(await freshWrap( - contractWriteThrowing({ - contract: deployment.Inventory, - abi: inventoryABI, - functionName: "addDeck", - args: [ - args.playerAddress, - { name: args.deck.name, cards: cardBigInts } - ], - }))) - - args.onSuccess() - return true -} - -async function modifyImpl(args: ModifyArgs): Promise { - const cardBigInts = args.deck.cards.map(card => card.id) - console.log("INDEX: " + args.index) - checkFresh(await freshWrap( - contractWriteThrowing({ - contract: deployment.Inventory, - abi: inventoryABI, - functionName: "replaceDeck", - args: [ - args.playerAddress, - args.index, - { name: args.deck.name, cards: cardBigInts } - ], - }))) - - args.onSuccess() - return true -} - -// ================================================================================================= \ No newline at end of file +import { defaultErrorHandling } from "src/actions/errors" +import { contractWriteThrowing } from "src/actions/libContractWrite" +import { Address } from "src/chain" +import { deployment } from "src/deployment" +import { inventoryABI } from "src/generated" +import { checkFresh, freshWrap } from "src/store/checkFresh" +import { Deck } from "src/store/types" + +// ================================================================================================= + +export type SaveArgs = { + deck: Deck + playerAddress: Address + onSuccess: () => void +} + +export type ModifyArgs = { + deck: Deck + playerAddress: Address + index: number + onSuccess: () => void +} + +// ------------------------------------------------------------------------------------------------- + +/** + * Saves a deck created by the player by sending the `saveDeck` transaction. + * + * Returns `true` iff the transaction is successful. + */ +export async function save(args: SaveArgs): Promise { + try { + return await saveImpl(args) + } catch (err) { + return defaultErrorHandling("save", err) + } +} + +/** + * Modifies a deck owned by the player by sending the `modifyDeck` transaction. + * + * Returns `true` iff the transaction is successful. + */ +export async function modify(args: ModifyArgs): Promise { + try { + return await modifyImpl(args) + } catch (err) { + return defaultErrorHandling("modify", err) + } +} + +// ------------------------------------------------------------------------------------------------- + +async function saveImpl(args: SaveArgs): Promise { + const cardBigInts = args.deck.cards.map((card) => card.id) + + checkFresh( + await freshWrap( + contractWriteThrowing({ + contract: deployment.Inventory, + abi: inventoryABI, + functionName: "addDeck", + args: [args.playerAddress, { name: args.deck.name, cards: cardBigInts }], + }) + ) + ) + + args.onSuccess() + return true +} + +async function modifyImpl(args: ModifyArgs): Promise { + const cardBigInts = args.deck.cards.map((card) => card.id) + console.log("INDEX: " + args.index) + checkFresh( + await freshWrap( + contractWriteThrowing({ + contract: deployment.Inventory, + abi: inventoryABI, + functionName: "replaceDeck", + args: [args.playerAddress, args.index, { name: args.deck.name, cards: cardBigInts }], + }) + ) + ) + + args.onSuccess() + return true +} + +// ================================================================================================= diff --git a/packages/webapp/src/components/collection/deckList.tsx b/packages/webapp/src/components/collection/deckList.tsx index 24676a9e..770ecf34 100644 --- a/packages/webapp/src/components/collection/deckList.tsx +++ b/packages/webapp/src/components/collection/deckList.tsx @@ -1,86 +1,79 @@ -import React, { useEffect, useState, useCallback } from "react" +import React, { useCallback, useEffect, useState } from "react" + +import { getDeckNames } from "src/actions/getDeck" import Link from "src/components/link" -import { Deck } from 'src/store/types' import { Button } from "src/components/ui/button" -import { getAllDecks, getNumDecks, getDeckNames } from "src/actions/getDeck" import * as store from "src/store/hooks" -import { Deck } from "src/store/types" interface DeckCollectionDisplayProps { - decks: Deck[] - setDecks: React.Dispatch> - onDeckSelect: (deckID: number) => void + onDeckSelect: (deckID: number) => void } -const DeckCollectionDisplay: React.FC = ({ decks, setDecks, onDeckSelect }) => { - const playerAddress = store.usePlayerAddress() - const [ deckNames, setDeckNames] = useState([]) - const [ isLoadingDecks, setIsLoadingDecks ] = useState(false) - - function deckCount(): Promise { - return new Promise((resolve) => { - getNumDecks({ - playerAddress: playerAddress!, - onSuccess: () => { } - }) - }) - } - - const loadDeckNames = useCallback(() => { - if (playerAddress) { - setIsLoadingDecks(true) - getDeckNames({ - playerAddress: playerAddress, - onSuccess: () => { - }, - }).then(response => { - if(!response.simulatedResult) return - const receivedDecks = response.simulatedResult as string[] - setDeckNames(receivedDecks) - }).catch(error => { - console.error("Error fetching decks:", error) - }).finally(() => { - setIsLoadingDecks(false) - }) - } - }, [playerAddress]) +const DeckCollectionDisplay: React.FC = ({ onDeckSelect }) => { + const playerAddress = store.usePlayerAddress() + const [deckNames, setDeckNames] = useState([]) + const [isLoadingDecks, setIsLoadingDecks] = useState(false) + const loadDeckNames = useCallback(() => { + if (playerAddress) { + setIsLoadingDecks(true) + getDeckNames({ + playerAddress: playerAddress, + onSuccess: () => {}, + }) + .then((response) => { + if (!response.simulatedResult) return + const receivedDecks = response.simulatedResult as string[] + setDeckNames(receivedDecks) + }) + .catch((error) => { + console.error("Error fetching decks:", error) + }) + .finally(() => { + setIsLoadingDecks(false) + }) + } + }, [playerAddress]) - useEffect(() => { - loadDeckNames() - }, [loadDeckNames]) + useEffect(() => { + loadDeckNames() + }, [loadDeckNames]) - return ( -
- {/* New Deck Button */} - + return ( +
+ {/* New Deck Button */} + - {/* Loading Button */} - {isLoadingDecks && ( - - )} + {/* Loading Button */} + {isLoadingDecks && ( + + )} - {/* Deck Buttons */} - {deckNames.map((deckname, deckID) => ( - - ))} -
- ) + {/* Deck Buttons */} + {deckNames.map((deckname, deckID) => ( + + ))} +
+ ) } export default DeckCollectionDisplay diff --git a/packages/webapp/src/components/collection/deckPanel.tsx b/packages/webapp/src/components/collection/deckPanel.tsx index 5e162d07..9699d065 100644 --- a/packages/webapp/src/components/collection/deckPanel.tsx +++ b/packages/webapp/src/components/collection/deckPanel.tsx @@ -62,21 +62,22 @@ const DeckConstructionPanel: React.FC = ({ {/* Counter Row */}
-
-
+
+
-
- {selectedCards.length}/{MAX_CARDS} + {selectedCards.length}/{MAX_CARDS}
{/* Save and Cancel Buttons */}