diff --git a/components/Treasury/TreasuryVoteTable/TreasuryVotePopover.tsx b/components/Treasury/TreasuryVoteTable/TreasuryVotePopover.tsx index b150e5c5..1f412e4e 100644 --- a/components/Treasury/TreasuryVoteTable/TreasuryVotePopover.tsx +++ b/components/Treasury/TreasuryVoteTable/TreasuryVotePopover.tsx @@ -7,6 +7,7 @@ import { TreasuryVoteSupport, useTreasuryVoteEventsQuery, } from "apollo"; +import { useEnsData } from "hooks"; import React from "react"; import TreasuryVoteDetail from "./TreasuryVoteDetail"; @@ -14,17 +15,17 @@ import TreasuryVoteHistoryModal from "./TreasuryVoteHistoryModal"; interface TreasuryVotePopoverProps { voter: string; - ensName?: string; onClose: () => void; formatWeight: (weight: string) => string; } const Index: React.FC = ({ voter, - ensName, onClose, formatWeight, }) => { + const ensIdentity = useEnsData(voter); + const ensName = ensIdentity?.name || ensIdentity?.idShort || ""; const { data: votesData, loading: isLoading } = useTreasuryVoteEventsQuery({ variables: { where: { diff --git a/components/Treasury/TreasuryVoteTable/Views/DesktopVoteTable.tsx b/components/Treasury/TreasuryVoteTable/Views/DesktopVoteTable.tsx index 6d512f79..4aedca56 100644 --- a/components/Treasury/TreasuryVoteTable/Views/DesktopVoteTable.tsx +++ b/components/Treasury/TreasuryVoteTable/Views/DesktopVoteTable.tsx @@ -12,7 +12,6 @@ import { Column } from "react-table"; import { VoteReasonPopover } from "./VoteReasonPopover"; export type Vote = TreasuryVote & { - ensName?: string; transactionHash?: string; timestamp?: number; }; @@ -20,7 +19,7 @@ export type Vote = TreasuryVote & { export interface TreasuryVoteTableProps { votes: Vote[]; formatWeight: (weight: string) => string; - onSelect: (voter: { address: string; ensName?: string }) => void; + onSelect: (voter: { address: string }) => void; pageSize?: number; totalPages?: number; currentPage?: number; @@ -37,7 +36,7 @@ export const DesktopVoteTable: React.FC = ({ () => [ { Header: "Voter", - accessor: "ensName", + accessor: "voter", id: "voter", Cell: ({ row }) => ( @@ -206,7 +205,6 @@ export const DesktopVoteTable: React.FC = ({ e.stopPropagation(); onSelect({ address: row.original.voter.id, - ensName: row.original.ensName, }); }} css={{ diff --git a/components/Treasury/TreasuryVoteTable/Views/VoteItem.tsx b/components/Treasury/TreasuryVoteTable/Views/VoteItem.tsx index f94c508e..722d6ba0 100644 --- a/components/Treasury/TreasuryVoteTable/Views/VoteItem.tsx +++ b/components/Treasury/TreasuryVoteTable/Views/VoteItem.tsx @@ -18,6 +18,7 @@ import { CounterClockwiseClockIcon, } from "@radix-ui/react-icons"; import { TreasuryVoteSupport } from "apollo/subgraph"; +import { useEnsData } from "hooks"; import { useState } from "react"; import { Vote } from "./DesktopVoteTable"; @@ -25,7 +26,7 @@ import { VoteReasonPopover } from "./VoteReasonPopover"; interface VoteViewProps { vote: Vote; - onSelect: (voter: { address: string; ensName?: string }) => void; + onSelect: (voter: { address: string }) => void; formatWeight: (weight: string) => string; isMobile?: boolean; } @@ -53,6 +54,8 @@ export function VoteView({ function MobileVoteView({ vote, onSelect, formatWeight }: VoteViewProps) { const [isExpanded, setIsExpanded] = useState(false); + const ensIdentity = useEnsData(vote.voter.id); + const displayName = ensIdentity?.name || ensIdentity?.idShort || ""; const support = VOTING_SUPPORT_MAP[vote.support] || VOTING_SUPPORT_MAP[TreasuryVoteSupport.Abstain]; @@ -113,12 +116,12 @@ function MobileVoteView({ vote, onSelect, formatWeight }: VoteViewProps) { }, }} > - {vote.ensName} + {displayName} - onSelect({ address: vote.voter.id, ensName: vote.ensName }) - } + onClick={() => onSelect({ address: vote.voter.id })} > History @@ -277,6 +278,8 @@ function MobileVoteView({ vote, onSelect, formatWeight }: VoteViewProps) { } function DesktopVoteView({ vote, onSelect, formatWeight }: VoteViewProps) { + const ensIdentity = useEnsData(vote.voter.id); + const displayName = ensIdentity?.name || ensIdentity?.idShort || ""; const support = VOTING_SUPPORT_MAP[vote.support] || VOTING_SUPPORT_MAP[TreasuryVoteSupport.Abstain]; @@ -330,7 +333,7 @@ function DesktopVoteView({ vote, onSelect, formatWeight }: VoteViewProps) { }} size="2" > - {vote.ensName} + {displayName} @@ -492,7 +495,7 @@ function DesktopVoteView({ vote, onSelect, formatWeight }: VoteViewProps) { as="button" onClick={(e) => { e.stopPropagation(); - onSelect({ address: vote.voter.id, ensName: vote.ensName }); + onSelect({ address: vote.voter.id }); }} css={{ display: "inline-flex", diff --git a/components/Treasury/TreasuryVoteTable/index.tsx b/components/Treasury/TreasuryVoteTable/index.tsx index 583ab35c..111b3556 100644 --- a/components/Treasury/TreasuryVoteTable/index.tsx +++ b/components/Treasury/TreasuryVoteTable/index.tsx @@ -1,9 +1,8 @@ import Spinner from "@components/Spinner"; -import { getEnsForVotes } from "@lib/api/ens"; -import { formatAddress, lptFormatter } from "@lib/utils"; +import { lptFormatter } from "@lib/utils"; import { Flex, Text } from "@livepeer/design-system"; import { useTreasuryVoteEventsQuery, useTreasuryVotesQuery } from "apollo"; -import React, { useEffect, useMemo, useState } from "react"; +import React, { useMemo, useState } from "react"; import { useWindowSize } from "react-use"; import TreasuryVotePopover from "./TreasuryVotePopover"; @@ -40,69 +39,33 @@ const useVotes = (proposalId: string) => { }, }); - const [votes, setVotes] = useState([]); - const [votesLoading, setVotesLoading] = useState(false); - useEffect(() => { - if ( - !treasuryVotesData?.treasuryVotes || - !treasuryVoteEventsData?.treasuryVoteEvents - ) { - setVotes([]); + const votes = useMemo(() => { + const votesList = treasuryVotesData?.treasuryVotes; + const eventsList = treasuryVoteEventsData?.treasuryVoteEvents; + + if (!votesList || !eventsList) { + return []; } - const decorateVotes = async () => { - setVotesLoading(true); - const uniqueVoters = Array.from( - new Set(treasuryVotesData?.treasuryVotes?.map((v) => v.voter.id) ?? []) - ); - const localEnsCache: { [address: string]: string } = {}; - - await Promise.all( - uniqueVoters.map(async (address) => { - try { - if (localEnsCache[address]) { - return; - } - const ensAddress = await getEnsForVotes(address); - - if (ensAddress && ensAddress.name) { - localEnsCache[address] = ensAddress.name; - } else { - localEnsCache[address] = formatAddress(address); - } - } catch (e) { - console.warn(`Failed to fetch ENS for ${address}`, e); - } - }) - ); - const votes = - treasuryVotesData?.treasuryVotes?.map((vote) => { - const events = (treasuryVoteEventsData?.treasuryVoteEvents ?? []) - .filter((event) => event.voter.id === vote.voter.id) - .sort((a, b) => b.timestamp - a.timestamp); - - const latestEvent = events[0]; - const ensName = localEnsCache[vote.voter.id] ?? ""; - - return { - ...vote, - reason: latestEvent?.reason || vote.reason || "", - ensName, - transactionHash: latestEvent?.transaction.id ?? "", - timestamp: latestEvent?.timestamp, - }; - }) ?? []; - setVotes(votes as Vote[]); - setVotesLoading(false); - }; - decorateVotes(); - }, [ - treasuryVotesData?.treasuryVotes, - treasuryVoteEventsData?.treasuryVoteEvents, - ]); + + return votesList.map((vote) => { + const events = eventsList + .filter((event) => event.voter.id === vote.voter.id) + .sort((a, b) => b.timestamp - a.timestamp); + + const latestEvent = events[0]; + + return { + ...vote, + reason: latestEvent?.reason || vote.reason || "", + transactionHash: latestEvent?.transaction.id ?? "", + timestamp: latestEvent?.timestamp, + }; + }) as Vote[]; + }, [treasuryVotesData, treasuryVoteEventsData]); return { votes, - loading: loading || votesLoading || treasuryVoteEventsLoading, + loading: loading || treasuryVoteEventsLoading, error: error || treasuryVoteEventsError, }; }; @@ -113,7 +76,6 @@ const Index: React.FC = ({ proposalId }) => { const [selectedVoter, setSelectedVoter] = useState<{ address: string; - ensName?: string; } | null>(null); const [currentPage, setCurrentPage] = useState(1); const pageSize = 10; @@ -191,7 +153,6 @@ const Index: React.FC = ({ proposalId }) => { {selectedVoter && ( setSelectedVoter(null)} formatWeight={formatWeight} />