Skip to content

Commit

Permalink
Fix/bob various (#2573)
Browse files Browse the repository at this point in the history
* Enable selling resources when 0 donkeys

* Add prev button for step 2 transfer

* add resource filter

* Use same resources ordering

* Fix sell order when 0 donkeys

* Remove need for diacritical marks when searching realm names

* disable construction mode for non/enemy realms
  • Loading branch information
bob0005 authored Dec 20, 2024
1 parent 8e41926 commit b4b9145
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 23 deletions.
4 changes: 2 additions & 2 deletions client/src/ui/components/trading/MarketOrderPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ const OrderRow = memo(
<ConfirmationPopup
title="Confirm Trade"
onConfirm={onAccept}
disabled={donkeysNeeded > donkeyBalance || donkeyBalance === 0}
disabled={!isBuy && donkeysNeeded > donkeyBalance}
onCancel={() => {
setConfirmOrderModal(false);
}}
Expand Down Expand Up @@ -600,7 +600,7 @@ const OrderCreation = memo(

const enoughDonkeys = useMemo(() => {
if (resourceId === ResourcesIds.Donkey) return true;
return donkeyBalance > donkeysNeeded;
return donkeyBalance >= donkeysNeeded;
}, [donkeyBalance, donkeysNeeded, resourceId]);

return (
Expand Down
25 changes: 20 additions & 5 deletions client/src/ui/components/trading/SelectResources.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ListSelect from "@/ui/elements/ListSelect";
import { NumberInput } from "@/ui/elements/NumberInput";
import { ResourceCost } from "@/ui/elements/ResourceCost";
import { divideByPrecision } from "@/ui/utils/utils";
import { ID, resources } from "@bibliothecadao/eternum";
import { ID, RESOURCE_TIERS, ResourcesIds, resources } from "@bibliothecadao/eternum";
import { useMemo } from "react";

export const SelectResources = ({
Expand All @@ -24,8 +24,18 @@ export const SelectResources = ({
const { getBalance } = useResourceBalance();
const { playResourceSound } = usePlayResourceSound();

const orderedResources = useMemo(() => {
return Object.values(RESOURCE_TIERS)
.flat()
.filter((resourceId) => resourceId !== ResourcesIds.Lords)
.map((resourceId) => ({
id: resourceId,
trait: ResourcesIds[resourceId],
}));
}, []);

const unselectedResources = useMemo(
() => resources.filter((res) => !selectedResourceIds.includes(res.id)),
() => orderedResources.filter((res) => !selectedResourceIds.includes(res.id)),
[selectedResourceIds],
);

Expand All @@ -39,10 +49,11 @@ export const SelectResources = ({
};

return (
<div className=" items-center col-span-4 space-y-2 p-3">
<div className="items-center col-span-4 space-y-2 p-3">
{selectedResourceIds.map((id: any, index: any) => {
const resource = getBalance(entity_id, id);
const options = [resources.find((res) => res.id === id), ...unselectedResources].map((res: any) => ({

const options = [orderedResources.find((res) => res.id === id), ...unselectedResources].map((res: any) => ({
id: res.id,
label: (
<ResourceCost resourceId={res.id} amount={divideByPrecision(getBalance(entity_id, res.id)?.balance || 0)} />
Expand All @@ -65,7 +76,10 @@ export const SelectResources = ({
</Button>
)}
<ListSelect
options={options}
options={options.map((option) => ({
...option,
searchText: resources.find((res) => res.id === option.id)?.trait,
}))}
value={selectedResourceIds[index]}
onChange={(value) => {
const updatedResourceIds = [...selectedResourceIds];
Expand All @@ -77,6 +91,7 @@ export const SelectResources = ({
});
playResourceSound(value);
}}
enableFilter={true}
/>
<NumberInput
className="h-14 "
Expand Down
20 changes: 15 additions & 5 deletions client/src/ui/components/trading/TransferBetweenEntities.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Button from "@/ui/elements/Button";
import { Checkbox } from "@/ui/elements/Checkbox";
import { Headline } from "@/ui/elements/Headline";
import TextInput from "@/ui/elements/TextInput";
import { multiplyByPrecision } from "@/ui/utils/utils";
import { multiplyByPrecision, normalizeDiacriticalMarks } from "@/ui/utils/utils";
import { DONKEY_ENTITY_TYPE, ID } from "@bibliothecadao/eternum";
import { ArrowRight, LucideArrowRight } from "lucide-react";
import { memo, useEffect, useMemo, useState } from "react";
Expand Down Expand Up @@ -76,11 +76,13 @@ const SelectEntitiesStep = memo(
};

const filterEntities = (entities: any[], searchTerm: string, selectedEntityId: ID | undefined) => {
const normalizedSearchTerm = normalizeDiacriticalMarks(searchTerm.toLowerCase());
return entities.filter(
(entity) =>
entity.entity_id === selectedEntityId ||
entity.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
(entity.accountName && entity.accountName.toLowerCase().includes(searchTerm.toLowerCase())),
normalizeDiacriticalMarks(entity.name.toLowerCase()).includes(normalizedSearchTerm) ||
(entity.accountName &&
normalizeDiacriticalMarks(entity.accountName.toLowerCase()).includes(normalizedSearchTerm)),
);
};

Expand Down Expand Up @@ -319,9 +321,17 @@ export const TransferBetweenEntities = ({
</div>
</div>

<div className="w-full col-span-2">
<div className="w-full col-span-2 grid grid-cols-4 gap-4">
<Button
className="w-full justify-center"
className="col-span-1 justify-center"
variant="secondary"
size="md"
onClick={() => setSelectedStepId(STEP_ID.SELECT_ENTITIES)}
>
Back
</Button>
<Button
className="col-span-3 justify-center"
isLoading={isLoading}
disabled={!canCarry || selectedResourceIds.length === 0}
variant="primary"
Expand Down
13 changes: 8 additions & 5 deletions client/src/ui/components/worldmap/players/PlayersPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ 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 { getEntityIdFromKeys, normalizeDiacriticalMarks, toHexString } from "@/ui/utils/utils";
import { ContractAddress, Player } from "@bibliothecadao/eternum";
import { Has, HasValue, getComponentValue, runQuery } from "@dojoengine/recs";
import { KeyboardEvent, useMemo, useState } from "react";
Expand Down Expand Up @@ -73,17 +73,20 @@ export const PlayersPanel = ({
}, [isLoading, players]);

const filteredPlayers = useMemo(() => {
const term = searchTerm.toLowerCase();
const normalizedTerm = normalizeDiacriticalMarks(searchTerm.toLowerCase());

return searchTerm === ""
? playersWithStructures
: playersWithStructures.filter((player) => {
const nameMatch = player.name.toLowerCase().includes(term);
const nameMatch = normalizeDiacriticalMarks(player.name.toLowerCase()).includes(normalizedTerm);
if (nameMatch) return true;

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

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

Expand Down
49 changes: 44 additions & 5 deletions client/src/ui/elements/ListSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { ReactComponent as CaretDown } from "@/assets/icons/common/caret-down-fi
import { ReactComponent as Checkmark } from "@/assets/icons/common/checkmark.svg";
import { Listbox, Transition } from "@headlessui/react";
import clsx from "clsx";
import { Fragment, ReactNode, useMemo } from "react";
import { Fragment, ReactNode, useMemo, useRef, useState } from "react";
import TextInput from "./TextInput";

interface ListSelectOption {
id: any;
label: ReactNode;
searchText?: string;
}

type ListSelectProps = {
Expand All @@ -16,20 +18,45 @@ type ListSelectProps = {
onChange: (value: any) => void;
className?: string;
style?: "default" | "black";
enableFilter?: boolean;
};

function ListSelect(props: ListSelectProps) {
const [searchInput, setSearchInput] = useState("");
const inputRef = useRef<HTMLInputElement>(null);

const selectedOption = useMemo(
() =>
props.options.find((option) => option.id === props.value) ||
props.options[0] || { id: "", label: "Select a wallet..." },
[props.value],
);

const filteredOptions = useMemo(() => {
if (!searchInput || !props.enableFilter) return props.options;

return props.options.filter((option) => {
const searchText = option.searchText || (typeof option.label === "string" ? option.label : "");
return searchText.toLowerCase().includes(searchInput.toLowerCase());
});
}, [props.options, searchInput, props.enableFilter]);

const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter") {
if (filteredOptions.length > 0) {
props.onChange(filteredOptions[0].id);
setSearchInput("");
}
} else {
e.stopPropagation();
}
};

return (
<div className={clsx("w-full", props.className, "z-100")}>
<Listbox value={props.value} onChange={props.onChange}>
{({ open }) => (
<div className="relative ">
<div className="relative">
<Listbox.Button
className={clsx(
"flex items-center relative cursor-pointer text-xs py-1 min-h-[32px] z-0 w-full bg-gold/10 hover:bg-gold/20 px-2",
Expand All @@ -56,14 +83,26 @@ function ListSelect(props: ListSelectProps) {
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="absolute top-[100%] z-50 w-min text-xs">
<div className="absolute top-[100%] z-50 w-full text-xs">
<Listbox.Options
className={clsx(
"z-50 mt-2 w-full rounded-md py-1 max-h-72 overflow-scroll z-100 border border-gold/10 no-scrollbar",
"mt-2 w-full rounded-md py-1 max-h-72 overflow-scroll z-100 border border-gold/10 no-scrollbar",
props.style === "black" ? "bg-brown" : " bg-brown",
)}
>
{props.options.map((option) => (
{props.enableFilter && (
<div className="p-2">
<TextInput
ref={inputRef}
onChange={setSearchInput}
placeholder="Filter..."
onKeyDown={handleKeyDown}
className="w-full"
/>
</div>
)}

{filteredOptions.map((option) => (
<Listbox.Option
key={option.id}
className={({ active }) =>
Expand Down
2 changes: 1 addition & 1 deletion client/src/ui/modules/navigation/LeftNavigationModule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export const LeftNavigationModule = memo(() => {
name: MenuEnum.construction,
button: (
<CircleButton
// disabled={!structureIsMine || !isRealm}
disabled={!structureIsMine || !isRealm}
className="construction-selector"
image={BuildingThumbs.construction}
tooltipLocation="top"
Expand Down
4 changes: 4 additions & 0 deletions client/src/ui/utils/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -530,3 +530,7 @@ export const calculateDonkeysNeeded = (orderWeight: number): number => {

return Math.ceil(divideByPrecision(orderWeight) / donkeyCapacityGrams);
};

export const normalizeDiacriticalMarks = (str: string) => {
return str.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
};

0 comments on commit b4b9145

Please sign in to comment.