Skip to content

Commit

Permalink
landing page + quest + inventory (#2461)
Browse files Browse the repository at this point in the history
* update inventory

* more discrete quest loading

* fix landing page sync
  • Loading branch information
aymericdelab authored Dec 12, 2024
1 parent fb1892f commit a20d2a9
Show file tree
Hide file tree
Showing 12 changed files with 366 additions and 105 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
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
16 changes: 3 additions & 13 deletions client/src/ui/modules/navigation/TopLeftNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ 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 { useWorldStore } from "@/hooks/store/useWorldLoading";
import useNextBlockTimestamp from "@/hooks/useNextBlockTimestamp";
import { soundSelector, useUiSounds } from "@/hooks/useUISound";
import { Position } from "@/types/Position";
Expand Down Expand Up @@ -97,8 +96,6 @@ const WorkersHutTooltipContent = () => {
export const TopLeftNavigation = memo(() => {
const { setup } = useDojo();

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

const { unclaimedQuestsCount } = useUnclaimedQuestsCount();
const { isMapView, handleUrlChange, hexPosition } = useQuery();
const { playerStructures } = useEntities();
Expand Down Expand Up @@ -324,17 +321,10 @@ export const TopLeftNavigation = memo(() => {
</motion.div>
<div className="relative">
<SecondaryMenuItems />
{worldLoading ? (
<div className="absolute right-2 p-4 mt-2 top-full flex flex-row items-center justify-center bg-black/80 rounded-lg">
<img src="/images/eternumloader.png" className="w-10" />
<div className="ml-4">Quests are loading...</div>
{unclaimedQuestsCount > 0 && (
<div className="absolute right-0 px-4 top-full mt-2">
<QuestsMenu unclaimedQuestsCount={unclaimedQuestsCount} />
</div>
) : (
unclaimedQuestsCount > 0 && (
<div className="absolute right-0 px-4 top-full mt-2">
<QuestsMenu unclaimedQuestsCount={unclaimedQuestsCount} />
</div>
)
)}
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion landing/src/components/modules/bridge-out-step-1.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ function formatFee(fee: number) {

export const BridgeOutStep1 = () => {
const { address } = useAccount();
const [realmEntityId, setRealmEntityId] = useState<string>("");

const { getRealmNameById } = useRealm();
const { computeTravelTime } = useTravel();
const [isFeesOpen, setIsFeesOpen] = useState(false);

const [isLoading, setIsLoading] = useState(false);
const [realmEntityId, setRealmEntityId] = useState<string>("");
const { bridgeStartWithdrawFromRealm } = useBridgeAsset();
const [selectedResourceIds, setSelectedResourceIds] = useState([]);
const [selectedResourceAmounts, setSelectedResourceAmounts] = useState<{ [key: string]: number }>({});
Expand Down
Loading

0 comments on commit a20d2a9

Please sign in to comment.