Skip to content

Commit

Permalink
next into main (#2463)
Browse files Browse the repository at this point in the history
* Add confirmation step to destroy building

* raise limits and remove chat (#2435)

* loading page loading itmes (#2436)

* loaf-opti

* buildings

* load

* push config

* loading

* fix for 0 donkey bridge, base manifest on chain env

* tiles

* merge

* do sync

* bank

* market

* bump

* queries

* reintroduce syncing and fetching

* sync and get happening again

* working multi bridge out step 2, fix transaction success states

* tiles

* remove logging

* memo

* world

* set loading state

* chunk

* coords

* as

* bunk

* bridge styling

* update

* update dojo version

* update dojo sync

* Fix hyperstructures

* fix

* add back chat

* a

* llint

* ✨ Add sub to all player structures

* fix(social): get name from address directly

* chore: add has not settled realm yet

* undefined if no realm found

* pretty

* fix: trade history crash

* 🐛 Fix

* config

* add realm select border animation

* hovered frag mine

* hs cost (#2443)

* hs cost

* fix deposit arrival

* update lock

* load

* Fix/army stamina (#2448)

* Fix current tick values in nextBlockTimestamp

* lint

* Remove quest UI while syncing (#2449)

* Remove quest UI while syncing

* Add quest load animation

* Raschel-dev (#2447)

* hs cost

* fix deposit arrival

* update lock

* fix hs crash

* building cost config

* fix namespace

* remove resource cost syncing

* added production

* fix costs

* add upgrade

* trigger

* remove events

* fix tile

* fixes

* remove loading

* fix: transfer view styling bug (#2451)

* Fix social tribe crash (#2450)

* fix build

* fix market

* add lords to controller on landing

* feat: optimise event messages (#2455)

* optimize events

* fix getSyncEvents composite

* small fixes

* 🐛 Fix mainnet torii cfg

* Fix laggy social search

* landing page + quest + inventory (#2461)

* update inventory

* more discrete quest loading

* fix landing page sync

---------

Co-authored-by: Bob <[email protected]>
Co-authored-by: tedison <[email protected]>
Co-authored-by: ponderingdemocritus <[email protected]>
Co-authored-by: tedison <[email protected]>
Co-authored-by: RedBeardEth <[email protected]>
Co-authored-by: Loaf <[email protected]>
Co-authored-by: bal7hazar <[email protected]>
Co-authored-by: Nasr <[email protected]>
Co-authored-by: Larko <[email protected]>
Co-authored-by: 0x1337 <[email protected]>
Co-authored-by: Bob <[email protected]>
Co-authored-by: zabanyat.eth <[email protected]>
  • Loading branch information
13 people authored Dec 12, 2024
1 parent ad15efe commit 2c6bbf1
Show file tree
Hide file tree
Showing 16 changed files with 411 additions and 136 deletions.
75 changes: 54 additions & 21 deletions client/src/ui/components/resources/InventoryResources.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { addToSubscription } from "@/dojo/queries";
import { useDojo } from "@/hooks/context/DojoContext";
import { useResourceBalance, useResourcesUtils } from "@/hooks/helpers/useResources";
import { ResourceCost } from "@/ui/elements/ResourceCost";
import { divideByPrecision } from "@/ui/utils/utils";
import { ID, Resource, ResourcesIds } from "@bibliothecadao/eternum";
import { useMemo, useState } from "react";
import { useEffect, useMemo, useState } from "react";

export const InventoryResources = ({
entityId,
Expand All @@ -19,18 +21,47 @@ export const InventoryResources = ({
resourcesIconSize?: "xs" | "sm" | "md" | "lg";
textSize?: "xxs" | "xs" | "sm" | "md" | "lg";
}) => {
const dojo = useDojo();

const [showAll, setShowAll] = useState(false);
const { useResourcesFromBalance } = useResourcesUtils();
const { getBalance } = useResourceBalance();

const inventoriesResources = useResourcesFromBalance(entityId);

const dynamicResources = dynamic.map(
(resourceId): Resource => ({ resourceId, amount: getBalance(entityId, resourceId).balance }),
const [isSyncing, setIsSyncing] = useState(false);

const dynamicResources = useMemo(
() => dynamic.map((resourceId): Resource => ({ resourceId, amount: getBalance(entityId, resourceId).balance })),
[dynamic, entityId, getBalance],
);

useEffect(() => {
if (inventoriesResources.length === 0) {
setIsSyncing(true);
const fetch = async () => {
try {
await addToSubscription(
dojo.network.toriiClient,
dojo.network.contractComponents as any,
entityId.toString(),
);
} catch (error) {
console.error("Fetch failed", error);
} finally {
setIsSyncing(false);
}
};
fetch();
}
}, [inventoriesResources.length, entityId]);

const allResources = [...inventoriesResources, ...dynamicResources];

const sortedResources = useMemo(() => {
return allResources.sort((a, b) => b.amount - a.amount);
}, [allResources]);

const updatedMax = useMemo(() => {
if (showAll) return Infinity;
return max;
Expand All @@ -39,25 +70,27 @@ export const InventoryResources = ({
const maxResources = updatedMax - dynamicResources.length;
let currentCount = 0;

return allResources.length > 0 ? (
return isSyncing ? (
<div className={`p-2 bg-gold/10 ${className}`}>
{allResources
.sort((a, b) => b.amount - a.amount)
.map((resource) => {
if (!resource || currentCount >= maxResources) return null;
currentCount++;
return (
<ResourceCost
size={resourcesIconSize}
textSize={textSize}
key={resource.resourceId}
type="vertical"
color="text-green"
resourceId={resource.resourceId}
amount={divideByPrecision(Number(resource.amount))}
/>
);
})}
<div className="text-gold/50 italic">Loading resources...</div>
</div>
) : allResources.length > 0 ? (
<div className={`p-2 bg-gold/10 ${className}`}>
{sortedResources.map((resource) => {
if (!resource || currentCount >= maxResources) return null;
currentCount++;
return (
<ResourceCost
size={resourcesIconSize}
textSize={textSize}
key={resource.resourceId}
type="vertical"
color="text-green"
resourceId={resource.resourceId}
amount={divideByPrecision(Number(resource.amount))}
/>
);
})}
<div className="ml-1 font-bold hover:opacity-70">
{updatedMax < inventoriesResources.length && !showAll && (
<div onClick={() => setShowAll(true)}>+{inventoriesResources.length - updatedMax}</div>
Expand Down
61 changes: 38 additions & 23 deletions client/src/ui/components/worldmap/players/PlayersPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useDojo } from "@/hooks/context/DojoContext";
import { useGetAllPlayers } from "@/hooks/helpers/use-get-all-players";
import { useEntitiesUtils } from "@/hooks/helpers/useEntities";
import { useGuilds } from "@/hooks/helpers/useGuilds";
import Button from "@/ui/elements/Button";
import TextInput from "@/ui/elements/TextInput";
import { getEntityIdFromKeys, toHexString } from "@/ui/utils/utils";
import { ContractAddress, Player } from "@bibliothecadao/eternum";
import { Has, HasValue, getComponentValue, runQuery } from "@dojoengine/recs";
import { useMemo, useState } from "react";
import { KeyboardEvent, useMemo, useState } from "react";
import { PlayerCustom, PlayerList } from "./PlayerList";

export const PlayersPanel = ({
Expand All @@ -25,15 +25,12 @@ export const PlayersPanel = ({
} = useDojo();

const { getGuildFromPlayerAddress } = useGuilds();

const { getEntityName } = useEntitiesUtils();
const userGuild = getGuildFromPlayerAddress(ContractAddress(account.address));

const [isLoading, setIsLoading] = useState(false);

const [searchInput, setSearchInput] = useState("");

const { getEntityName } = useEntitiesUtils();
const getPlayers = useGetAllPlayers();
const [inputValue, setInputValue] = useState("");
const [searchTerm, setSearchTerm] = useState("");

const playersWithStructures: PlayerCustom[] = useMemo(() => {
// Sort players by points in descending order
Expand All @@ -52,7 +49,7 @@ export const PlayersPanel = ({
const structureName = getEntityName(structure.entity_id);
return structureName;
})
.filter((structure) => structure !== undefined);
.filter((structure): structure is string => structure !== undefined);

const guild = getGuildFromPlayerAddress(player.address);

Expand All @@ -73,18 +70,22 @@ export const PlayersPanel = ({
};
});
return playersWithStructures;
}, [getPlayers, isLoading]);
}, [isLoading]);

const filteredPlayers = useMemo(() => {
return playersWithStructures.filter(
(player) =>
player.name.toLowerCase().includes(searchInput.toLowerCase()) ||
player.structures.some(
(structure) => structure && structure.toLowerCase().includes(searchInput.toLowerCase()),
) ||
toHexString(player.address).toLowerCase().includes(searchInput.toLowerCase()),
);
}, [playersWithStructures, searchInput]);
const term = searchTerm.toLowerCase();
return searchTerm === ""
? playersWithStructures
: playersWithStructures.filter((player) => {
const nameMatch = player.name.toLowerCase().includes(term);
if (nameMatch) return true;

const addressMatch = toHexString(player.address).toLowerCase().includes(term);
if (addressMatch) return true;

return player.structures.some((structure) => structure && structure.toLowerCase().includes(term));
});
}, [playersWithStructures, searchTerm]);

const whitelistPlayer = (address: ContractAddress) => {
setIsLoading(true);
Expand All @@ -104,17 +105,31 @@ export const PlayersPanel = ({
}).finally(() => setIsLoading(false));
};

const handleSearch = () => {
setSearchTerm(inputValue);
};

const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter") {
handleSearch();
}
};

return (
<div className="flex flex-col min-h-72 p-2 h-full w-full overflow-hidden">
<div>
<div className="flex gap-2 mb-4">
<TextInput
placeholder="Search players/realms/structures..."
onChange={(searchInput) => setSearchInput(searchInput)}
className="mb-4"
onChange={(value) => setInputValue(value)}
onKeyDown={handleKeyDown}
className="flex-1"
/>
<Button onClick={handleSearch} variant="primary">
Search
</Button>
</div>

<div className="flex-1 min-h-0 ">
<div className="flex-1 min-h-0">
<PlayerList
players={filteredPlayers}
viewPlayerInfo={viewPlayerInfo}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ 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 { StructureType } from "@bibliothecadao/eternum";
import clsx from "clsx";
import { useMemo } from "react";
import { TroopDisplay } from "../../military/TroopChip";
Expand Down Expand Up @@ -187,9 +187,6 @@ export const StructureListItem = ({
entityId={structure.entity_id}
className="flex gap-1 h-14 mt-2 overflow-x-auto no-scrollbar"
resourcesIconSize="xs"
dynamic={
structure.category === StructureType[StructureType.FragmentMine] ? [ResourcesIds.AncientFragment] : []
}
/>
</div>
</div>
Expand Down
68 changes: 51 additions & 17 deletions client/src/ui/modules/navigation/QuestMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useDojo } from "@/hooks/context/DojoContext";
import { Prize, QuestStatus, useQuests } from "@/hooks/helpers/useQuests";
import { useRealm } from "@/hooks/helpers/useRealm";
import useUIStore from "@/hooks/store/useUIStore";
import { useWorldStore } from "@/hooks/store/useWorldLoading";
import { useStartingTutorial } from "@/hooks/use-starting-tutorial";
import { questSteps, useTutorial } from "@/hooks/use-tutorial";
import Button from "@/ui/elements/Button";
Expand All @@ -18,6 +19,8 @@ export const QuestsMenu = ({ unclaimedQuestsCount }: { unclaimedQuestsCount: num
},
} = useDojo();

const worldLoading = useWorldStore((state) => state.isWorldLoading);

useStartingTutorial();

const { quests } = useQuests();
Expand Down Expand Up @@ -75,6 +78,8 @@ export const QuestsMenu = ({ unclaimedQuestsCount }: { unclaimedQuestsCount: num
};

const handleClaimMouseEnter = (e: React.MouseEvent<HTMLButtonElement>) => {
if (worldLoading) return;

const rect = e.currentTarget.getBoundingClientRect();
const tooltipWidth = 300;

Expand All @@ -97,20 +102,24 @@ export const QuestsMenu = ({ unclaimedQuestsCount }: { unclaimedQuestsCount: num
};

return (
<div className="flex gap-2 bg-brown/90 border border-gold/30 rounded-full px-4 h-10 md:h-12 py-2">
<div
className={clsx("flex gap-2 bg-brown/90 border border-gold/30 rounded-full px-4 h-10 md:h-12 py-2", {
"opacity-50 pointer-events-none": worldLoading,
})}
>
<Button
variant="outline"
isLoading={isLoading}
className={clsx("claim-selector text-sm !font-bold capitalize", {
"!border-gold/70 !text-brown !bg-gold hover:!bg-gold/70 animate-pulse hover:animate-none":
currentQuest?.status === QuestStatus.Completed,
currentQuest?.status === QuestStatus.Completed && !worldLoading,
})}
onClick={handleClaimQuest}
onMouseEnter={handleClaimMouseEnter}
onMouseLeave={() => setTooltip(null)}
disabled={currentQuest?.status !== QuestStatus.Completed}
onMouseLeave={() => !worldLoading && setTooltip(null)}
disabled={currentQuest?.status !== QuestStatus.Completed || worldLoading}
>
Claim
{worldLoading ? "Loading..." : "Claim"}
</Button>

<div className="h-full flex items-center">
Expand All @@ -120,16 +129,21 @@ export const QuestsMenu = ({ unclaimedQuestsCount }: { unclaimedQuestsCount: num
<Button
onClick={() => handleStart()}
variant="outline"
disabled={currentQuest?.status === QuestStatus.Completed && currentQuest.id !== QuestType.Settle}
disabled={
(currentQuest?.status === QuestStatus.Completed && currentQuest.id !== QuestType.Settle) || worldLoading
}
className={clsx("tutorial-selector relative text-sm capitalize", {
"!border-gold/70 !text-brown !bg-gold hover:!bg-gold/70 animate-pulse hover:animate-none":
currentQuest?.status !== QuestStatus.Completed,
currentQuest?.status !== QuestStatus.Completed && !worldLoading,
})}
>
<span className="font-semibold">{currentQuest?.name}</span>
<span className="font-semibold">{worldLoading ? "Loading..." : currentQuest?.name}</span>
<div
className={clsx(
"absolute animate-bounce rounded-full border border-green/30 bg-green/90 text-brown px-1.5 md:px-2 text-[0.6rem] md:text-xxs z-[100] font-bold -top-1 -right-1",
"absolute rounded-full border border-green/30 bg-green/90 text-brown px-1.5 md:px-2 text-[0.6rem] md:text-xxs z-[100] font-bold -top-1 -right-1",
{
"animate-bounce": !worldLoading,
},
)}
>
{unclaimedQuestsCount}
Expand All @@ -142,19 +156,39 @@ export const QuestsMenu = ({ unclaimedQuestsCount }: { unclaimedQuestsCount: num

{skipQuest ? (
<div className="flex flex-row gap-4">
<Button className="text-sm font-semibold capitalize" onClick={handleClaimAllQuests} variant="red">
Skip All Quests
<Button
className="text-sm font-semibold capitalize"
onClick={handleClaimAllQuests}
variant="red"
disabled={worldLoading}
>
{worldLoading ? "Loading..." : "Skip All Quests"}
</Button>
<Button className="text-sm font-semibold capitalize" onClick={handleClaimQuest} variant="red">
Confirm
<Button
className="text-sm font-semibold capitalize"
onClick={handleClaimQuest}
variant="red"
disabled={worldLoading}
>
{worldLoading ? "Loading..." : "Confirm"}
</Button>
<Button variant="primary" className="text-sm font-semibold capitalize" onClick={() => setSkipQuest(false)}>
Cancel
<Button
variant="primary"
className="text-sm font-semibold capitalize"
onClick={() => setSkipQuest(false)}
disabled={worldLoading}
>
{worldLoading ? "Loading..." : "Cancel"}
</Button>
</div>
) : (
<Button variant="primary" className="text-sm font-semibold capitalize w-6" onClick={() => setSkipQuest(true)}>
Skip
<Button
variant="primary"
className="text-sm font-semibold capitalize w-6"
onClick={() => setSkipQuest(true)}
disabled={worldLoading}
>
{worldLoading ? "..." : "Skip"}
</Button>
)}
</div>
Expand Down
Loading

0 comments on commit 2c6bbf1

Please sign in to comment.