Skip to content

Commit

Permalink
Merge pull request #21 from aragon/f/ui-improvements-4
Browse files Browse the repository at this point in the history
F/UI improvements 4
  • Loading branch information
brickpop authored Jul 30, 2024
2 parents a947305 + 6d0fbc4 commit e349f12
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 38 deletions.
44 changes: 26 additions & 18 deletions components/input/function-abi-select-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,30 +136,38 @@ const FunctionSelect = ({
functionAbiList: AbiFunction[];
onSelect: (f: AbiFunction) => any;
}) => {
const [showReadOnly, setShowReadOnly] = useState(false);
const readonlyCount = functionAbiList.filter((f) => ["pure", "view"].includes(f.stateMutability)).length;

return (
<InputContainer id="func-abi-select" label="Select the function to call" className="my-4">
<dl className="w-full divide-y divide-neutral-100">
{functionAbiList.map((func, idx) => (
<If not={["pure", "view"].includes(func.stateMutability)} key={idx}>
<Then>
<div
onClick={() => onSelect(func)}
className=" flex cursor-pointer flex-col items-baseline gap-y-2 py-3 hover:bg-neutral-50 lg:gap-x-6 lg:py-4"
>
<dd className="size-full px-3 text-base leading-tight text-neutral-500">
{decodeCamelCase(func.name)}
</dd>
</div>
</Then>
<Else>
<div className="flex flex-col items-baseline gap-y-2 py-3 lg:gap-x-6 lg:py-4">
<dd className="size-full px-3 text-base leading-tight text-neutral-500">
{decodeCamelCase(func.name)} <span className="text-xs text-neutral-300">(read only)</span>
</dd>
</div>
</Else>
<If condition={!["pure", "view"].includes(func.stateMutability) || showReadOnly} key={idx}>
<div
onClick={() => onSelect(func)}
className="flex cursor-pointer flex-col items-baseline gap-y-2 py-3 first:rounded-t-xl last:rounded-b-xl hover:bg-neutral-50 lg:gap-x-6 lg:py-4"
>
<dd className="size-full px-3 text-base leading-tight text-neutral-500">
{decodeCamelCase(func.name)}
<If condition={["pure", "view"].includes(func.stateMutability)}>
{" "}
<span className="text-xs text-neutral-300">(read only)</span>
</If>
</dd>
</div>
</If>
))}
<If condition={!showReadOnly && readonlyCount > 0}>
<div
onClick={() => setShowReadOnly(true)}
className="flex cursor-pointer flex-col items-baseline gap-y-2 py-3 first:rounded-t-xl last:rounded-b-xl hover:bg-neutral-50 lg:gap-x-6 lg:py-4"
>
<dd className="size-full px-3 text-base text-sm leading-tight text-neutral-300">
Show read only methods ({readonlyCount})
</dd>
</div>
</If>
</dl>
</InputContainer>
);
Expand Down
16 changes: 8 additions & 8 deletions components/input/function-params-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,6 @@ export const FunctionParamsForm = ({
<p className="text-md font-semibold text-neutral-800">Parameters</p>
</div>
</If>
<If condition={["pure", "view"].includes(functionAbi?.stateMutability ?? "")}>
<div className="">
<AlertInline
message="This function is marked as read only. An action sent to it will have no impact"
variant="warning"
/>
</div>
</If>
{functionAbi?.inputs.map((paramAbi, i) => (
<div key={i} className=" my-3">
<InputParameter abi={paramAbi} idx={i} onChange={onParameterChange} />
Expand All @@ -101,6 +93,14 @@ export const FunctionParamsForm = ({
/>
</div>
</If>
<If condition={["pure", "view"].includes(functionAbi?.stateMutability ?? "")}>
<div className="mt-2">
<AlertInline
message="This method is marked as read only. An action calling it should have no impact."
variant="warning"
/>
</div>
</If>
</div>
);
};
17 changes: 17 additions & 0 deletions hooks/useShuffled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useEffect, useState } from "react";

export function useShuffled<T>(array?: T[] | readonly T[]) {
const [shuffledArray, setShuffledArray] = useState<T[]>([]);

useEffect(() => {
if (!array) return;

// If the length changes, shuffle and update
const newArray = ([] as T[]).concat(array);
newArray.sort(() => (Math.random() >= 0.5 ? 1 : -1));

setShuffledArray(newArray);
}, [array?.length]);

return shuffledArray;
}
36 changes: 24 additions & 12 deletions plugins/members/hooks/useDelegates.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
import { useReadContract } from "wagmi";
import { useConfig } from "wagmi";
import { DelegateAnnouncerAbi } from "@/plugins/members/artifacts/DelegationWall.sol";
import { PUB_CHAIN, PUB_DELEGATION_WALL_CONTRACT_ADDRESS } from "@/constants";
import { PUB_DELEGATION_WALL_CONTRACT_ADDRESS } from "@/constants";
import { readContract } from "@wagmi/core";
import { useQuery } from "@tanstack/react-query";
import { useShuffled } from "@/hooks/useShuffled";

/** Returns the list of delegates who posted a candidacy */
export function useDelegates() {
const {
data: delegates,
status,
refetch,
} = useReadContract({
chainId: PUB_CHAIN.id,
address: PUB_DELEGATION_WALL_CONTRACT_ADDRESS,
abi: DelegateAnnouncerAbi,
functionName: "getCandidateAddresses",
const config = useConfig();

const { data, status, refetch } = useQuery({
queryKey: ["delegate-addresses-list", PUB_DELEGATION_WALL_CONTRACT_ADDRESS],
queryFn: () => {
return readContract(config, {
abi: DelegateAnnouncerAbi,
address: PUB_DELEGATION_WALL_CONTRACT_ADDRESS,
functionName: "getCandidateAddresses",
args: [],
});
},
retry: true,
refetchOnMount: false,
refetchOnReconnect: false,
retryOnMount: true,
staleTime: 1000 * 60 * 10,
});
const shuffledDelegates = useShuffled(data);

return { delegates, status, refetch };
return { delegates: shuffledDelegates, status, refetch };
}

0 comments on commit e349f12

Please sign in to comment.