fix(governance): vote state update fix (#3023)

This commit is contained in:
Sam Keen 2023-02-28 12:43:20 +00:00 committed by GitHub
parent 7364abbbf2
commit d87adfd7d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 22 deletions

View File

@ -5,6 +5,7 @@ import { VoteValue } from '@vegaprotocol/types';
import { useEffect, useState } from 'react';
import { useUserVoteQuery } from './__generated__/Vote';
import { removePaginationWrapper } from '@vegaprotocol/react-helpers';
import type { FinalizedVote } from '@vegaprotocol/governance';
export enum VoteState {
NotCast = 'NotCast',
@ -21,25 +22,14 @@ export type Vote = {
party: { id: string };
};
export type Votes = Array<Vote | null>;
export function getUserVote(pubkey: string, yesVotes?: Votes, noVotes?: Votes) {
const yesVote = yesVotes?.find((v) => v && v.party.id === pubkey);
const noVote = noVotes?.find((v) => v && v.party.id === pubkey);
if (yesVote) {
return yesVote;
} else if (noVote) {
return noVote;
} else {
return null;
}
}
/**
* Finds the status of a users given vote in a given proposal and provides
* a function to send a vote transaction to your wallet
*/
export function useUserVote(proposalId: string | null | undefined) {
export function useUserVote(
proposalId: string | null | undefined,
finalizedVote?: FinalizedVote | null
) {
const { pubKey } = useVegaWallet();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const [timeout, setTimeoutValue] = useState<any>(null);
@ -50,10 +40,27 @@ export function useUserVote(proposalId: string | null | undefined) {
variables: { partyId: pubKey || '' },
skip: !pubKey || !proposalId,
});
const [userVote, setUserVote] = useState<FinalizedVote | undefined>(
undefined
);
const userVote = removePaginationWrapper(
data?.party?.votesConnection?.edges
).find(({ proposalId: pId }) => proposalId === pId);
useEffect(() => {
if (finalizedVote?.vote.value) {
setUserVote(finalizedVote);
} else if (data?.party?.votesConnection?.edges) {
// This sets the vote (if any) when the user first loads the page
setUserVote(
removePaginationWrapper(data?.party?.votesConnection?.edges).find(
({ proposalId: pId }) => proposalId === pId
)
);
}
}, [
finalizedVote?.vote.value,
data?.party?.votesConnection?.edges,
finalizedVote,
proposalId,
]);
// If user vote changes update the vote state
useEffect(() => {

View File

@ -22,6 +22,8 @@ describe('Vote buttons', () => {
minVoterBalance={null}
spamProtectionMinTokens={null}
currentStakeAvailable={new BigNumber(1)}
dialog={() => <div>Blah</div>}
submit={() => Promise.resolve()}
/>
</VegaWalletContext.Provider>
</MockedProvider>
@ -43,6 +45,8 @@ describe('Vote buttons', () => {
minVoterBalance={null}
spamProtectionMinTokens={null}
currentStakeAvailable={new BigNumber(1)}
dialog={() => <div>Blah</div>}
submit={() => Promise.resolve()}
/>
</VegaWalletContext.Provider>
</MockedProvider>
@ -75,6 +79,8 @@ describe('Vote buttons', () => {
minVoterBalance={null}
spamProtectionMinTokens={null}
currentStakeAvailable={new BigNumber(1)}
dialog={() => <div>Blah</div>}
submit={() => Promise.resolve()}
/>
</VegaWalletContext.Provider>
</MockedProvider>
@ -97,6 +103,8 @@ describe('Vote buttons', () => {
minVoterBalance={null}
spamProtectionMinTokens={null}
currentStakeAvailable={new BigNumber(0)}
dialog={() => <div>Blah</div>}
submit={() => Promise.resolve()}
/>
</VegaWalletContext.Provider>
</MockedProvider>
@ -120,6 +128,8 @@ describe('Vote buttons', () => {
minVoterBalance="2000000000000000000"
spamProtectionMinTokens="1000000000000000000"
currentStakeAvailable={new BigNumber(1)}
dialog={() => <div>Blah</div>}
submit={() => Promise.resolve()}
/>
</VegaWalletContext.Provider>
</MockedProvider>
@ -145,6 +155,8 @@ describe('Vote buttons', () => {
minVoterBalance="2000000000000000000"
spamProtectionMinTokens="1000000000000000000"
currentStakeAvailable={new BigNumber(10)}
dialog={() => <div>Blah</div>}
submit={() => Promise.resolve()}
/>
</VegaWalletContext.Provider>
</MockedProvider>
@ -167,6 +179,8 @@ describe('Vote buttons', () => {
minVoterBalance="2000000000000000000"
spamProtectionMinTokens="1000000000000000000"
currentStakeAvailable={new BigNumber(10)}
dialog={() => <div>Blah</div>}
submit={() => Promise.resolve()}
/>
</VegaWalletContext.Provider>
</MockedProvider>

View File

@ -4,7 +4,6 @@ import { useTranslation } from 'react-i18next';
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
import { AsyncRenderer, Button, ButtonLink } from '@vegaprotocol/ui-toolkit';
import { addDecimal, toBigNum } from '@vegaprotocol/react-helpers';
import { useVoteSubmit } from '@vegaprotocol/governance';
import { ProposalState, VoteValue } from '@vegaprotocol/types';
import {
AppStateActionType,
@ -16,6 +15,7 @@ import { VoteState } from './use-user-vote';
import { ProposalMinRequirements, ProposalUserAction } from '../shared';
import { VoteTransactionDialog } from './vote-transaction-dialog';
import { useVoteButtonsQuery } from './__generated__/Stake';
import type { DialogProps } from '@vegaprotocol/wallet';
interface VoteButtonsContainerProps {
voteState: VoteState | null;
@ -24,6 +24,8 @@ interface VoteButtonsContainerProps {
proposalState: ProposalState;
minVoterBalance: string | null;
spamProtectionMinTokens: string | null;
submit: (voteValue: VoteValue, proposalId: string | null) => Promise<void>;
dialog: (props: DialogProps) => JSX.Element;
className?: string;
}
@ -62,11 +64,12 @@ export const VoteButtons = ({
currentStakeAvailable,
minVoterBalance,
spamProtectionMinTokens,
submit,
dialog: Dialog,
}: VoteButtonsProps) => {
const { t } = useTranslation();
const { appDispatch } = useAppState();
const { pubKey } = useVegaWallet();
const { submit, Dialog } = useVoteSubmit();
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
openVegaWalletDialog: store.openVegaWalletDialog,
}));

View File

@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next';
import { formatDistanceToNow } from 'date-fns';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { ProposalState } from '@vegaprotocol/types';
import { VoteProgress } from '@vegaprotocol/governance';
import { useVoteSubmit, VoteProgress } from '@vegaprotocol/governance';
import { formatNumber } from '../../../../lib/format-number';
import { ConnectToVega } from '../../../../components/connect-to-vega';
import { useVoteInformation } from '../../hooks';
@ -44,7 +44,8 @@ export const VoteDetails = ({
} = useVoteInformation({ proposal });
const { t } = useTranslation();
const { voteState, voteDatetime } = useUserVote(proposal?.id);
const { submit, Dialog, finalizedVote } = useVoteSubmit();
const { voteState, voteDatetime } = useUserVote(proposal?.id, finalizedVote);
const defaultDecimals = 2;
const daysLeft = t('daysLeft', {
daysLeft: formatDistanceToNow(new Date(proposal?.terms.closingDatetime)),
@ -188,6 +189,8 @@ export const VoteDetails = ({
minVoterBalance={minVoterBalance}
spamProtectionMinTokens={spamProtectionMinTokens}
className="flex"
submit={submit}
dialog={Dialog}
/>
)}
</section>

View File

@ -5,6 +5,8 @@ import { useVoteEvent } from './use-vote-event';
import type { VoteValue } from '@vegaprotocol/types';
import type { VoteEventFieldsFragment } from './__generated__/VoteSubsciption';
export type FinalizedVote = VoteEventFieldsFragment;
export const useVoteSubmit = () => {
const { pubKey } = useVegaWallet();
const { send, transaction, setComplete, Dialog } = useVegaTransaction();