diff --git a/landing/src/components/modules/bridge-out-step-2.tsx b/landing/src/components/modules/bridge-out-step-2.tsx index 559ceb328..1691c01b9 100644 --- a/landing/src/components/modules/bridge-out-step-2.tsx +++ b/landing/src/components/modules/bridge-out-step-2.tsx @@ -6,7 +6,7 @@ import { displayAddress } from "@/lib/utils"; import { ADMIN_BANK_ENTITY_ID, RESOURCE_PRECISION, ResourcesIds } from "@bibliothecadao/eternum"; import { useAccount } from "@starknet-react/core"; import { ChevronDown, ChevronUp, Loader } from "lucide-react"; -import { useEffect, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { TypeP } from "../typography/type-p"; import { ShowSingleResource } from "../ui/SelectResources"; import { Button } from "../ui/button"; @@ -86,23 +86,27 @@ export const BridgeOutStep2 = () => { const [selectedDonkeys, setSelectedDonkeys] = useState>(new Set()); const [isTableOpen, setIsTableOpen] = useState(false); - const updateResourcesFromSelectedDonkeys = (selectedDonkeyIds: Set) => { - const allResources = Array.from(selectedDonkeyIds).flatMap( - (id) => - donkeyInfos?.find((d) => d?.donkeyEntityId && BigInt(d.donkeyEntityId) === id)?.donkeyResourceBalances || [], - ); + const updateResourcesFromSelectedDonkeys = useMemo( + () => (selectedDonkeyIds: Set) => { + const allResources = Array.from(selectedDonkeyIds).flatMap( + (id) => + donkeyInfos?.find((d) => d?.donkeyEntityId && BigInt(d.donkeyEntityId) === id)?.donkeyResourceBalances || [], + ); + + setSelectedResourceIds(allResources.map((r) => r.resourceId as never)); + setSelectedResourceAmounts( + allResources.reduce( + (acc, r) => ({ + ...acc, + [r.resourceId]: (acc[r.resourceId] || 0) + r.amount / RESOURCE_PRECISION, + }), + {}, + ), + ); + }, + [donkeyInfos, selectedDonkeys], + ); - setSelectedResourceIds(allResources.map((r) => r.resourceId as never)); - setSelectedResourceAmounts( - allResources.reduce( - (acc, r) => ({ - ...acc, - [r.resourceId]: (acc[r.resourceId] || 0) + r.amount / RESOURCE_PRECISION, - }), - {}, - ), - ); - }; useEffect(() => { const newSelected = new Set(); @@ -111,10 +115,7 @@ export const BridgeOutStep2 = () => { newSelected.add(BigInt(donkey?.donkeyEntityId || 0)); } }); - - setSelectedDonkeys(newSelected); - updateResourcesFromSelectedDonkeys(newSelected); - }, [donkeyInfos]); + }, [donkeyInfos, selectedDonkeys]); const handleRefresh = () => { setIsRefreshing(true); diff --git a/landing/src/hooks/helpers/useDonkeyArrivals.tsx b/landing/src/hooks/helpers/useDonkeyArrivals.tsx index 7263edb44..fc4add932 100644 --- a/landing/src/hooks/helpers/useDonkeyArrivals.tsx +++ b/landing/src/hooks/helpers/useDonkeyArrivals.tsx @@ -1,6 +1,6 @@ import { ADMIN_BANK_ENTITY_ID, ID } from "@bibliothecadao/eternum"; -import { useQuery } from "@tanstack/react-query"; +import { useQueries, useQuery } from "@tanstack/react-query"; import { useMemo } from "react"; import { execute } from "../gql/execute"; import { GetEternumEntityOwnerQuery } from "../gql/graphql"; @@ -9,103 +9,116 @@ import { GET_ENTITY_DISTANCE } from "../query/position"; import { GET_ENTITIES_RESOURCES } from "../query/resources"; export function useDonkeyArrivals(realmEntityIds: ID[]) { - const filteredRealmIds = useMemo(() => - realmEntityIds.filter(id => id !== 54), - [realmEntityIds] - ); - - const { - data: entityPositions, - isLoading: isLoadingPositions, - error: positionsError, - } = useQuery({ - queryKey: ["entityPositionBank"], - queryFn: () => execute(GET_ENTITY_DISTANCE, { entityIds: [Number(ADMIN_BANK_ENTITY_ID)] }), - }); - - const { - data: donkeyEntities, - isLoading: isLoadingDonkeyEntityIds, - error: errorDonkeyEntityIds, - } = useQuery({ - queryKey: ["donkeyEntityIds", filteredRealmIds], - queryFn: () => execute(GET_ETERNUM_ENTITY_OWNERS, { entityOwnerIds: filteredRealmIds }), - enabled: filteredRealmIds.length > 0, + const { + data: entityPositions, + isLoading: isLoadingPositions, + error: positionsError, + } = useQuery({ + queryKey: ["entityPositionBank"], + queryFn: () => execute(GET_ENTITY_DISTANCE, { entityIds: [Number(ADMIN_BANK_ENTITY_ID)] }), + }); + + // const { + // data: donkeyEntities, + // isLoading: isLoadingDonkeyEntityIds, + // error: errorDonkeyEntityIds, + // } = useQuery({ + // queryKey: ["donkeyEntityIds", realmEntityIds], + // queryFn: () => execute(GET_ETERNUM_ENTITY_OWNERS, { entityOwnerIds: realmEntityIds }), + // enabled: realmEntityIds.length > 0, + // refetchInterval: 10_000, + // }); + + const donkeyQueriesResults = useQueries({ + queries: realmEntityIds.map((realmId) => ({ + queryKey: ["donkeyEntityIds", realmId], + queryFn: () => execute(GET_ETERNUM_ENTITY_OWNERS, { entityOwnerIds: [realmId] }), + enabled: !!realmId, refetchInterval: 10_000, + staleTime: 5000, + })), + }); + + const donkeyEntities = useMemo( + () => ({ + s0EternumEntityOwnerModels: { + edges: donkeyQueriesResults + .filter((result) => result.data) + .flatMap((result) => result.data?.s0EternumEntityOwnerModels?.edges || []), + }, + }), + [donkeyQueriesResults], + ); + + const isLoadingDonkeyEntityIds = donkeyQueriesResults.some((result) => result.isLoading); + const errorDonkeyEntityIds = donkeyQueriesResults.find((result) => result.error)?.error; + + const bankPosition = useMemo( + () => + entityPositions?.s0EternumPositionModels?.edges?.find((entity) => entity?.node?.entity_id == ADMIN_BANK_ENTITY_ID) + ?.node, + [entityPositions], + ); + + const donkeysAtBank = useMemo(() => { + if (!donkeyEntities?.s0EternumEntityOwnerModels?.edges || !bankPosition) return []; + + return donkeyEntities.s0EternumEntityOwnerModels.edges.filter((edge) => { + const position = edge?.node?.entity?.models?.find((model) => model?.__typename === "s0_eternum_Position"); + const resource = edge?.node?.entity?.models?.find( + (model) => model?.__typename === "s0_eternum_OwnedResourcesTracker", + ); + + return Boolean( + position?.x === bankPosition?.x && position?.y === bankPosition?.y && resource?.resource_types !== "0x0", + ); }); - - const bankPosition = useMemo( - () => - entityPositions?.s0EternumPositionModels?.edges?.find((entity) => entity?.node?.entity_id == ADMIN_BANK_ENTITY_ID) - ?.node, - [entityPositions], - ); - - const donkeysAtBank = useMemo(() => { - if (!donkeyEntities?.s0EternumEntityOwnerModels?.edges || !bankPosition) return []; - - return donkeyEntities.s0EternumEntityOwnerModels.edges.filter((edge) => { - const position = edge?.node?.entity?.models?.find( - (model) => model?.__typename === "s0_eternum_Position" - ); - const resource = edge?.node?.entity?.models?.find( - (model) => model?.__typename === "s0_eternum_OwnedResourcesTracker" - ); - - return Boolean( - position?.x === bankPosition?.x && - position?.y === bankPosition?.y && - resource?.resource_types !== "0x0" - ); - }); - }, [donkeyEntities, bankPosition]); - - const donkeyEntityIds = useMemo( - () => - donkeysAtBank?.map((edge) => edge?.node?.entity_id) - .filter((id): id is number => id != null) ?? [], - [donkeysAtBank], - ); - - const { data: donkeyResources } = useQuery({ - queryKey: ["donkeyResources" + donkeyEntityIds], - queryFn: () => execute(GET_ENTITIES_RESOURCES, { entityIds: donkeyEntityIds }), - enabled: !!donkeyEntityIds, - }); - - const getDonkeyInfo = ( - donkeyEntity: NonNullable< - NonNullable["edges"]>[number] - >, - ) => { - const donkeyEntityId = donkeyEntity?.node?.entity_id; - const donkeyArrivalTime = donkeyEntity?.node?.entity?.models?.find( - (model) => model?.__typename === "s0_eternum_ArrivalTime", - )?.arrives_at; - - const donkeyResourceBalances = - donkeyResources?.s0EternumResourceModels?.edges - ?.filter((edge) => edge?.node?.entity_id === donkeyEntityId) - ?.map((edge) => edge?.node) - ?.map((node) => ({ - resourceId: node?.resource_type, - amount: node?.balance, - })) - .filter((r) => Number(r.amount) > 0) ?? []; - - return { donkeyEntityId, donkeyArrivalTime, donkeyResourceBalances }; - }; - - const donkeyInfos = useMemo(() => { - return donkeysAtBank?.map((donkey) => donkey && getDonkeyInfo(donkey)); - }, [donkeysAtBank, donkeyResources]); - - return { - donkeyArrivals: donkeysAtBank, - donkeyInfos, - bankPosition, - donkeyResources, - isLoading: isLoadingPositions || isLoadingDonkeyEntityIds, - error: positionsError || errorDonkeyEntityIds, - }; - } \ No newline at end of file + }, [donkeyEntities, bankPosition]); + + const donkeyEntityIds = useMemo( + () => donkeysAtBank?.map((edge) => edge?.node?.entity_id).filter((id): id is number => id != null) ?? [], + [donkeysAtBank], + ); + + const { data: donkeyResources } = useQuery({ + queryKey: ["donkeyResources" + donkeyEntityIds], + queryFn: () => execute(GET_ENTITIES_RESOURCES, { entityIds: donkeyEntityIds }), + enabled: !!donkeyEntityIds, + }); + + const getDonkeyInfo = ( + donkeyEntity: NonNullable< + NonNullable["edges"]>[number] + >, + ) => { + const donkeyEntityId = donkeyEntity?.node?.entity_id; + const donkeyArrivalTime = donkeyEntity?.node?.entity?.models?.find( + (model) => model?.__typename === "s0_eternum_ArrivalTime", + )?.arrives_at; + + const donkeyResourceBalances = + donkeyResources?.s0EternumResourceModels?.edges + ?.filter((edge) => edge?.node?.entity_id === donkeyEntityId) + ?.map((edge) => edge?.node) + ?.map((node) => ({ + resourceId: node?.resource_type, + amount: node?.balance, + })) + .filter((r) => Number(r.amount) > 0) ?? []; + + return { donkeyEntityId, donkeyArrivalTime, donkeyResourceBalances }; + }; + + const donkeyInfos = useMemo(() => { + return donkeysAtBank?.map((donkey) => donkey && getDonkeyInfo(donkey)); + }, [donkeysAtBank, donkeyResources]); + + return { + donkeyArrivals: donkeysAtBank, + donkeyInfos, + bankPosition, + donkeyResources, + isLoading: isLoadingPositions || isLoadingDonkeyEntityIds, + error: positionsError || errorDonkeyEntityIds, + }; +}