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?
)}
-
+