From d9f88828bd96dae48a56d102ebc6b21b769d89fb Mon Sep 17 00:00:00 2001 From: ponderingdemocritus Date: Fri, 20 Dec 2024 10:09:14 +1100 Subject: [PATCH] try --- .../hooks/helpers/use-resource-arrivals.tsx | 9 +-- .../components/trading/ResourceArrivals.tsx | 28 +++++--- client/src/ui/containers/BaseContainer.tsx | 72 ++++++++++--------- client/src/ui/containers/BattleContainer.tsx | 6 +- .../ui/containers/BlankOverlayContainer.tsx | 6 +- .../ui/containers/BottomMiddleContainer.tsx | 6 +- .../ui/containers/BottomRightContainer.tsx | 6 +- .../src/ui/containers/LeftMiddleContainer.tsx | 6 +- .../ui/containers/RightMiddleContainer.tsx | 6 +- .../src/ui/containers/TopCenterContainer.tsx | 6 +- client/src/ui/containers/TopLeftContainer.tsx | 6 +- client/src/ui/layouts/World.tsx | 23 ++++-- .../military/battle-view/BattleView.tsx | 6 +- .../modules/navigation/TopLeftNavigation.tsx | 6 +- 14 files changed, 109 insertions(+), 83 deletions(-) diff --git a/client/src/hooks/helpers/use-resource-arrivals.tsx b/client/src/hooks/helpers/use-resource-arrivals.tsx index 053e5e142..dfb205ee5 100644 --- a/client/src/hooks/helpers/use-resource-arrivals.tsx +++ b/client/src/hooks/helpers/use-resource-arrivals.tsx @@ -39,14 +39,11 @@ const usePlayerArrivals = () => { HasValue(Owner, { address: ContractAddress(account.address) }), ]); - const [playerStructurePositions, setPlayerStructurePositions] = useState<(Position & { entityId: ID })[]>([]); - - useEffect(() => { - const positions = playerStructures.map((entityId) => { + const playerStructurePositions = useMemo(() => { + return playerStructures.map((entityId) => { const position = getComponentValue(Position, entityId); return { x: position?.x ?? 0, y: position?.y ?? 0, entityId: position?.entity_id || 0 }; }); - setPlayerStructurePositions(positions); }, [playerStructures, Position]); const [entitiesWithInventory, setEntitiesWithInventory] = useState([]); @@ -62,8 +59,6 @@ const usePlayerArrivals = () => { const arrivals = positions.flatMap((position) => { return Array.from(runQuery([HasValue(Position, { x: position.x, y: position.y }), ...queryFragments])); }); - - console.log("arrivals", arrivals); return arrivals; }, []); diff --git a/client/src/ui/components/trading/ResourceArrivals.tsx b/client/src/ui/components/trading/ResourceArrivals.tsx index d12b766f1..346ffd570 100644 --- a/client/src/ui/components/trading/ResourceArrivals.tsx +++ b/client/src/ui/components/trading/ResourceArrivals.tsx @@ -3,14 +3,28 @@ import { useDojo } from "@/hooks/context/DojoContext"; import { ArrivalInfo } from "@/hooks/helpers/use-resource-arrivals"; import { Headline } from "@/ui/elements/Headline"; import { HintModalButton } from "@/ui/elements/HintModalButton"; -import { memo, useEffect, useState } from "react"; +import { memo, useEffect } from "react"; +import { create } from "zustand"; import { EntityArrival } from "../entities/Entity"; import { HintSection } from "../hints/HintModal"; +interface SubscribedIdsStore { + subscribedIds: Set; + addSubscribedIds: (ids: string[]) => void; +} + +const useSubscribedIdsStore = create((set) => ({ + subscribedIds: new Set(), + addSubscribedIds: (ids) => + set((state) => ({ + subscribedIds: new Set([...state.subscribedIds, ...ids]), + })), +})); + export const AllResourceArrivals = memo( ({ arrivals, className = "" }: { arrivals: ArrivalInfo[]; className?: string }) => { const dojo = useDojo(); - const [subscribedIds, setSubscribedIds] = useState>(new Set()); + const { subscribedIds, addSubscribedIds } = useSubscribedIdsStore(); useEffect(() => { // Create a single Set from newIds for O(1) lookup @@ -21,19 +35,15 @@ export const AllResourceArrivals = memo( if (unsubscribedIds.length === 0) return; - // Batch the state update with the API call - setSubscribedIds((prev) => { - // If nothing changed, return the previous state to prevent re-render - if (unsubscribedIds.every((id) => prev.has(id))) return prev; - return new Set([...prev, ...unsubscribedIds]); - }); + // Update zustand store + addSubscribedIds(unsubscribedIds); // Move API call outside of state updates addToSubscription(dojo.network.toriiClient, dojo.network.contractComponents as any, unsubscribedIds).catch( (error) => console.error("Fetch failed", error), ); console.log("AddToSubscriptionStart - 5"); - }, [arrivals, subscribedIds]); + }, [arrivals, subscribedIds, addSubscribedIds]); return (
diff --git a/client/src/ui/containers/BaseContainer.tsx b/client/src/ui/containers/BaseContainer.tsx index 58b6985f7..01130d30d 100644 --- a/client/src/ui/containers/BaseContainer.tsx +++ b/client/src/ui/containers/BaseContainer.tsx @@ -1,7 +1,7 @@ import { ReactComponent as Collapse } from "@/assets/icons/common/collapse.svg"; import { ReactComponent as Expand } from "@/assets/icons/common/expand.svg"; import clsx from "clsx"; -import { forwardRef, ReactNode, useState } from "react"; +import { forwardRef, memo, ReactNode, useState } from "react"; interface BaseContainerProps { children?: ReactNode; @@ -11,38 +11,40 @@ interface BaseContainerProps { collapsedClassName?: string; scrollbarSide?: "left" | "right"; } -export const BaseContainer = forwardRef( - ( - { children, className, expandable, expandedClassName, collapsedClassName, scrollbarSide }: BaseContainerProps, - ref, - ) => { - const [expanded, setExpanded] = useState(false); - return ( -
- {children} - {expandable && - (expanded ? ( - setExpanded(false)} - className="absolute w-4 h-4 transition-colors duration-200 cursor-pointer top-4 right-4 fill-gold hover:fill-white" - /> - ) : ( - setExpanded(true)} - className="absolute w-4 h-4 transition-colors duration-200 cursor-pointer top-4 right-4 fill-gold hover:fill-white" - /> - ))} -
- ); - }, +export const BaseContainer = memo( + forwardRef( + ( + { children, className, expandable, expandedClassName, collapsedClassName, scrollbarSide }: BaseContainerProps, + ref, + ) => { + const [expanded, setExpanded] = useState(false); + return ( +
+ {children} + {expandable && + (expanded ? ( + setExpanded(false)} + className="absolute w-4 h-4 transition-colors duration-200 cursor-pointer top-4 right-4 fill-gold hover:fill-white" + /> + ) : ( + setExpanded(true)} + className="absolute w-4 h-4 transition-colors duration-200 cursor-pointer top-4 right-4 fill-gold hover:fill-white" + /> + ))} +
+ ); + }, + ), ); diff --git a/client/src/ui/containers/BattleContainer.tsx b/client/src/ui/containers/BattleContainer.tsx index 99ead1cd5..4d7ecb591 100644 --- a/client/src/ui/containers/BattleContainer.tsx +++ b/client/src/ui/containers/BattleContainer.tsx @@ -1,7 +1,7 @@ import useUIStore from "@/hooks/store/useUIStore"; -import { useEffect } from "react"; +import { memo, useEffect } from "react"; -export const BattleContainer = ({ children }: { children: React.ReactNode }) => { +export const BattleContainer = memo(({ children }: { children: React.ReactNode }) => { const setBattleView = useUIStore((state) => state.setBattleView); const battleView = useUIStore((state) => state.battleView); @@ -26,4 +26,4 @@ export const BattleContainer = ({ children }: { children: React.ReactNode }) => {children}
); -}; +}); diff --git a/client/src/ui/containers/BlankOverlayContainer.tsx b/client/src/ui/containers/BlankOverlayContainer.tsx index abdabe54c..d192400bd 100644 --- a/client/src/ui/containers/BlankOverlayContainer.tsx +++ b/client/src/ui/containers/BlankOverlayContainer.tsx @@ -1,12 +1,12 @@ import { Transition } from "@headlessui/react"; -import React, { Fragment } from "react"; +import { Fragment, memo } from "react"; type BlurOverlayContainerProps = { children?: React.ReactNode; open: boolean; } & React.HTMLAttributes; -export const BlankOverlayContainer = ({ children, open }: BlurOverlayContainerProps) => { +export const BlankOverlayContainer = memo(({ children, open }: BlurOverlayContainerProps) => { return ( ); -}; +}); diff --git a/client/src/ui/containers/BottomMiddleContainer.tsx b/client/src/ui/containers/BottomMiddleContainer.tsx index 9d5dcc8e8..c0cac11c7 100644 --- a/client/src/ui/containers/BottomMiddleContainer.tsx +++ b/client/src/ui/containers/BottomMiddleContainer.tsx @@ -1,7 +1,9 @@ -export const BottomMiddleContainer = ({ children }: { children: React.ReactNode }) => { +import { memo } from "react"; + +export const BottomMiddleContainer = memo(({ children }: { children: React.ReactNode }) => { return (
{children}
); -}; +}); diff --git a/client/src/ui/containers/BottomRightContainer.tsx b/client/src/ui/containers/BottomRightContainer.tsx index a367e9945..efa5787e5 100644 --- a/client/src/ui/containers/BottomRightContainer.tsx +++ b/client/src/ui/containers/BottomRightContainer.tsx @@ -1,9 +1,9 @@ -import { ReactNode } from "react"; +import { ReactNode, memo } from "react"; interface BottomRightContainerProps { children?: ReactNode; } -export const BottomRightContainer = ({ children }: BottomRightContainerProps) => { +export const BottomRightContainer = memo(({ children }: BottomRightContainerProps) => { return
{children}
; -}; +}); diff --git a/client/src/ui/containers/LeftMiddleContainer.tsx b/client/src/ui/containers/LeftMiddleContainer.tsx index 4fbb608d5..96dbc0b2b 100644 --- a/client/src/ui/containers/LeftMiddleContainer.tsx +++ b/client/src/ui/containers/LeftMiddleContainer.tsx @@ -1,7 +1,9 @@ -const LeftMiddleContainer = ({ children }: { children: React.ReactNode }) => { +import { memo } from "react"; + +const LeftMiddleContainer = memo(({ children }: { children: React.ReactNode }) => { return (
{children}
); -}; +}); export default LeftMiddleContainer; diff --git a/client/src/ui/containers/RightMiddleContainer.tsx b/client/src/ui/containers/RightMiddleContainer.tsx index 77db6dd35..c101c5adb 100644 --- a/client/src/ui/containers/RightMiddleContainer.tsx +++ b/client/src/ui/containers/RightMiddleContainer.tsx @@ -1,5 +1,7 @@ -const RightMiddleContainer = ({ children }: { children: React.ReactNode }) => { +import { memo } from "react"; + +const RightMiddleContainer = memo(({ children }: { children: React.ReactNode }) => { return
{children}
; -}; +}); export default RightMiddleContainer; diff --git a/client/src/ui/containers/TopCenterContainer.tsx b/client/src/ui/containers/TopCenterContainer.tsx index a4e004138..269ddb518 100644 --- a/client/src/ui/containers/TopCenterContainer.tsx +++ b/client/src/ui/containers/TopCenterContainer.tsx @@ -1,5 +1,7 @@ -const TopCenterContainer = ({ children }: { children: React.ReactNode }) => { +import { memo } from "react"; + +const TopCenterContainer = memo(({ children }: { children: React.ReactNode }) => { return
{children}
; -}; +}); export default TopCenterContainer; diff --git a/client/src/ui/containers/TopLeftContainer.tsx b/client/src/ui/containers/TopLeftContainer.tsx index 53c01524e..71dd252f4 100644 --- a/client/src/ui/containers/TopLeftContainer.tsx +++ b/client/src/ui/containers/TopLeftContainer.tsx @@ -1,5 +1,7 @@ -const TopLeftContainer = ({ children }: { children: React.ReactNode }) => { +import { memo } from "react"; + +const TopLeftContainer = memo(({ children }: { children: React.ReactNode }) => { return
{children}
; -}; +}); export default TopLeftContainer; diff --git a/client/src/ui/layouts/World.tsx b/client/src/ui/layouts/World.tsx index 22a06988e..8461b484b 100644 --- a/client/src/ui/layouts/World.tsx +++ b/client/src/ui/layouts/World.tsx @@ -93,10 +93,8 @@ export const World = ({ backgroundImage }: { backgroundImage: string }) => { const [subscriptions, setSubscriptions] = useState<{ [entity: string]: boolean }>({}); const showBlankOverlay = useUIStore((state) => state.showBlankOverlay); const isLoadingScreenEnabled = useUIStore((state) => state.isLoadingScreenEnabled); - const showModal = useUIStore((state) => state.showModal); const modalContent = useUIStore((state) => state.modalContent); - const battleView = useUIStore((state) => state.battleView); // Setup hooks @@ -199,6 +197,21 @@ export const World = ({ backgroundImage }: { backgroundImage: string }) => { } }, []); + const battleViewContent = useMemo( + () => ( +
+ }> + {battleView && ( + + + + )} + +
+ ), + [battleView], + ); + return (
{ @@ -232,9 +245,7 @@ export const World = ({ backgroundImage }: { backgroundImage: string }) => { )} - - - + {battleViewContent}
@@ -261,7 +272,7 @@ export const World = ({ backgroundImage }: { backgroundImage: string }) => { )} - +
diff --git a/client/src/ui/modules/military/battle-view/BattleView.tsx b/client/src/ui/modules/military/battle-view/BattleView.tsx index d9985125e..2c38e8e80 100644 --- a/client/src/ui/modules/military/battle-view/BattleView.tsx +++ b/client/src/ui/modules/military/battle-view/BattleView.tsx @@ -6,10 +6,10 @@ import { Structure, useStructureByEntityId, useStructureByPosition } from "@/hoo import useUIStore from "@/hooks/store/useUIStore"; import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; import { BattleSide } from "@bibliothecadao/eternum"; -import { useMemo } from "react"; +import { memo, useMemo } from "react"; import { Battle } from "./Battle"; -export const BattleView = () => { +export const BattleView = memo(() => { const dojo = useDojo(); const getStructure = useStructureByPosition(); const armiesByBattleId = getArmiesByBattleId(); @@ -148,4 +148,4 @@ export const BattleView = () => { structure={structure as Structure} /> ); -}; +}); diff --git a/client/src/ui/modules/navigation/TopLeftNavigation.tsx b/client/src/ui/modules/navigation/TopLeftNavigation.tsx index ed6befec1..ebab40085 100644 --- a/client/src/ui/modules/navigation/TopLeftNavigation.tsx +++ b/client/src/ui/modules/navigation/TopLeftNavigation.tsx @@ -1,6 +1,6 @@ import { configManager } from "@/dojo/setup"; import { useDojo } from "@/hooks/context/DojoContext"; -import { useEntities, useEntitiesUtils } from "@/hooks/helpers/useEntities"; +import { PlayerStructure, useEntitiesUtils } from "@/hooks/helpers/useEntities"; import { useQuery } from "@/hooks/helpers/useQuery"; import useUIStore from "@/hooks/store/useUIStore"; import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp"; @@ -92,13 +92,11 @@ const WorkersHutTooltipContent = () => { ); }; -export const TopLeftNavigation = memo(() => { +export const TopLeftNavigation = memo(({ structures }: { structures: PlayerStructure[] }) => { const { setup } = useDojo(); const { isMapView, handleUrlChange, hexPosition } = useQuery(); - const { playerStructures } = useEntities(); const { getEntityInfo } = useEntitiesUtils(); - const structures = playerStructures(); const isSpectatorMode = useUIStore((state) => state.isSpectatorMode); const structureEntityId = useUIStore((state) => state.structureEntityId);