Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/dev-dist/sw.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"), {
Expand Down
38 changes: 18 additions & 20 deletions client/src/components/SpawnBeast/index.tsx
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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';
Expand All @@ -38,7 +37,14 @@ const SpawnBeast: React.FC<SpawnBeastProps> = ({ 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<SpawnBeastState>({
loading: false,
Expand Down Expand Up @@ -73,8 +79,7 @@ const SpawnBeast: React.FC<SpawnBeastProps> = ({ 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!' });
Expand All @@ -83,23 +88,16 @@ const SpawnBeast: React.FC<SpawnBeastProps> = ({ 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');
Expand Down
71 changes: 63 additions & 8 deletions client/src/hooks/useBeasts.tsx
Original file line number Diff line number Diff line change
@@ -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 = `
Expand Down Expand Up @@ -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<any> => {
try {
Expand All @@ -52,6 +70,26 @@ export const fetchBeastsData = async (): Promise<any> => {
}
};

export const fetchMyBeastsData = async (contractAddress: string): Promise<any> => {
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<Beast[]> => {
const playerAddresses = data.tamagotchiBeastModels.edges
.map((edge: BeastEdge) => edge.node.player)
Expand Down Expand Up @@ -85,18 +123,29 @@ const extractBeastStatuses = (statusModels: any): BeastStatuses => {
};

// Hook
export const useBeasts = () => {
export const useBeasts = (userAddress?: string) => {
const [beastsData, setBeastsData] = useState<Beast[]>([]);
const [myBeastsData, setMyBeastsData] = useState<Beast[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<Error | null>(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 {
Expand All @@ -105,11 +154,17 @@ export const useBeasts = () => {
};

loadBeasts();
}, []);
}, [userAddress, trigger]);

const refetch = () => {
setTrigger(prev => prev + 1);
};

return {
beastsData,
myBeastsData,
isLoading,
error
error,
refetch
};
};