Skip to content

Commit

Permalink
Merge branch 'next' of https://github.com/BibliothecaDAO/eternum into…
Browse files Browse the repository at this point in the history
… next
  • Loading branch information
aymericdelab committed Dec 20, 2024
2 parents 63b26d7 + e48ce4a commit 008c026
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 88 deletions.
16 changes: 15 additions & 1 deletion client/src/dojo/debouncedQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ToriiClient } from "@dojoengine/torii-client";
import debounce from "lodash/debounce";
import {
addArrivalsSubscription,
addHyperstructureSubscription,
addMarketSubscription,
addToSubscription,
addToSubscriptionOneKeyModelbyRealmEntityId,
Expand Down Expand Up @@ -55,7 +56,7 @@ class RequestQueue {
const positionQueue = new RequestQueue();
const subscriptionQueue = new RequestQueue();
const marketQueue = new RequestQueue();

const hyperstructureQueue = new RequestQueue();
// Debounced functions that add to queues
export const debouncedSyncPosition = debounce(
async <S extends Schema>(
Expand Down Expand Up @@ -141,9 +142,22 @@ export const debouncedAddMarketSubscription = debounce(
{ leading: true },
);

export const debouncedAddHyperstructureSubscription = debounce(
async <S extends Schema>(
client: ToriiClient,
components: Component<S, Metadata, undefined>[],
onComplete?: () => void,
) => {
await hyperstructureQueue.add(() => addHyperstructureSubscription(client, components), onComplete);
},
500,
{ leading: true },
);

// Utility function to clear all queues if needed
export const clearAllQueues = () => {
positionQueue.clear();
subscriptionQueue.clear();
marketQueue.clear();
hyperstructureQueue.clear();
};
38 changes: 38 additions & 0 deletions client/src/dojo/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,44 @@ export const addMarketSubscription = async <S extends Schema>(
console.log("MarketEnd", end - start);
};

export const addHyperstructureSubscription = async <S extends Schema>(
client: ToriiClient,
components: Component<S, Metadata, undefined>[],
) => {
const start = performance.now();
await getEntities(
client,
{
Composite: {
operator: "Or",
clauses: [
{
Keys: {
keys: [undefined, undefined],
pattern_matching: "FixedLen",
models: ["s0_eternum-Epoch", "s0_eternum-Progress"],
},
},
{
Keys: {
keys: [undefined, undefined, undefined],
pattern_matching: "FixedLen",
models: ["s0_eternum-Contribution"],
},
},
],
},
},
components as any,
[],
[],
40_000,
false,
);
const end = performance.now();
console.log("HyperstructureEnd", end - start);
};

export const addArrivalsSubscription = async <S extends Schema>(
client: ToriiClient,
components: Component<S, Metadata, undefined>[],
Expand Down
7 changes: 6 additions & 1 deletion client/src/ui/components/worldmap/players/PlayerList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,16 @@ export const PlayerList = ({
sort: "none",
});

const sortedPlayers = useMemo(
() => sortItems(players, activeSort, { sortKey: "rank", sort: "asc" }),
[players, activeSort],
);

return (
<div className="flex flex-col h-full p-2 bg-brown-900/50 border border-gold/30 rounded-xl backdrop-blur-sm">
<PlayerListHeader activeSort={activeSort} setActiveSort={setActiveSort} />
<div className="mt-4 overflow-y-auto scrollbar-thin scrollbar-thumb-gold/20 scrollbar-track-transparent">
{sortItems(players, activeSort, { sortKey: "rank", sort: "asc" }).map((player) => (
{sortedPlayers.map((player) => (
<PlayerRow
key={player.address}
player={player}
Expand Down
2 changes: 1 addition & 1 deletion client/src/ui/components/worldmap/players/PlayersPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const PlayersPanel = ({
};
});
return playersWithStructures;
}, [isLoading]);
}, [isLoading, players]);

const filteredPlayers = useMemo(() => {
const term = searchTerm.toLowerCase();
Expand Down
22 changes: 22 additions & 0 deletions client/src/ui/layouts/World.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import useUIStore from "../../hooks/store/useUIStore";

import {
debounceAddResourceArrivals,
debouncedAddHyperstructureSubscription,
debouncedAddMarketSubscription,
debouncedAddToSubscription,
debouncedAddToSubscriptionOneKey,
Expand Down Expand Up @@ -229,6 +230,27 @@ export const World = ({ backgroundImage }: { backgroundImage: string }) => {
fetch();
}, []);

useEffect(() => {
const fetch = async () => {
try {
setLoading(LoadingStateKey.Hyperstructure, true);
console.log("AddToSubscriptionStart - 4");
await Promise.all([
debouncedAddHyperstructureSubscription(dojo.network.toriiClient, dojo.network.contractComponents as any, () =>
setLoading(LoadingStateKey.Hyperstructure, false),
),
]);
} catch (error) {
console.error("Fetch failed", error);
} finally {
// Ensure loading states are reset even if there's an error
setLoading(LoadingStateKey.Hyperstructure, false);
}
};

fetch();
}, []);

const battleViewContent = useMemo(
() => (
<div>
Expand Down
4 changes: 1 addition & 3 deletions client/src/ui/modules/navigation/TopNavigation.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { useGetAllPlayers } from "@/hooks/helpers/use-get-all-players";

import { memo } from "react";
import { Rewards } from "../rewards/Rewards";
import { SettingsWindow } from "../settings/Settings";
import { Social } from "../social/Social";

export const TopMiddleNavigation = memo(() => {
const getPlayers = useGetAllPlayers();
const players = getPlayers();

return (
<>
<div className="pointer-events-auto">
<Social players={players} />
<Social getPlayers={getPlayers} />
<Rewards />
<SettingsWindow />
</div>
Expand Down
23 changes: 18 additions & 5 deletions client/src/ui/modules/social/Social.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useDojo } from "@/hooks/context/DojoContext";
import { useHyperstructureData } from "@/hooks/store/useLeaderBoardStore";
import { useHyperstructureData, useLeaderBoardStore } from "@/hooks/store/useLeaderBoardStore";
import useUIStore from "@/hooks/store/useUIStore";
import { HintSection } from "@/ui/components/hints/HintModal";
import { social } from "@/ui/components/navigation/Config";
Expand All @@ -12,11 +12,11 @@ import { Tabs } from "@/ui/elements/tab";
import { ContractAddress, ID, Player } from "@bibliothecadao/eternum";
import { useEntityQuery } from "@dojoengine/react";
import { Has } from "@dojoengine/recs";
import { useMemo, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { EndSeasonButton } from "./EndSeasonButton";
import { PlayerId } from "./PlayerId";

export const Social = ({ players }: { players: Player[] }) => {
export const Social = ({ getPlayers }: { getPlayers: () => Player[] }) => {
const {
setup: {
components: {
Expand All @@ -26,7 +26,7 @@ export const Social = ({ players }: { players: Player[] }) => {
} = useDojo();
const [selectedTab, setSelectedTab] = useState(0);
const [isExpanded, setIsExpanded] = useState(false);

const [isLoading, setIsLoading] = useState(false);
const [selectedGuild, setSelectedGuild] = useState<ID>(0);
const [selectedPlayer, setSelectedPlayer] = useState<ContractAddress>(0n);

Expand All @@ -35,8 +35,21 @@ export const Social = ({ players }: { players: Player[] }) => {

const gameEnded = useEntityQuery([Has(GameEnded)]);

const [players, setPlayers] = useState(() => getPlayers());
const playersByRank = useLeaderBoardStore((state) => state.playersByRank);

const updateLeaderboard = useHyperstructureData();

const handleUpdatePoints = () => {
setIsLoading(true);
updateLeaderboard();
};

useEffect(() => {
setPlayers(getPlayers());
setIsLoading(false);
}, [playersByRank]);

const viewGuildMembers = (guildEntityId: ID) => {
if (selectedGuild === guildEntityId) {
setSelectedPlayer(0n);
Expand Down Expand Up @@ -112,7 +125,7 @@ export const Social = ({ players }: { players: Player[] }) => {

<div className="flex justify-center gap-8">
{gameEnded.length === 0 && <EndSeasonButton />}
<Button variant="secondary" onClick={updateLeaderboard}>
<Button isLoading={isLoading} variant="secondary" onClick={handleUpdatePoints}>
Update Points
</Button>
</div>
Expand Down
78 changes: 1 addition & 77 deletions client/src/ui/modules/world-structures/WorldStructuresMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { useFragmentMines } from "@/hooks/helpers/useFragmentMines";
import { useGuilds } from "@/hooks/helpers/useGuilds";
import { useHyperstructureProgress, useHyperstructures } from "@/hooks/helpers/useHyperstructures";
import { useResourceBalance } from "@/hooks/helpers/useResources";
import useUIStore from "@/hooks/store/useUIStore";
import { LoadingStateKey } from "@/hooks/store/useWorldLoading";
import { FragmentMinePanel } from "@/ui/components/fragmentMines/FragmentMinePanel";
import { HintSection } from "@/ui/components/hints/HintModal";
import { DisplayedAccess, HyperstructurePanel } from "@/ui/components/hyperstructures/HyperstructurePanel";
Expand All @@ -20,37 +18,15 @@ import { HintModalButton } from "@/ui/elements/HintModalButton";
import { ResourceIcon } from "@/ui/elements/ResourceIcon";
import { currencyFormat, currencyIntlFormat, divideByPrecision } from "@/ui/utils/utils";
import { BattleSide, ContractAddress, ID, ResourcesIds, findResourceById } from "@bibliothecadao/eternum";
import { Metadata } from "@dojoengine/recs";
import { S } from "@dojoengine/recs/dist/types-3444e4c1";
import { getEntities } from "@dojoengine/state";
import { ToriiClient } from "@dojoengine/torii-wasm";
import { ArrowRight } from "lucide-react";
import { Component, useCallback, useEffect, useMemo, useState } from "react";
import { useCallback, useMemo, useState } from "react";
import { Tabs } from "../../elements/tab";

export const WorldStructuresMenu = ({ className }: { className?: string }) => {
const {
account: { account },
network: { toriiClient, contractComponents },
} = useDojo();

const hyperstructuresLoaded = useUIStore((state) => state.loadingStates.hyperstructure);
const setLoading = useUIStore((state) => state.setLoading);

useEffect(() => {
const fetchData = async () => {
try {
setLoading(LoadingStateKey.Hyperstructure, false),
await fetchHyperstructureData(toriiClient, contractComponents as any, hyperstructuresLoaded, () =>
setLoading(LoadingStateKey.Hyperstructure, true),
);
} catch (error) {
console.error("Failed to fetch hyperstructure data:", error);
}
};
fetchData();
}, [toriiClient, contractComponents]);

const [selectedTab, setSelectedTab] = useState(0);
const [showOnlyMine, setShowOnlyMine] = useState(false);

Expand Down Expand Up @@ -141,14 +117,6 @@ export const WorldStructuresMenu = ({ className }: { className?: string }) => {
[selectedTab, hyperstructures, fragmentMines, showOnlyMine, account.address, myHyperstructures],
);

if (hyperstructuresLoaded) {
return (
<div className="flex items-center justify-center h-full">
<div className="text-gold">Loading structures...</div>
</div>
);
}

return (
<>
<HintModalButton className="absolute top-1 right-1" section={HintSection.WorldStructures} />
Expand Down Expand Up @@ -341,47 +309,3 @@ const EntityHeader = ({ entity }: { entity: any }) => {
</div>
);
};

const fetchHyperstructureData = async (
client: ToriiClient,
components: Component<S, Metadata, undefined>[],
isStructuresLoading: boolean,
onCompleted?: () => void,
) => {
if (!isStructuresLoading) {
return;
}

console.log("Fetching hyperstructure data");
await getEntities(
client,
{
Composite: {
operator: "Or",
clauses: [
{
Keys: {
keys: [undefined, undefined],
pattern_matching: "VariableLen",
models: ["s0_eternum-Contribution"],
},
},
{
Keys: {
keys: [undefined, undefined, undefined],
pattern_matching: "VariableLen",
models: ["s0_eternum-Epoch", "s0_eternum-Progress"],
},
},
],
},
},
components as any,
[],
[],
40_000,
false,
).finally(() => {
onCompleted?.();
});
};

0 comments on commit 008c026

Please sign in to comment.