From 86dc24b0f6fcd2d768dd646e2355bfc12eeda845 Mon Sep 17 00:00:00 2001 From: ECWireless Date: Fri, 2 Aug 2024 15:09:20 -0600 Subject: [PATCH 1/4] Redirect leaderboard to home if not connected --- packages/client/src/pages/Leaderboard.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/client/src/pages/Leaderboard.tsx b/packages/client/src/pages/Leaderboard.tsx index a8a47d2b6..32cfce11d 100644 --- a/packages/client/src/pages/Leaderboard.tsx +++ b/packages/client/src/pages/Leaderboard.tsx @@ -25,11 +25,14 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import { FaSearch, FaSortAmountDown, FaSortAmountUp } from 'react-icons/fa'; import { FaBackwardStep, FaForwardStep } from 'react-icons/fa6'; import { IoCaretBack, IoCaretForward } from 'react-icons/io5'; +import { useNavigate } from 'react-router-dom'; import { formatEther, hexToString } from 'viem'; +import { useAccount } from 'wagmi'; import { LeaderboardRow } from '../components/LeaderboardRow'; import { useMUD } from '../contexts/MUDContext'; import { useToast } from '../hooks/useToast'; +import { HOME_PATH } from '../Routes'; import { fetchMetadataFromUri, uriToHttp } from '../utils/helpers'; import { Character, StatsClasses } from '../utils/types'; @@ -37,6 +40,8 @@ const PER_PAGE = 10; export const Leaderboard = (): JSX.Element => { const { renderError } = useToast(); + const navigate = useNavigate(); + const { isConnected } = useAccount(); const { components: { Characters, CharactersTokenURI, GoldBalances, Stats }, @@ -54,6 +59,13 @@ export const Leaderboard = (): JSX.Element => { const [page, setPage] = useState('1'); const [pageLimit, setPageLimit] = useState(0); + useEffect(() => { + if (!isConnected) { + navigate(HOME_PATH); + window.location.reload(); + } + }, [isConnected, navigate]); + const pageNumber = useMemo(() => { if (isNaN(Number(page))) { return 1; From 86e6ee663f7e859abd4f5824cf18f96b438f4c15 Mon Sep 17 00:00:00 2001 From: ECWireless Date: Fri, 2 Aug 2024 15:20:03 -0600 Subject: [PATCH 2/4] Change app loader text to progress bar --- packages/client/src/Routes.tsx | 10 ++++++---- packages/client/src/pages/Welcome.tsx | 8 +++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/client/src/Routes.tsx b/packages/client/src/Routes.tsx index 8ff5e6a4e..0ddd2dc59 100644 --- a/packages/client/src/Routes.tsx +++ b/packages/client/src/Routes.tsx @@ -1,4 +1,4 @@ -import { Text, VStack } from '@chakra-ui/react'; +import { Progress, Text, VStack } from '@chakra-ui/react'; import { useComponentValue } from '@latticexyz/react'; import { SyncStep } from '@latticexyz/store-sync'; import { singletonEntity } from '@latticexyz/store-sync/recs'; @@ -31,9 +31,11 @@ const AppRoutes: React.FC = () => { ) { return ( - - {syncProgress.message} {Math.round(syncProgress.percentage)}% - + Loading {Math.round(syncProgress.percentage)}% + ); } diff --git a/packages/client/src/pages/Welcome.tsx b/packages/client/src/pages/Welcome.tsx index 73a09bc10..7efda8aca 100644 --- a/packages/client/src/pages/Welcome.tsx +++ b/packages/client/src/pages/Welcome.tsx @@ -2,6 +2,7 @@ import { Button, Container, Heading, + Progress, Text, useDisclosure, VStack, @@ -74,9 +75,10 @@ export const Welcome = (): JSX.Element => { {syncProgress && syncProgress.step !== SyncStep.LIVE ? ( - - {syncProgress.message} {Math.round(syncProgress.percentage)}% - + + Loading {Math.round(syncProgress.percentage)}% + + ) : ( )} From e2eaa51864f52bf59553b7eff17c6fb027a043ec Mon Sep 17 00:00:00 2001 From: ECWireless Date: Sun, 4 Aug 2024 10:18:20 -0600 Subject: [PATCH 3/4] Render armor separately from weapons --- packages/client/src/components/ItemCard.tsx | 28 +- .../client/src/components/ItemEquipModal.tsx | 26 +- packages/client/src/pages/Character.tsx | 475 +++++++++++------- .../client/src/pages/CharacterCreation.tsx | 32 +- packages/client/src/pages/GameBoard.tsx | 8 +- packages/client/src/utils/constants.ts | 3 +- packages/client/src/utils/types.ts | 18 + packages/contracts/items.json | 14 +- packages/contracts/script/PostDeploy.s.sol | 63 +-- 9 files changed, 410 insertions(+), 257 deletions(-) diff --git a/packages/client/src/components/ItemCard.tsx b/packages/client/src/components/ItemCard.tsx index bc5fd7b78..b3c00fea2 100644 --- a/packages/client/src/components/ItemCard.tsx +++ b/packages/client/src/components/ItemCard.tsx @@ -6,11 +6,12 @@ import { Center, Text, } from '@chakra-ui/react'; -import { GiRogue } from 'react-icons/gi'; +import { FaHatWizard } from 'react-icons/fa'; +import { GiAxeSword, GiRogue } from 'react-icons/gi'; -import type { Weapon } from '../utils/types'; +import { type Armor, StatsClasses, type Weapon } from '../utils/types'; -type ItemCardProps = Weapon & { +type ItemCardProps = (Armor | Weapon) & { isEquipped?: boolean; onClick?: () => void; }; @@ -18,9 +19,10 @@ type ItemCardProps = Weapon & { export const ItemCard: React.FC = ({ isEquipped = false, onClick, - ...weapon + ...item }): JSX.Element => { - const { agiModifier, intModifier, strModifier, name } = weapon; + const { agiModifier, classRestrictions, intModifier, strModifier, name } = + item; return ( = ({ - STR+{strModifier} AGI+{agiModifier} INT+{intModifier} + STR+{strModifier} AGI+{agiModifier} INT+ + {intModifier}{' '} + {(item as Armor).armorModifier + ? `ARM+${(item as Armor).armorModifier}` + : ''}
- + {classRestrictions.includes(StatsClasses.Warrior) && ( + + )} + {classRestrictions.includes(StatsClasses.Rogue) && ( + + )} + {classRestrictions.includes(StatsClasses.Mage) && ( + + )}
diff --git a/packages/client/src/components/ItemEquipModal.tsx b/packages/client/src/components/ItemEquipModal.tsx index adae352a5..ddb9d3d69 100644 --- a/packages/client/src/components/ItemEquipModal.tsx +++ b/packages/client/src/components/ItemEquipModal.tsx @@ -14,10 +14,10 @@ import { useCallback, useMemo, useState } from 'react'; import { useCharacter } from '../contexts/CharacterContext'; import { useMUD } from '../contexts/MUDContext'; import { useToast } from '../hooks/useToast'; -import type { Weapon } from '../utils/types'; +import type { Armor, Weapon } from '../utils/types'; import { ItemCard } from './ItemCard'; -type ItemEquipModalProps = Weapon & { +type ItemEquipModalProps = (Armor | Weapon) & { isEquipped: boolean; isOpen: boolean; onClose: () => void; @@ -27,7 +27,7 @@ export const ItemEquipModal: React.FC = ({ isEquipped, isOpen, onClose, - ...weapon + ...item }): JSX.Element => { const { renderError, renderSuccess } = useToast(); const { @@ -39,8 +39,8 @@ export const ItemEquipModal: React.FC = ({ const [isEquipping, setIsEquipping] = useState(false); const isOwner = useMemo( - () => character?.owner === weapon.owner, - [character, weapon.owner], + () => character?.owner === item.owner, + [character, item.owner], ); const onEquipItem = useCallback(async () => { @@ -56,7 +56,7 @@ export const ItemEquipModal: React.FC = ({ } const { error, success } = await equipItems(character.characterId, [ - weapon.tokenId, + item.tokenId, ]); if (error && !success) { @@ -64,7 +64,7 @@ export const ItemEquipModal: React.FC = ({ } await refreshCharacter(); - renderSuccess(`${weapon.name} equipped successfully!`); + renderSuccess(`${item.name} equipped successfully!`); onClose(); } catch (e) { renderError((e as Error)?.message ?? 'Failed to equip item.', e); @@ -75,11 +75,11 @@ export const ItemEquipModal: React.FC = ({ character, delegatorAddress, equipItems, + item, onClose, refreshCharacter, renderError, renderSuccess, - weapon, ]); const onUnequipItem = useCallback(async () => { @@ -96,7 +96,7 @@ export const ItemEquipModal: React.FC = ({ const { error, success } = await unequipItem( character.characterId, - weapon.tokenId, + item.tokenId, ); if (error && !success) { @@ -104,7 +104,7 @@ export const ItemEquipModal: React.FC = ({ } await refreshCharacter(); - renderSuccess(`${weapon.name} unequipped successfully!`); + renderSuccess(`${item.name} unequipped successfully!`); onClose(); } catch (e) { renderError((e as Error)?.message ?? 'Failed to unequip item.', e); @@ -114,12 +114,12 @@ export const ItemEquipModal: React.FC = ({ }, [ character, delegatorAddress, + item, onClose, refreshCharacter, renderError, renderSuccess, unequipItem, - weapon, ]); if (isEquipped) { @@ -137,7 +137,7 @@ export const ItemEquipModal: React.FC = ({ ) : ( Do you want to make an offer for this item? )} - +