diff --git a/client/dev-dist/sw.js b/client/dev-dist/sw.js index 6366b5a..2f717d3 100644 --- a/client/dev-dist/sw.js +++ b/client/dev-dist/sw.js @@ -82,7 +82,7 @@ define(['./workbox-20a2f87f'], (function (workbox) { 'use strict'; "revision": "3ca0b8505b4bec776b69afdba2768812" }, { "url": "index.html", - "revision": "0.uv6bn1a6tj" + "revision": "0.8j5p84f6nhg" }], {}); workbox.cleanupOutdatedCaches(); workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { diff --git a/client/src/components/SpawnBeast/index.tsx b/client/src/components/SpawnBeast/index.tsx index 2fd4166..70efbe9 100644 --- a/client/src/components/SpawnBeast/index.tsx +++ b/client/src/components/SpawnBeast/index.tsx @@ -1,8 +1,8 @@ // React and external libraries -import { useEffect, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { useNavigate, useSearchParams } from 'react-router-dom'; import { useAccount } from "@starknet-react/core"; -import { Account } from "starknet"; +import { Account, addAddressPadding } from "starknet"; import { useDojoSDK } from "@dojoengine/sdk/react"; // Internal components @@ -13,14 +13,13 @@ import ProgressBar from '../ProgressBar/index.tsx'; // Hooks and Contexts import { useSystemCalls } from "../../dojo/useSystemCalls.ts"; import { usePlayer } from "../../hooks/usePlayers.tsx"; -import { fetchBeastsData, processBeastData } from "../../hooks/useBeasts"; +import { useBeasts, fetchBeastsData } from "../../hooks/useBeasts"; // Types import type { SpawnBeastProps, SpawnBeastState } from '../../types/components'; -import type { Beast } from '../../types/game'; // Utils import { getRandomNumber } from './utils/helpers'; @@ -38,7 +37,14 @@ const SpawnBeast: React.FC = ({ className = '' }) => { const { spawn } = useSystemCalls(); const navigate = useNavigate(); const [searchParams] = useSearchParams(); - + + const userAddress = useMemo(() => + account ? addAddressPadding(account.address).toLowerCase() : '', + [account] + ); + + const { myBeastsData, refetch } = useBeasts(userAddress); + // State const [state, setState] = useState({ loading: false, @@ -73,8 +79,7 @@ const SpawnBeast: React.FC = ({ className = '' }) => { if (!player) { setSpawnProgress({ progress: 20, message: 'Creating player account' }); const spawnPlayerTx = await client.player.spawnPlayer(account as Account); - console.info('spawnPlayerTx', spawnPlayerTx); - + // Esperar un momento para que se actualice el player await new Promise(resolve => setTimeout(resolve, 2000)); setSpawnProgress({ progress: 40, message: 'Player account created!' }); @@ -83,23 +88,16 @@ const SpawnBeast: React.FC = ({ className = '' }) => { setSpawnProgress({ progress: 50, message: 'Generating your beast' }); const randomBeastId = getRandomNumber(MIN_BEAST_ID, MAX_BEAST_ID); const { spawnTx } = await spawn(randomBeastId); + await new Promise(resolve => setTimeout(resolve, 2000)); if (spawnTx && spawnTx.code === "SUCCESS") { + refetch(); + const beastsData = await fetchBeastsData(); + console.log('beastsData', beastsData); setSpawnProgress({ progress: 70, message: 'Beast generated! Setting as current' }); - let newBeast; - do { - // Recargar la lista de beasts usando GraphQL - const beastsData = await fetchBeastsData(); - const processedBeasts = await processBeastData(beastsData); - - // Encontrar la bestia reciƩn creada - newBeast = processedBeasts.find((beast: Beast) => beast.player === account!.address); - console.log(newBeast, 'newBeast'); - await new Promise(resolve => setTimeout(resolve, 2000)); - } while (!newBeast); - + const newBeast = myBeastsData[0]; if (newBeast) { - console.log(newBeast, 'newBeast inside'); + setSpawnProgress({ progress: 90, message: 'Finalizing setup' }); setSpawnProgress({ progress: 100, message: 'Your beast is ready!' }); setTimeout(() => { navigate('/play'); diff --git a/client/src/hooks/useBeasts.tsx b/client/src/hooks/useBeasts.tsx index e794d98..c4370d4 100644 --- a/client/src/hooks/useBeasts.tsx +++ b/client/src/hooks/useBeasts.tsx @@ -1,8 +1,8 @@ import { useEffect, useState } from "react"; import { dojoConfig } from "../dojo/dojoConfig"; import { lookupAddresses } from '@cartridge/controller'; -import { Beast, BeastEdge, BeastStatus, BeastStatusEdge, BeastStatuses } from '../types/game'; - +import { Beast, BeastEdge, BeastStatusEdge, BeastStatuses } from '../types/game'; + // Constants const TORII_URL = dojoConfig.toriiUrl + "/graphql"; const BEASTS_QUERY = ` @@ -31,6 +31,24 @@ const BEASTS_QUERY = ` } `; +const MY_BEASTS = (address: string) => ` + query GetBeastsByContract() { + tamagotchiBeastModels(where: { player: "${address}"}) { + edges { + node { + beast_id + birth_date + player + age + specie + beast_type + } + } + totalCount + } + } +`; + // API Functions export const fetchBeastsData = async (): Promise => { try { @@ -52,6 +70,26 @@ export const fetchBeastsData = async (): Promise => { } }; +export const fetchMyBeastsData = async (contractAddress: string): Promise => { + try { + const response = await fetch(TORII_URL, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ query: MY_BEASTS(contractAddress) }), + }); + + const result = await response.json(); + if (!result.data?.tamagotchiBeastModels) { + throw new Error('No beast data found'); + } + + return result.data; + } catch (error) { + console.error("Error fetching my beasts:", error); + throw error; + } +}; + export const processBeastData = async (data: any): Promise => { const playerAddresses = data.tamagotchiBeastModels.edges .map((edge: BeastEdge) => edge.node.player) @@ -85,18 +123,29 @@ const extractBeastStatuses = (statusModels: any): BeastStatuses => { }; // Hook -export const useBeasts = () => { +export const useBeasts = (userAddress?: string) => { const [beastsData, setBeastsData] = useState([]); + const [myBeastsData, setMyBeastsData] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); + const [trigger, setTrigger] = useState(0); useEffect(() => { const loadBeasts = async () => { try { setIsLoading(true); - const data = await fetchBeastsData(); - const processedData = await processBeastData(data); - setBeastsData(processedData); + const [allBeastsData, myBeasts] = await Promise.all([ + fetchBeastsData(), + userAddress ? fetchMyBeastsData(userAddress) : Promise.resolve(null) + ]); + + const processedAllBeasts = await processBeastData(allBeastsData); + setBeastsData(processedAllBeasts); + + if (myBeasts) { + const processedMyBeasts = await processBeastData(myBeasts); + setMyBeastsData(processedMyBeasts); + } } catch (err) { setError(err instanceof Error ? err : new Error('Unknown error occurred')); } finally { @@ -105,11 +154,17 @@ export const useBeasts = () => { }; loadBeasts(); - }, []); + }, [userAddress, trigger]); + + const refetch = () => { + setTrigger(prev => prev + 1); + }; return { beastsData, + myBeastsData, isLoading, - error + error, + refetch }; };