From da99e69d20fd51bdda46fa1b2fd752a14985552b Mon Sep 17 00:00:00 2001 From: notV4l Date: Wed, 10 Apr 2024 23:09:55 +0200 Subject: [PATCH] ui fixes --- web/src/components/RegisterEntities.tsx | 2 +- web/src/components/layout/Loader.tsx | 4 +- web/src/components/layout/LoadingModal.tsx | 36 +++++++++++++ web/src/components/layout/MobileMenu.tsx | 42 ++++++++++++--- web/src/components/layout/QuitGameModal.tsx | 44 +++++++++++++++ web/src/components/layout/index.tsx | 2 + web/src/components/map/Map.tsx | 8 +-- web/src/components/pages/home/HallOfFame.tsx | 54 +++++++++++++------ web/src/components/pages/profile/Profile.tsx | 2 +- web/src/components/player/Inventory.tsx | 2 +- web/src/components/wallet/ConnectButton.tsx | 8 +-- web/src/components/wallet/DeployingModal.tsx | 52 ++++++++++++++++++ web/src/components/wallet/index.ts | 1 + web/src/dojo/class/Events.ts | 2 +- web/src/dojo/context/DojoContext.tsx | 20 +++++-- web/src/dojo/hooks/useFaucet.ts | 4 +- web/src/dojo/stores/ui.tsx | 14 +++++ .../[drugSlug]/[tradeDirection].tsx | 4 +- .../pages/[gameId]/[locationSlug]/index.tsx | 18 ++++--- web/src/pages/_app.tsx | 9 ++++ web/src/pages/create/new.tsx | 4 +- web/src/pages/index.tsx | 16 +++--- 22 files changed, 287 insertions(+), 61 deletions(-) create mode 100644 web/src/components/layout/LoadingModal.tsx create mode 100644 web/src/components/layout/QuitGameModal.tsx create mode 100644 web/src/components/wallet/DeployingModal.tsx diff --git a/web/src/components/RegisterEntities.tsx b/web/src/components/RegisterEntities.tsx index c91701311..7d2abee57 100644 --- a/web/src/components/RegisterEntities.tsx +++ b/web/src/components/RegisterEntities.tsx @@ -29,7 +29,7 @@ const RegisterEntities = observer(() => { useEffect(() => { - console.log("RegisterEntities", gameId); + // console.log("RegisterEntities", gameId); if (gameStore && gameId) { gameStore.init(gameId); diff --git a/web/src/components/layout/Loader.tsx b/web/src/components/layout/Loader.tsx index 2457860a4..5ca0385d8 100644 --- a/web/src/components/layout/Loader.tsx +++ b/web/src/components/layout/Loader.tsx @@ -1,10 +1,10 @@ import { Image, Text, VStack } from "@chakra-ui/react"; -export const Loader = () => { +export const Loader = ({ text = "LOADING ..."}: { text?: string}) => { return ( loading - LOADING ... + {text} ); }; diff --git a/web/src/components/layout/LoadingModal.tsx b/web/src/components/layout/LoadingModal.tsx new file mode 100644 index 000000000..85acc02b9 --- /dev/null +++ b/web/src/components/layout/LoadingModal.tsx @@ -0,0 +1,36 @@ +import { Modal, ModalBody, ModalContent, ModalOverlay, VStack } from "@chakra-ui/react"; +import { observer } from "mobx-react-lite"; +import { useState } from "react"; +import { Loader } from "./Loader"; + +export const LoadingModal = observer(() => { + const [isLoading, setIsLoading] = useState(false); + + // useLayoutEffect(() => { + // const onDOMContentLoaded = (event: any) => { + // if (event.target.readyState === "complete") { + // setIsLoading(false); + // } + // }; + + // window.addEventListener("load", (event) => { + // onDOMContentLoaded(event); + // }, false); + // return () => { + // window.removeEventListener("load", onDOMContentLoaded); + // }; + // }, []); + + return ( + {}}> + + + + + + + + + + ); +}); diff --git a/web/src/components/layout/MobileMenu.tsx b/web/src/components/layout/MobileMenu.tsx index db1981e2b..7c963b2c6 100644 --- a/web/src/components/layout/MobileMenu.tsx +++ b/web/src/components/layout/MobileMenu.tsx @@ -1,11 +1,17 @@ +import { useDojoContext, useRouterContext } from "@/dojo/hooks"; +import { Sounds, playSound } from "@/hooks/sound"; import { Menu, MenuItem, Popover, PopoverBody, PopoverContent, PopoverTrigger, StyleProps } from "@chakra-ui/react"; -import { Dots } from "../icons"; +import { Cigarette, Dots, Home } from "../icons"; import { ProfileLinkMobile } from "../pages/profile/Profile"; -import { ConnectButtonMobile } from "../wallet"; +import { ChainSelector, ConnectButtonMobile } from "../wallet"; +import { Burners } from "../wallet/Burners"; +import { Predeployed } from "../wallet/Predeployed"; import { HeaderButton } from "./HeaderButton"; import { MediaPlayer } from "./MediaPlayer"; export const MobileMenu = ({ ...props }: StyleProps) => { + const { gameId } = useRouterContext(); + const { uiStore } = useDojoContext(); return ( <> @@ -22,11 +28,35 @@ export const MobileMenu = ({ ...props }: StyleProps) => { - {/* - - + + + {" "} + {" "} - */} + + + {gameId && ( + <> + { + playSound(Sounds.Ooo); + //uiStore.openQuitGame(); + }} + > + IM LOST + + + { + uiStore.openQuitGame(); + }} + > + QUIT GAME + + + )} diff --git a/web/src/components/layout/QuitGameModal.tsx b/web/src/components/layout/QuitGameModal.tsx new file mode 100644 index 000000000..dff9fcf8a --- /dev/null +++ b/web/src/components/layout/QuitGameModal.tsx @@ -0,0 +1,44 @@ +import { useDojoContext } from "@/dojo/hooks"; +import { + Button, + HStack, + Modal, + ModalBody, + ModalContent, + ModalHeader, + ModalOverlay, + Text, + VStack, +} from "@chakra-ui/react"; +import { observer } from "mobx-react-lite"; +import { useRouter } from "next/router"; + +export const QuitGameModal = observer(() => { + const router = useRouter(); + const { uiStore } = useDojoContext(); + + return ( + {}}> + + + Quit game + + + Are you sure ? + + + + + + + + + ); +}); diff --git a/web/src/components/layout/index.tsx b/web/src/components/layout/index.tsx index 828c3e88f..c88fdaa10 100644 --- a/web/src/components/layout/index.tsx +++ b/web/src/components/layout/index.tsx @@ -3,8 +3,10 @@ export * from "./Footer" export * from "./Header" export * from "./HeaderButton" export * from "./Layout" +export * from "./LoadingModal" export * from "./MakeItRain" export * from "./MediaPlayer" export * from "./MobileMenu" export * from "./OG" +export * from "./QuitGameModal" diff --git a/web/src/components/map/Map.tsx b/web/src/components/map/Map.tsx index 207480889..111a4c181 100644 --- a/web/src/components/map/Map.tsx +++ b/web/src/components/map/Map.tsx @@ -31,7 +31,7 @@ export const coordinatePercent: CoordinateType = { [Locations.Brooklyn]: { x: 47, y: 72 }, }; -const yOffset = -150; +const yOffset = -180; export const Map = ({ targetId, @@ -53,9 +53,9 @@ export const Map = ({ const point = coordinate[targetId] ? coordinate[targetId] : { x: 0, y: 0 }; const animation = isMobile ? { - scale: 1.5, - x: point.x, - y: point.y + yOffset, + scale: 1.25, + x: point.x * 0.5, + y: point.y * 0.5 + yOffset, } : { scale: 1, x: 0, y: 0 }; animate( diff --git a/web/src/components/pages/home/HallOfFame.tsx b/web/src/components/pages/home/HallOfFame.tsx index 80b47b1ba..4efc1da3a 100644 --- a/web/src/components/pages/home/HallOfFame.tsx +++ b/web/src/components/pages/home/HallOfFame.tsx @@ -24,17 +24,28 @@ export const HallOfFame = observer(() => { return ( <> - {isFetchingHallOfFame && } - {!isFetchingHallOfFame && ( - - {hallOfFame - .filter((i) => i.version !== config?.ryo?.leaderboard_version) - .sort((a, b) => b.version - a.version) - .map((i, index) => { - return ; - })} - - )} + + {isFetchingHallOfFame && } + {!isFetchingHallOfFame && ( + + {hallOfFame + .filter((i) => i.version !== config?.ryo?.leaderboard_version) + .sort((a, b) => b.version - a.version) + .map((i, index) => { + return ; + })} + + )} + ); }); @@ -44,7 +55,7 @@ const HallOfFameEntry = ({ entry, account }: { entry: Leaderboard; account: Acco const { game, isFetched } = useGameById(entry.game_id); const isSelf = useMemo(() => { - if(!account) return false + if (!account) return false; return account?.address === game?.player_id; }, [account?.address, game?.player_id]); @@ -56,7 +67,7 @@ const HallOfFameEntry = ({ entry, account }: { entry: Leaderboard; account: Acco router.push(`/0x${entry.game_id.toString(16)}/logs`); }, [entry.game_id, game?.player_id, router]); - const color = isSelf ? colors.yellow["400"].toString() : colors.neon["400"].toString() + const color = isSelf ? colors.yellow["400"].toString() : colors.neon["400"].toString(); if (!isFetched) return null; return ( @@ -74,7 +85,9 @@ const HallOfFameEntry = ({ entry, account }: { entry: Leaderboard; account: Acco /> - {shortString.decodeShortString(game?.player_name)} {isSelf && ("(you)")} + + {shortString.decodeShortString(game?.player_name)} {isSelf && "(you)"} + {formatCash(entry.high_score)} @@ -82,10 +95,19 @@ const HallOfFameEntry = ({ entry, account }: { entry: Leaderboard; account: Acco {!game && No winner!} - + SEASON {entry.version} - {formatCash(entry.paper_balance).replace("$", "")} + + {formatCash(entry.paper_balance).replace("$", "")} diff --git a/web/src/components/pages/profile/Profile.tsx b/web/src/components/pages/profile/Profile.tsx index a71fb13c3..a7799d479 100644 --- a/web/src/components/pages/profile/Profile.tsx +++ b/web/src/components/pages/profile/Profile.tsx @@ -55,7 +55,7 @@ export const ProfileLinkMobile = () => { return ( <> - + {gameEvents.playerName} diff --git a/web/src/components/player/Inventory.tsx b/web/src/components/player/Inventory.tsx index cea69d8f5..023550297 100644 --- a/web/src/components/player/Inventory.tsx +++ b/web/src/components/player/Inventory.tsx @@ -71,7 +71,7 @@ export const Inventory = observer(({ hidePawnshop = false, ...props }: StyleProp {game.drugs.drug ? game?.drugs.quantity * configStore.getDrug(game.drugs.drug?.drug)!.weight : 0}/ - {game.items.transport!.tier.stat} LB + {game.items.transport!.tier.stat} diff --git a/web/src/components/wallet/ConnectButton.tsx b/web/src/components/wallet/ConnectButton.tsx index 9e3462c13..3d7d05e68 100644 --- a/web/src/components/wallet/ConnectButton.tsx +++ b/web/src/components/wallet/ConnectButton.tsx @@ -67,13 +67,13 @@ export const ConnectButtonMobile = ({ ...props }) => { )} {account && ( uiStore.openAccountDetails()}> - + {connector && {connector.name}} {frenlyAddress(account.address || "")} - Ξ - {formatEther(balance)} - + Ξ + {formatEther(balance)} + )} diff --git a/web/src/components/wallet/DeployingModal.tsx b/web/src/components/wallet/DeployingModal.tsx new file mode 100644 index 000000000..3d3785e7d --- /dev/null +++ b/web/src/components/wallet/DeployingModal.tsx @@ -0,0 +1,52 @@ +import { useDojoContext } from "@/dojo/hooks"; +import { Modal, ModalBody, ModalContent, ModalOverlay, VStack } from "@chakra-ui/react"; +import { observer } from "mobx-react-lite"; +import { useEffect, useState } from "react"; +import { Loader } from "../layout/Loader"; + +export const DeployingModal = observer(() => { + const { burnerManager, isPrefundingPaper } = useDojoContext(); + + const [text, setText] = useState("Loading ..."); + + // const isDeploying = useMemo(() => { + // return burnerManager?.isDeploying + // }, [burnerManager, burnerManager?.isDeploying]); + + // useEffect(() => { + // setIsDeploying(burnerManager?.isDeploying); + // }, [burnerManager?.isDeploying]); + + const [isDeploying, setIsDeploying] = useState(false); + useEffect(() => { + const handle = setInterval(() => { + setIsDeploying(burnerManager?.isDeploying || false); + }, 500); + return () => { + clearInterval(handle); + }; + }, []); + + useEffect(() => { + if (isDeploying) { + setText("Deploying burner..."); + } + + if (isPrefundingPaper) { + setText("Paper Airdrop burner..."); + } + }, [isDeploying, isPrefundingPaper]); + + return ( + {}}> + + + + + + + + + + ); +}); diff --git a/web/src/components/wallet/index.ts b/web/src/components/wallet/index.ts index 11bb5ecb1..d42069e55 100644 --- a/web/src/components/wallet/index.ts +++ b/web/src/components/wallet/index.ts @@ -4,6 +4,7 @@ export * from "./ChainSelector" export * from "./ChildrenOrConnect" export * from "./ConnectButton" export * from "./ConnectModal" +export * from "./DeployingModal" export * from "./PaperFaucet" export * from "./StarknetProvider" export * from "./TokenBalance" diff --git a/web/src/dojo/class/Events.ts b/web/src/dojo/class/Events.ts index 34381c87f..618143778 100644 --- a/web/src/dojo/class/Events.ts +++ b/web/src/dojo/class/Events.ts @@ -35,7 +35,7 @@ export class EventClass { lastEncounterResult: computed, }) - console.log("Events", this) + // console.log("Events", this) } public static parseWorldEvent(event: World__Event): DojoEvent { diff --git a/web/src/dojo/context/DojoContext.tsx b/web/src/dojo/context/DojoContext.tsx index dde3cab4a..71fc29697 100644 --- a/web/src/dojo/context/DojoContext.tsx +++ b/web/src/dojo/context/DojoContext.tsx @@ -26,6 +26,7 @@ interface DojoContextType { clients: DojoClientsResult; masterAccount?: AccountInterface; burnerManager?: BurnerManager; + isPrefundingPaper: boolean; predeployedManager?: PredeployedManager; configStore: ConfigStoreClass; gameStore: GameStoreClass; @@ -49,6 +50,8 @@ export const DojoContextProvider = observer( error: undefined, }); + const [isPrefundingPaper, setIsPrefundingPaper] = useState(false); + const defaultChain = process.env.NODE_ENV === "production" ? dojoContextConfig.KATANA_SLOT_420 : dojoContextConfig.KATANA; @@ -78,14 +81,20 @@ export const DojoContextProvider = observer( masterAccount: masterAccount!, accountClassHash: selectedChain.accountClassHash!, rpcProvider: rpcProvider, - feeTokenAddress: selectedChain.chainConfig.nativeCurrency.address + feeTokenAddress: selectedChain.chainConfig.nativeCurrency.address, }); const afterDeploy = async ({ account, deployTx }: { account: Account; deployTx: string }) => { - const receipt = await account!.waitForTransaction(deployTx, { - retryInterval: 200, - }); - await paperFaucet({ account, paperAddress: configStore.config?.ryoAddress.paper }); + setIsPrefundingPaper(true); + try { + const receipt = await account!.waitForTransaction(deployTx, { + retryInterval: 500, + }); + await paperFaucet({ account, paperAddress: configStore.config?.ryoAddress.paper }); + } catch (e: any) { + console.log("fail afterDeploy"); + } + setIsPrefundingPaper(false); }; manager.setAfterDeployingCallback(afterDeploy); @@ -188,6 +197,7 @@ export const DojoContextProvider = observer( rpcProvider, }, burnerManager, + isPrefundingPaper, predeployedManager, masterAccount, configStore, diff --git a/web/src/dojo/hooks/useFaucet.ts b/web/src/dojo/hooks/useFaucet.ts index 926994d6e..f2c3c2e48 100644 --- a/web/src/dojo/hooks/useFaucet.ts +++ b/web/src/dojo/hooks/useFaucet.ts @@ -49,7 +49,7 @@ export const useFaucet = (tokenAddress?: string): FaucetInterface => { }) receipt = await account!.waitForTransaction(tx.transaction_hash, { - retryInterval: 200, + retryInterval: 500, }); } catch (e: any) { @@ -93,7 +93,7 @@ export const paperFaucet = async ({ account, paperAddress }: { account: Account, const tx = await contract.invoke("faucet", [], { parseRequest: false }) const receipt = await account!.waitForTransaction(tx.transaction_hash, { - retryInterval: 200, + retryInterval: 500, }); } \ No newline at end of file diff --git a/web/src/dojo/stores/ui.tsx b/web/src/dojo/stores/ui.tsx index 86ef6a5f5..94a1428b8 100644 --- a/web/src/dojo/stores/ui.tsx +++ b/web/src/dojo/stores/ui.tsx @@ -4,6 +4,7 @@ type Modals = { seasonDetails?: any; connect?: any; accountDetails?: any; + quitGame?: any; }; export class UiStore { @@ -11,6 +12,7 @@ export class UiStore { seasonDetails: undefined, connect: undefined, accountDetails: undefined, + quitGame: undefined, }; constructor() { @@ -25,6 +27,9 @@ export class UiStore { // openAccountDetails: action, closeAccountDetails: action, + // + openQuitGame: action, + closeQuitGame: action, }); } @@ -54,4 +59,13 @@ export class UiStore { closeAccountDetails() { this.modals.accountDetails = undefined; } + + // + + openQuitGame() { + this.modals.quitGame = {}; + } + closeQuitGame() { + this.modals.quitGame = undefined; + } } diff --git a/web/src/pages/[gameId]/[locationSlug]/[drugSlug]/[tradeDirection].tsx b/web/src/pages/[gameId]/[locationSlug]/[drugSlug]/[tradeDirection].tsx index 3dd04795c..5105f6d97 100644 --- a/web/src/pages/[gameId]/[locationSlug]/[drugSlug]/[tradeDirection].tsx +++ b/web/src/pages/[gameId]/[locationSlug]/[drugSlug]/[tradeDirection].tsx @@ -105,8 +105,8 @@ const Market = observer(() => { } > - - {drug.name} + + {drug.name} {market.weight} lb diff --git a/web/src/pages/[gameId]/[locationSlug]/index.tsx b/web/src/pages/[gameId]/[locationSlug]/index.tsx index 275925065..4e684d4f2 100644 --- a/web/src/pages/[gameId]/[locationSlug]/index.tsx +++ b/web/src/pages/[gameId]/[locationSlug]/index.tsx @@ -98,7 +98,7 @@ const Location = observer(() => { } > - + @@ -110,10 +110,13 @@ const Location = observer(() => { const freeSpace = game.items.transport.tier.stat - game.drugs.quantity * (game.drugs?.drug?.weight || 0); const hasFreeSpace = freeSpace >= drug.weight; + const hasMinCash = game.player.cash >= drug.price; const canBuy = hasFreeSpace && + hasMinCash && (game.drugs.quantity === 0 || !game.drugs?.drug || game.drugs?.drug?.drug === drug!.drug); + const canSell = (game.drugs.quantity > 0 && game.drugs?.drug && game.drugs?.drug?.drug === drug!.drug) || false; @@ -171,7 +174,7 @@ const BuySellBtns = observer( ({ canBuy, canSell, drugConfig }: { canBuy: boolean; canSell: boolean; drugConfig: DrugConfigFull }) => { const { router } = useRouterContext(); return ( - + @@ -199,22 +202,25 @@ const BuySellMobileToggle = observer( return ( <> - - + ); }, diff --git a/web/src/pages/_app.tsx b/web/src/pages/_app.tsx index 82ee4559c..4f7dc2893 100644 --- a/web/src/pages/_app.tsx +++ b/web/src/pages/_app.tsx @@ -1,5 +1,6 @@ import { MakeItRain } from "@/components/layout"; import { AccountDetailsModal, ConnectModal } from "@/components/wallet"; +import { DeployingModal } from "@/components/wallet/DeployingModal"; import { DojoContextProvider } from "@/dojo/context/DojoContext"; import { dojoContextConfig } from "@/dojo/setup/config"; import useKonamiCode, { starkpimpSequence } from "@/hooks/useKonamiCode"; @@ -13,6 +14,11 @@ import { useEffect } from "react"; import theme from "../theme"; +// should avoid mobx memory leaks / GC issue.. +import { LoadingModal } from "@/components/layout/LoadingModal"; +import { QuitGameModal } from "@/components/layout/QuitGameModal"; +import { enableStaticRendering } from "mobx-react-lite"; +enableStaticRendering(typeof window === "undefined"); export default function App({ Component, pageProps }: AppProps) { @@ -47,8 +53,11 @@ export default function App({ Component, pageProps }: AppProps) { {/* */} {/* Common modales */} + + + diff --git a/web/src/pages/create/new.tsx b/web/src/pages/create/new.tsx index 96700acff..15a0f1472 100644 --- a/web/src/pages/create/new.tsx +++ b/web/src/pages/create/new.tsx @@ -98,7 +98,7 @@ const New = observer(() => { } > - + Choose your @@ -218,7 +218,7 @@ const New = observer(() => { /> - {config?.ryo.paper_fee > 0 && ( + {!isMobile && config?.ryo.paper_fee > 0 && ( diff --git a/web/src/pages/index.tsx b/web/src/pages/index.tsx index f9d24910f..e3a1d0f3d 100644 --- a/web/src/pages/index.tsx +++ b/web/src/pages/index.tsx @@ -11,11 +11,10 @@ import { Card, Divider, HStack, Tab, TabList, TabPanel, TabPanels, Tabs, Text, V import { useAccount } from "@starknet-react/core"; import { useEffect, useState } from "react"; - export default function Home() { const { router } = useRouterContext(); const { account } = useAccount(); - const { uiStore } = useDojoContext(); + const { uiStore, burnerManager } = useDojoContext(); const { toast } = useToast(); const [isGated, setIsGated] = useState(false); @@ -31,9 +30,9 @@ export default function Home() { const [isTutorialOpen, setIsTutorialOpen] = useState(false); const onHustle = async () => { - if(!account){ - uiStore.openConnectModal() - return + if (!account) { + uiStore.openConnectModal(); + return; } if (!disableAutoPlay) { @@ -44,9 +43,10 @@ export default function Home() { }; return ( -