diff --git a/client/src/hooks/helpers/use-resource-arrivals.tsx b/client/src/hooks/helpers/use-resource-arrivals.tsx index bc2739b3a..21e8ccc1a 100644 --- a/client/src/hooks/helpers/use-resource-arrivals.tsx +++ b/client/src/hooks/helpers/use-resource-arrivals.tsx @@ -13,7 +13,7 @@ import { import { getEntityIdFromKeys } from "@dojoengine/utils"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useDojo } from "../context/DojoContext"; -import useUIStore from "../store/useUIStore"; +import useNextBlockTimestamp from "../useNextBlockTimestamp"; export type ArrivalInfo = { entityId: ID; @@ -168,7 +168,7 @@ export const usePlayerArrivalsNotifications = () => { const arrivals = usePlayerArrivals(); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); useEffect(() => { const arrivedCount = arrivals.filter( diff --git a/client/src/hooks/helpers/useResources.tsx b/client/src/hooks/helpers/useResources.tsx index 4e3480259..7400d78b3 100644 --- a/client/src/hooks/helpers/useResources.tsx +++ b/client/src/hooks/helpers/useResources.tsx @@ -15,6 +15,7 @@ import { ResourceManager } from "../../dojo/modelManager/ResourceManager"; import { getEntityIdFromKeys } from "../../ui/utils/utils"; import { useDojo } from "../context/DojoContext"; import useUIStore from "../store/useUIStore"; +import useNextBlockTimestamp from "../useNextBlockTimestamp"; export function useResourcesUtils() { const { setup } = useDojo(); @@ -27,7 +28,7 @@ export function useResourcesUtils() { }, []); const useResourcesFromBalance = (entityId: ID) => { - const currentDefaultTick = useUIStore((state) => state.currentDefaultTick); + const { currentDefaultTick } = useNextBlockTimestamp(); const weight = useComponentValue(Weight, getEntityIdFromKeys([BigInt(entityId)])); const capacityCategory = useComponentValue(CapacityCategory, getEntityIdFromKeys([BigInt(entityId)])); diff --git a/client/src/hooks/helpers/useStructures.tsx b/client/src/hooks/helpers/useStructures.tsx index 38ad4658e..88a9282ec 100644 --- a/client/src/hooks/helpers/useStructures.tsx +++ b/client/src/hooks/helpers/useStructures.tsx @@ -8,7 +8,7 @@ import { getEntityIdFromKeys } from "@dojoengine/utils"; import { useMemo } from "react"; import { shortString } from "starknet"; import { useDojo } from "../context/DojoContext"; -import useUIStore from "../store/useUIStore"; +import useNextBlockTimestamp from "../useNextBlockTimestamp"; import { ArmyInfo, getArmyByEntityId } from "./useArmies"; import { useEntitiesUtils } from "./useEntities"; @@ -245,7 +245,7 @@ export const useStructureImmunityTimer = (structure: Structure | undefined, next export const useIsResourcesLocked = (structureEntityId: ID) => { const dojo = useDojo(); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); const { getStructureByEntityId } = useStructures(); const structure = getStructureByEntityId(structureEntityId); diff --git a/client/src/hooks/helpers/useTrade.tsx b/client/src/hooks/helpers/useTrade.tsx index 74377be9d..9613f81ca 100644 --- a/client/src/hooks/helpers/useTrade.tsx +++ b/client/src/hooks/helpers/useTrade.tsx @@ -7,6 +7,7 @@ import { shortString } from "starknet"; import { getEntityIdFromKeys } from "../../ui/utils/utils"; import { useDojo } from "../context/DojoContext"; import useUIStore from "../store/useUIStore"; +import useNextBlockTimestamp from "../useNextBlockTimestamp"; import { useEntities } from "./useEntities"; type TradeResourcesFromViewpoint = { @@ -141,7 +142,7 @@ export function useGetMyOffers(): MarketInterface[] { const { computeTrades } = useTrade(); const structureEntityId = useUIStore((state) => state.structureEntityId); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); const [myOffers, setMyOffers] = useState([]); @@ -166,7 +167,7 @@ export function useSetMarket() { const { playerRealms } = useEntities(); const realmEntityIds = playerRealms().map((realm: any) => realm.entity_id); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); const { computeTrades } = useTrade(); diff --git a/client/src/hooks/store/useBlockchainStore.tsx b/client/src/hooks/store/useBlockchainStore.tsx index 4fedecd95..5563c6220 100644 --- a/client/src/hooks/store/useBlockchainStore.tsx +++ b/client/src/hooks/store/useBlockchainStore.tsx @@ -1,6 +1,6 @@ import { configManager } from "@/dojo/setup"; import { TickIds } from "@bibliothecadao/eternum"; -import { useEffect } from "react"; +import { useEffect, useTransition } from "react"; import useUIStore from "./useUIStore"; export interface BlockchainStore { @@ -22,9 +22,7 @@ export const createBlockchainStore = (set: any) => ({ }); export const useFetchBlockchainData = () => { - const setNextBlockTimestamp = useUIStore((state) => state.setNextBlockTimestamp); - const setCurrentDefaultTick = useUIStore((state) => state.setCurrentDefaultTick); - const setCurrentArmiesTick = useUIStore((state) => state.setCurrentArmiesTick); + const [isPending, startTransition] = useTransition(); useEffect(() => { const tickConfigArmies = configManager.getTick(TickIds.Armies); @@ -34,9 +32,13 @@ export const useFetchBlockchainData = () => { const timestamp = Math.floor(Date.now() / 1000); if (timestamp) { - setNextBlockTimestamp(timestamp); - setCurrentDefaultTick(Math.floor(timestamp / Number(tickConfigDefault))); - setCurrentArmiesTick(Math.floor(timestamp / Number(tickConfigArmies))); + startTransition(() => { + useUIStore.setState({ + nextBlockTimestamp: timestamp, + currentDefaultTick: Math.floor(timestamp / Number(tickConfigDefault)), + currentArmiesTick: Math.floor(timestamp / Number(tickConfigArmies)), + }); + }); } }; diff --git a/client/src/hooks/store/useLeaderBoardStore.tsx b/client/src/hooks/store/useLeaderBoardStore.tsx index 6c4a0b6db..dd2dc63f4 100644 --- a/client/src/hooks/store/useLeaderBoardStore.tsx +++ b/client/src/hooks/store/useLeaderBoardStore.tsx @@ -4,7 +4,7 @@ import { useCallback } from "react"; import { create } from "zustand"; import { useDojo } from "../context/DojoContext"; import { useGuilds } from "../helpers/useGuilds"; -import useUIStore from "./useUIStore"; +import useNextBlockTimestamp from "../useNextBlockTimestamp"; interface LeaderboardStore { playersByRank: [ContractAddress, number][]; @@ -27,7 +27,7 @@ export const useHyperstructureData = () => { const { getGuildFromPlayerAddress } = useGuilds(); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); const setPlayersByRank = useLeaderBoardStore((state) => state.setPlayersByRank); const setGuildsByRank = useLeaderBoardStore((state) => state.setGuildsByRank); diff --git a/client/src/hooks/useNextBlockTimestamp.tsx b/client/src/hooks/useNextBlockTimestamp.tsx new file mode 100644 index 000000000..9fc738cc6 --- /dev/null +++ b/client/src/hooks/useNextBlockTimestamp.tsx @@ -0,0 +1,34 @@ +import { configManager } from "@/dojo/setup"; +import { TickIds } from "@bibliothecadao/eternum"; +import { startTransition, useEffect, useState } from "react"; + +const useNextBlockTimestamp = () => { + const [nextBlockTimestamp, setNextBlockTimestamp] = useState(Math.floor(Date.now() / 1000)); + const [currentDefaultTick, setCurrentDefaultTick] = useState(0); + const [currentArmiesTick, setCurrentArmiesTick] = useState(0); + + useEffect(() => { + const tickConfigArmies = configManager.getTick(TickIds.Armies); + const tickConfigDefault = configManager.getTick(TickIds.Default); + + const updateTimestamp = () => { + const timestamp = Math.floor(Date.now() / 1000); + startTransition(() => { + setNextBlockTimestamp(timestamp); + setCurrentDefaultTick(Math.floor(timestamp / Number(tickConfigDefault))); + setCurrentArmiesTick(Math.floor(timestamp / Number(tickConfigArmies))); + }); + }; + + // Create a unique interval for each hook instance + const intervalId = setInterval(updateTimestamp, 10000); + + return () => { + clearInterval(intervalId); + }; + }, []); + + return { nextBlockTimestamp, currentDefaultTick, currentArmiesTick }; +}; + +export default useNextBlockTimestamp; diff --git a/client/src/ui/components/battles/BattleListItem.tsx b/client/src/ui/components/battles/BattleListItem.tsx index d17c7bdf4..d1b73ac3b 100644 --- a/client/src/ui/components/battles/BattleListItem.tsx +++ b/client/src/ui/components/battles/BattleListItem.tsx @@ -7,6 +7,7 @@ import { BattleInfo } from "@/hooks/helpers/battles/useBattles"; import { ArmyInfo } from "@/hooks/helpers/useArmies"; import { useEntitiesUtils } from "@/hooks/helpers/useEntities"; import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { getComponentValue, HasValue, runQuery } from "@dojoengine/recs"; import React, { useMemo, useState } from "react"; import { ViewOnMapIcon } from "../military/ArmyManagementCard"; @@ -24,7 +25,7 @@ export const BattleListItem = ({ battle, ownArmySelected, showCompass = false }: const { getAddressNameFromEntity } = useEntitiesUtils(); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); const [showInventory, setShowInventory] = useState(false); diff --git a/client/src/ui/components/hyperstructures/CoOwners.tsx b/client/src/ui/components/hyperstructures/CoOwners.tsx index 18ab89dc8..70e7bdac3 100644 --- a/client/src/ui/components/hyperstructures/CoOwners.tsx +++ b/client/src/ui/components/hyperstructures/CoOwners.tsx @@ -4,6 +4,7 @@ import { useGetAllPlayers } from "@/hooks/helpers/use-get-all-players"; import { useRealm } from "@/hooks/helpers/useRealm"; import { useStructureByEntityId } from "@/hooks/helpers/useStructures"; import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import Button from "@/ui/elements/Button"; import { NumberInput } from "@/ui/elements/NumberInput"; import { SelectAddress } from "@/ui/elements/SelectAddress"; @@ -59,7 +60,7 @@ const CoOwnersRows = ({ } = useDojo(); const setTooltip = useUIStore((state) => state.setTooltip); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); const hyperstructureConfig = useMemo(() => { return getComponentValue(HyperstructureConfig, getEntityIdFromKeys([HYPERSTRUCTURE_CONFIG_ID])); diff --git a/client/src/ui/components/hyperstructures/Leaderboard.tsx b/client/src/ui/components/hyperstructures/Leaderboard.tsx index f5b87b260..fed724c01 100644 --- a/client/src/ui/components/hyperstructures/Leaderboard.tsx +++ b/client/src/ui/components/hyperstructures/Leaderboard.tsx @@ -2,7 +2,7 @@ import { LeaderboardManager } from "@/dojo/modelManager/LeaderboardManager"; import { useDojo } from "@/hooks/context/DojoContext"; import { useHyperstructureUpdates } from "@/hooks/helpers/useHyperstructures"; import { useRealm } from "@/hooks/helpers/useRealm"; -import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import Button from "@/ui/elements/Button"; import { SortButton, SortInterface } from "@/ui/elements/SortButton"; import { SortPanel } from "@/ui/elements/SortPanel"; @@ -26,7 +26,7 @@ export const Leaderboard = ({ }, } = dojo; - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); const { getAddressName } = useRealm(); diff --git a/client/src/ui/components/military/ArmyChip.tsx b/client/src/ui/components/military/ArmyChip.tsx index 4a1992cd4..6cafa5cf3 100644 --- a/client/src/ui/components/military/ArmyChip.tsx +++ b/client/src/ui/components/military/ArmyChip.tsx @@ -7,6 +7,7 @@ import { useDojo } from "@/hooks/context/DojoContext"; import { ArmyInfo, getArmiesByPosition } from "@/hooks/helpers/useArmies"; import { armyHasTroops } from "@/hooks/helpers/useQuests"; import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { Position as PositionInterface } from "@/types/Position"; import { ArmyCapacity } from "@/ui/elements/ArmyCapacity"; import Button from "@/ui/elements/Button"; @@ -71,7 +72,7 @@ export const ArmyChip = ({ const [showInventory, setShowInventory] = useState(false); const [showTroopSwap, setShowTroopSwap] = useState(false); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); const [editMode, setEditMode] = useState(false); diff --git a/client/src/ui/components/resources/EntityResourceTable.tsx b/client/src/ui/components/resources/EntityResourceTable.tsx index c5bc36396..37a04668b 100644 --- a/client/src/ui/components/resources/EntityResourceTable.tsx +++ b/client/src/ui/components/resources/EntityResourceTable.tsx @@ -1,6 +1,6 @@ import { configManager } from "@/dojo/setup"; import { useDojo } from "@/hooks/context/DojoContext"; -import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { getEntityIdFromKeys, gramToKg, multiplyByPrecision } from "@/ui/utils/utils"; import { BuildingType, CapacityConfigCategory, ID, RESOURCE_TIERS } from "@bibliothecadao/eternum"; import { useComponentValue } from "@dojoengine/react"; @@ -10,7 +10,7 @@ import { ResourceChip } from "./ResourceChip"; export const EntityResourceTable = ({ entityId }: { entityId: ID | undefined }) => { const dojo = useDojo(); - const tick = useUIStore((state) => state.currentDefaultTick); + const { currentDefaultTick: tick } = useNextBlockTimestamp(); const quantity = useComponentValue( diff --git a/client/src/ui/components/structures/worldmap/StructureCard.tsx b/client/src/ui/components/structures/worldmap/StructureCard.tsx index 976b2e4e1..816d8dfba 100644 --- a/client/src/ui/components/structures/worldmap/StructureCard.tsx +++ b/client/src/ui/components/structures/worldmap/StructureCard.tsx @@ -5,6 +5,7 @@ import { useGuilds } from "@/hooks/helpers/useGuilds"; import { useQuery } from "@/hooks/helpers/useQuery"; import { useIsStructureImmune, useStructureAtPosition, useStructureImmunityTimer } from "@/hooks/helpers/useStructures"; import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { Position } from "@/types/Position"; import { ArmyCapacity } from "@/ui/elements/ArmyCapacity"; import Button from "@/ui/elements/Button"; @@ -35,7 +36,7 @@ export const StructureCard = ({ }) => { const [showMergeTroopsPopup, setShowMergeTroopsPopup] = useState(false); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); const { handleUrlChange } = useQuery(); diff --git a/client/src/ui/components/trading/MarketOrderPanel.tsx b/client/src/ui/components/trading/MarketOrderPanel.tsx index 044404c52..4e7cb4e88 100644 --- a/client/src/ui/components/trading/MarketOrderPanel.tsx +++ b/client/src/ui/components/trading/MarketOrderPanel.tsx @@ -5,7 +5,7 @@ import { useRealm } from "@/hooks/helpers/useRealm"; import { useResourceManager } from "@/hooks/helpers/useResources"; import { useIsResourcesLocked } from "@/hooks/helpers/useStructures"; import { useTravel } from "@/hooks/helpers/useTravel"; -import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { soundSelector, useUiSounds } from "@/hooks/useUISound"; import Button from "@/ui/elements/Button"; import { NumberInput } from "@/ui/elements/NumberInput"; @@ -47,7 +47,7 @@ export const MarketResource = ({ bidPrice: number; ammPrice: number; }) => { - const currentDefaultTick = useUIStore((state) => state.currentDefaultTick); + const { currentDefaultTick } = useNextBlockTimestamp(); const resourceManager = useResourceManager(entityId, resourceId); const production = useMemo(() => { @@ -293,7 +293,7 @@ const OrderRow = ({ return isBuy ? offer.takerGets[0].amount : offer.makerGets[0].amount; }, [entityId, offer.makerId, offer.tradeId, offer]); - const currentDefaultTick = useUIStore((state) => state.currentDefaultTick); + const { currentDefaultTick } = useNextBlockTimestamp(); const resourceBalanceRatio = useMemo( () => (resourceBalance < getsDisplayNumber ? resourceBalance / getsDisplayNumber : 1), @@ -497,7 +497,8 @@ const OrderCreation = ({ const [resource, setResource] = useState(1000); const [lords, setLords] = useState(100); const [bid, setBid] = useState(String(lords / resource)); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); + const { play: playLordsSound } = useUiSounds(soundSelector.addLords); const { @@ -558,7 +559,8 @@ const OrderCreation = ({ return calculateDonkeysNeeded(orderWeight); }, [orderWeight]); - const currentDefaultTick = useUIStore((state) => state.currentDefaultTick); + const { currentDefaultTick } = useNextBlockTimestamp(); + const donkeyProductionManager = useResourceManager(entityId, ResourcesIds.Donkey); const donkeyProduction = useMemo(() => { diff --git a/client/src/ui/components/worldmap/armies/ArmyInfoLabel.tsx b/client/src/ui/components/worldmap/armies/ArmyInfoLabel.tsx index c6f8b6d35..6eaff4fe6 100644 --- a/client/src/ui/components/worldmap/armies/ArmyInfoLabel.tsx +++ b/client/src/ui/components/worldmap/armies/ArmyInfoLabel.tsx @@ -9,6 +9,7 @@ import { useStructureImmunityTimer, useStructures, } from "@/hooks/helpers/useStructures"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { ArmyCapacity } from "@/ui/elements/ArmyCapacity"; import { BaseThreeTooltip, Position } from "@/ui/elements/BaseThreeTooltip"; import { Headline } from "@/ui/elements/Headline"; @@ -56,7 +57,7 @@ const RaiderInfo = ({ army }: ArmyInfoLabelProps) => { } }, [entityOwner.entity_owner_id]); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); const isImmune = useIsStructureImmune(structure, nextBlockTimestamp || 0); const timer = useStructureImmunityTimer(structure as Structure, nextBlockTimestamp || 0); diff --git a/client/src/ui/components/worldmap/structures/StructureLabel.tsx b/client/src/ui/components/worldmap/structures/StructureLabel.tsx index 8f0948a5c..64d9ab4d8 100644 --- a/client/src/ui/components/worldmap/structures/StructureLabel.tsx +++ b/client/src/ui/components/worldmap/structures/StructureLabel.tsx @@ -6,6 +6,7 @@ import { useStructureImmunityTimer, useStructures, } from "@/hooks/helpers/useStructures"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { BaseThreeTooltip, Position } from "@/ui/elements/BaseThreeTooltip"; import { Headline } from "@/ui/elements/Headline"; import { formatTime } from "@/ui/utils/utils"; @@ -49,7 +50,7 @@ export const StructureInfoLabel = memo(() => { const playerGuild = getGuildFromPlayerAddress(ContractAddress(structure?.owner.address || 0n)); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); const isImmune = useIsStructureImmune(structure, nextBlockTimestamp || 0); const timer = useStructureImmunityTimer(structure as Structure, nextBlockTimestamp || 0); @@ -83,4 +84,4 @@ export const StructureInfoLabel = memo(() => { ); }); -StructureInfoLabel.displayName = "StructureInfoLabel"; +StructureInfoLabel.displayName = "StructureInfoLabel"; diff --git a/client/src/ui/components/worldmap/structures/StructureListItem.tsx b/client/src/ui/components/worldmap/structures/StructureListItem.tsx index 51e544b2b..567cb5cf9 100644 --- a/client/src/ui/components/worldmap/structures/StructureListItem.tsx +++ b/client/src/ui/components/worldmap/structures/StructureListItem.tsx @@ -7,6 +7,7 @@ import { ArmyInfo, getUserArmyInBattle } from "@/hooks/helpers/useArmies"; import { useGetHyperstructureProgress } from "@/hooks/helpers/useHyperstructures"; import { Structure, useIsStructureImmune } from "@/hooks/helpers/useStructures"; import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { ResourcesIds, StructureType } from "@bibliothecadao/eternum"; import clsx from "clsx"; import { useMemo } from "react"; @@ -39,7 +40,8 @@ export const StructureListItem = ({ }: StructureListItemProps) => { const dojo = useDojo(); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); + const setTooltip = useUIStore((state) => state.setTooltip); const setBattleView = useUIStore((state) => state.setBattleView); diff --git a/client/src/ui/elements/StaminaResource.tsx b/client/src/ui/elements/StaminaResource.tsx index 3eaf2484b..1194aa7aa 100644 --- a/client/src/ui/elements/StaminaResource.tsx +++ b/client/src/ui/elements/StaminaResource.tsx @@ -3,6 +3,7 @@ import { configManager } from "@/dojo/setup"; import { useDojo } from "@/hooks/context/DojoContext"; import { useStaminaManager } from "@/hooks/helpers/useStamina"; import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { ID } from "@bibliothecadao/eternum"; import { getComponentValue } from "@dojoengine/recs"; import { getEntityIdFromKeys } from "@dojoengine/utils"; @@ -10,7 +11,8 @@ import { useMemo } from "react"; export const StaminaResource = ({ entityId, className }: { entityId: ID | undefined; className?: string }) => { const { setup } = useDojo(); - const currentArmiesTick = useUIStore((state) => state.currentArmiesTick); + const { currentArmiesTick } = useNextBlockTimestamp(); + const staminaManager = useStaminaManager(entityId || 0); const setTooltip = useUIStore((state) => state.setTooltip); diff --git a/client/src/ui/elements/StaminaResourceCost.tsx b/client/src/ui/elements/StaminaResourceCost.tsx index 6d81fadeb..e5a16f702 100644 --- a/client/src/ui/elements/StaminaResourceCost.tsx +++ b/client/src/ui/elements/StaminaResourceCost.tsx @@ -1,6 +1,6 @@ import { configManager } from "@/dojo/setup"; import { useStaminaManager } from "@/hooks/helpers/useStamina"; -import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { ID } from "@bibliothecadao/eternum"; import clsx from "clsx"; import { useMemo } from "react"; @@ -14,8 +14,7 @@ export const StaminaResourceCost = ({ travelLength: number; isExplored: boolean; }) => { - const currentArmiesTick = useUIStore((state) => state.currentArmiesTick); - + const { currentArmiesTick } = useNextBlockTimestamp(); const staminaManager = useStaminaManager(travelingEntityId || 0); const stamina = useMemo(() => staminaManager.getStamina(currentArmiesTick), [currentArmiesTick, staminaManager]); diff --git a/client/src/ui/modules/entity-details/EnemyArmies.tsx b/client/src/ui/modules/entity-details/EnemyArmies.tsx index 399fe5408..e27f701b2 100644 --- a/client/src/ui/modules/entity-details/EnemyArmies.tsx +++ b/client/src/ui/modules/entity-details/EnemyArmies.tsx @@ -5,6 +5,7 @@ import { ArmyInfo } from "@/hooks/helpers/useArmies"; import { useEntitiesUtils } from "@/hooks/helpers/useEntities"; import { useIsStructureImmune, useStructureAtPosition } from "@/hooks/helpers/useStructures"; import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { Position } from "@/types/Position"; import { ArmyChip } from "@/ui/components/military/ArmyChip"; import clsx from "clsx"; @@ -23,7 +24,8 @@ export const EnemyArmies = ({ const { getEntityInfo } = useEntitiesUtils(); const structureAtPosition = useStructureAtPosition(position.getContract()); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); + const setBattleView = useUIStore((state) => state.setBattleView); const setTooltip = useUIStore((state) => state.setTooltip); diff --git a/client/src/ui/modules/entity-details/realm/RealmDetails.tsx b/client/src/ui/modules/entity-details/realm/RealmDetails.tsx index 43cf81d8b..868257fae 100644 --- a/client/src/ui/modules/entity-details/realm/RealmDetails.tsx +++ b/client/src/ui/modules/entity-details/realm/RealmDetails.tsx @@ -5,6 +5,7 @@ import { useStructureImmunityTimer, } from "@/hooks/helpers/useStructures"; import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { HintSection } from "@/ui/components/hints/HintModal"; import { HintModalButton } from "@/ui/elements/HintModalButton"; import { Tabs } from "@/ui/elements/tab"; @@ -15,7 +16,8 @@ import { Buildings } from "./Buildings"; import { Castle } from "./Castle"; export const RealmDetails = () => { - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp } = useNextBlockTimestamp(); + const structureEntityId = useUIStore((state) => state.structureEntityId); const setTooltip = useUIStore((state) => state.setTooltip); diff --git a/client/src/ui/modules/military/battle-view/BattleActions.tsx b/client/src/ui/modules/military/battle-view/BattleActions.tsx index cd7e637b6..4acc8eb3b 100644 --- a/client/src/ui/modules/military/battle-view/BattleActions.tsx +++ b/client/src/ui/modules/military/battle-view/BattleActions.tsx @@ -25,6 +25,7 @@ import { ReactComponent as Battle } from "@/assets/icons/battle.svg"; import { ReactComponent as Burn } from "@/assets/icons/burn.svg"; import { ReactComponent as Castle } from "@/assets/icons/castle.svg"; import { ReactComponent as Flag } from "@/assets/icons/flag.svg"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { currencyFormat } from "@/ui/utils/utils"; import { getEntityIdFromKeys } from "@dojoengine/utils"; import { getChancesOfSuccess, getMaxResourceAmountStolen, getTroopLossOnRaid } from "./utils"; @@ -67,8 +68,7 @@ export const BattleActions = ({ const { getAliveArmy } = getArmyByEntityId(); const setTooltip = useUIStore((state) => state.setTooltip); - const currentTimestamp = useUIStore((state) => state.nextBlockTimestamp); - const currentArmiesTick = useUIStore((state) => state.currentArmiesTick); + const { nextBlockTimestamp: currentTimestamp, currentArmiesTick } = useNextBlockTimestamp(); const setBattleView = useUIStore((state) => state.setBattleView); const setView = useUIStore((state) => state.setLeftNavigationView); diff --git a/client/src/ui/modules/military/battle-view/BattleProgress.tsx b/client/src/ui/modules/military/battle-view/BattleProgress.tsx index 75734ad3e..733972b4e 100644 --- a/client/src/ui/modules/military/battle-view/BattleProgress.tsx +++ b/client/src/ui/modules/military/battle-view/BattleProgress.tsx @@ -1,7 +1,7 @@ import { BattleManager, BattleStatus, BattleType } from "@/dojo/modelManager/BattleManager"; import { ArmyInfo } from "@/hooks/helpers/useArmies"; import { Structure } from "@/hooks/helpers/useStructures"; -import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { soundSelector, useUiSounds } from "@/hooks/useUISound"; import { Health } from "@/types"; import { motion } from "framer-motion"; @@ -135,7 +135,7 @@ export const BattleProgress = ({ defenderArmies: (ArmyInfo | undefined)[]; structure: Structure | undefined; }) => { - const currentTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp: currentTimestamp } = useNextBlockTimestamp(); const playUnitSelectedOne = useUiSounds(soundSelector.unitSelected1).play; const playUnitSelectedTwo = useUiSounds(soundSelector.unitSelected2).play; diff --git a/client/src/ui/modules/military/battle-view/BattleSideView.tsx b/client/src/ui/modules/military/battle-view/BattleSideView.tsx index 8e22325c2..f5e8e44b1 100644 --- a/client/src/ui/modules/military/battle-view/BattleSideView.tsx +++ b/client/src/ui/modules/military/battle-view/BattleSideView.tsx @@ -4,7 +4,7 @@ import { useDojo } from "@/hooks/context/DojoContext"; import { ArmyInfo, useArmyByArmyEntityId } from "@/hooks/helpers/useArmies"; import { useEntitiesUtils } from "@/hooks/helpers/useEntities"; import { Structure } from "@/hooks/helpers/useStructures"; -import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import Button from "@/ui/elements/Button"; import { BattleSide, ID } from "@bibliothecadao/eternum"; import { ComponentValue } from "@dojoengine/recs"; @@ -44,7 +44,7 @@ export const BattleSideView = ({ const [confirmLeaveWithAllArmies, setConfirmLeaveWithAllArmies] = useState(false); - const currentTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp: currentTimestamp } = useNextBlockTimestamp(); const isActive = useMemo(() => battleManager.isBattleOngoing(currentTimestamp!), [battleManager, currentTimestamp]); diff --git a/client/src/ui/modules/military/battle-view/BattleView.tsx b/client/src/ui/modules/military/battle-view/BattleView.tsx index c75609769..d9985125e 100644 --- a/client/src/ui/modules/military/battle-view/BattleView.tsx +++ b/client/src/ui/modules/military/battle-view/BattleView.tsx @@ -4,6 +4,7 @@ import { useBattleManager } from "@/hooks/helpers/battles/useBattles"; import { getArmiesByBattleId, getArmyByEntityId, useArmyByArmyEntityId } from "@/hooks/helpers/useArmies"; import { Structure, useStructureByEntityId, useStructureByPosition } from "@/hooks/helpers/useStructures"; import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { BattleSide } from "@bibliothecadao/eternum"; import { useMemo } from "react"; import { Battle } from "./Battle"; @@ -14,7 +15,7 @@ export const BattleView = () => { const armiesByBattleId = getArmiesByBattleId(); const { getAliveArmy } = getArmyByEntityId(); - const currentTimestamp = useUIStore((state) => state.nextBlockTimestamp); + const { nextBlockTimestamp: currentTimestamp } = useNextBlockTimestamp(); const battleView = useUIStore((state) => state.battleView); const selectedHex = useUIStore((state) => state.selectedHex); diff --git a/client/src/ui/modules/navigation/TopLeftNavigation.tsx b/client/src/ui/modules/navigation/TopLeftNavigation.tsx index 0d992e3d0..d8e6751d0 100644 --- a/client/src/ui/modules/navigation/TopLeftNavigation.tsx +++ b/client/src/ui/modules/navigation/TopLeftNavigation.tsx @@ -4,6 +4,7 @@ import { useEntities, useEntitiesUtils } from "@/hooks/helpers/useEntities"; import { useQuery } from "@/hooks/helpers/useQuery"; import { useUnclaimedQuestsCount } from "@/hooks/helpers/useQuests"; import useUIStore from "@/hooks/store/useUIStore"; +import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { soundSelector, useUiSounds } from "@/hooks/useUISound"; import { Position } from "@/types/Position"; import { NavigateToPositionIcon } from "@/ui/components/military/ArmyChip"; @@ -100,13 +101,12 @@ export const TopLeftNavigation = memo(() => { const { playerStructures } = useEntities(); const { getEntityInfo } = useEntitiesUtils(); const structures = playerStructures(); - - const isSpectatorMode = useUIStore((state) => state.isSpectatorMode); const structureEntityId = useUIStore((state) => state.structureEntityId); const setPreviewBuilding = useUIStore((state) => state.setPreviewBuilding); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp)!; + const { nextBlockTimestamp } = useNextBlockTimestamp(); + const setTooltip = useUIStore((state) => state.setTooltip); const [favorites, setFavorites] = useState(() => { @@ -336,7 +336,8 @@ TopLeftNavigation.displayName = "TopLeftNavigation"; const TickProgress = () => { const setTooltip = useUIStore((state) => state.setTooltip); - const nextBlockTimestamp = useUIStore((state) => state.nextBlockTimestamp)!; + const { nextBlockTimestamp } = useNextBlockTimestamp(); + const cycleTime = configManager.getTick(TickIds.Armies); const { play } = useUiSounds(soundSelector.gong); @@ -358,26 +359,27 @@ const TickProgress = () => { }, [progress, play]); // Memoize tooltip content - const tooltipContent = useMemo(() => ( -
-
- A day in Eternum is {formatTime(cycleTime)} -
-
- Time left until next cycle:{" "} - - {formatTime(cycleTime - (nextBlockTimestamp % cycleTime))} - + const tooltipContent = useMemo( + () => ( +
+
+ A day in Eternum is {formatTime(cycleTime)} +
+
+ Time left until next cycle:{" "} + {formatTime(cycleTime - (nextBlockTimestamp % cycleTime))} +
-
- ), [cycleTime, nextBlockTimestamp]); + ), + [cycleTime, nextBlockTimestamp], + ); // Handle tooltip visibility const handleMouseEnter = useCallback(() => { setIsTooltipOpen(true); setTooltip({ position: "bottom", - content: tooltipContent + content: tooltipContent, }); }, [setTooltip, tooltipContent]); @@ -389,7 +391,7 @@ const TickProgress = () => { return (