Skip to content

Commit

Permalink
feat: properly disable vote button and poll proposal changes
Browse files Browse the repository at this point in the history
  • Loading branch information
mateuszjasiuk committed Aug 23, 2024
1 parent 72f462b commit 00650c0
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 34 deletions.
2 changes: 1 addition & 1 deletion apps/namadillo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"license": "MIT",
"private": true,
"dependencies": {
"@anomaorg/namada-indexer-client": "../../../namada-indexer-client",
"@anomaorg/namada-indexer-client": "0.0.23",
"@cosmjs/encoding": "^0.32.3",
"@tailwindcss/container-queries": "^0.1.1",
"@tanstack/react-query": "^5.40.0",
Expand Down
4 changes: 3 additions & 1 deletion apps/namadillo/src/App/Governance/ProposalHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,9 @@ const VoteButton: React.FC<{
}> = ({ proposal, voted, proposalId }) => {
const navigate = useNavigate();
const isExtensionConnected = useAtomValue(namadaExtensionConnectedAtom);
const canVote = useAtomValue(canVoteAtom);
const canVote = useAtomValue(
canVoteAtom(proposal.data?.startEpoch || BigInt(-1))
);

if (!isExtensionConnected) {
return null;
Expand Down
7 changes: 6 additions & 1 deletion apps/namadillo/src/App/Governance/ProposalStatusSummary.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import BigNumber from "bignumber.js";
import clsx from "clsx";
import { AnimatePresence, motion } from "framer-motion";
import { useState } from "react";
import { useEffect, useState } from "react";

import { PieChart, PieChartData, Stack } from "@namada/components";
import { formatPercentage } from "@namada/utils";
Expand Down Expand Up @@ -165,6 +165,11 @@ const Loaded: React.FC<{
highestVoteType
);

useEffect(() => {
// Reset the hovered vote type to the highest vote type when the highest vote type changes(on data poll)
setHoveredVoteType(highestVoteType);
}, [highestVoteType]);

const votedProportion =
totalVotingPower.isEqualTo(0) ?
BigNumber(0)
Expand Down
3 changes: 2 additions & 1 deletion apps/namadillo/src/App/Governance/SubmitVote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,12 @@ export const WithProposalId: React.FC<{ proposalId: bigint }> = ({
const [selectedVoteType, setSelectedVoteType] = useState<VoteType>();

const proposalQueryResult = useAtomValue(proposalFamily(proposalId));
const canVote = useAtomValue(canVoteAtom);

const proposal =
proposalQueryResult.isSuccess ? proposalQueryResult.data : null;

const canVote = useAtomValue(canVoteAtom(proposal?.startEpoch || BigInt(-1)));

const onCloseModal = (): void => navigate(-1);

const dispatchPendingNotification = (txs: BuiltTx[]): void => {
Expand Down
9 changes: 8 additions & 1 deletion apps/namadillo/src/atoms/etc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import { atomWithStorage } from "jotai/utils";

type ControlRoutineProps = {
shouldUpdateAmount: boolean;
shouldUpdateProposal: boolean;
lastBlockHeight: BigNumber | undefined;
};

export const controlRoutineAtom = atomWithStorage<ControlRoutineProps>(
"namadillo:etc",
{
shouldUpdateAmount: false,
shouldUpdateProposal: false,
lastBlockHeight: undefined,
}
);
Expand All @@ -29,7 +31,12 @@ export const shouldUpdateBalanceAtom = atom(
changeProps<boolean>("shouldUpdateAmount")
);

export const shouldUpdateProposalAtom = atom(
(get) => get(controlRoutineAtom).shouldUpdateProposal,
changeProps<boolean>("shouldUpdateProposal")
);

export const lastBlockHeightAtom = atom(
(get) => get(controlRoutineAtom).shouldUpdateAmount,
(get) => get(controlRoutineAtom).lastBlockHeight,
changeProps<BigNumber | undefined>("lastBlockHeight")
);
51 changes: 30 additions & 21 deletions apps/namadillo/src/atoms/proposals/atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ import {
fetchVotedProposalIds,
} from "./functions";

import {
Bond as NamadaIndexerBond,
BondStatusEnum as NamadaIndexerBondStatusEnum,
} from "@anomaorg/namada-indexer-client";
import { Bond as NamadaIndexerBond } from "@anomaorg/namada-indexer-client";
import { shouldUpdateProposalAtom } from "atoms/etc";
export const proposalFamily = atomFamily((id: bigint) =>
atomWithQuery((get) => {
const api = get(indexerApiAtom);
const enablePolling = get(shouldUpdateProposalAtom);

return {
// TODO: subscribe to indexer events when it's done
refetchInterval: enablePolling ? 1000 : false,
queryKey: ["proposal", id.toString()],
queryFn: () => fetchProposalById(api, id),
};
Expand Down Expand Up @@ -96,7 +97,11 @@ export const paginatedProposalsFamily = atomFamily(
export const votedProposalIdsAtom = atomWithQuery((get) => {
const account = get(defaultAccountAtom);
const api = get(indexerApiAtom);
const enablePolling = get(shouldUpdateProposalAtom);

return {
// TODO: subscribe to indexer events when it's done
refetchInterval: enablePolling ? 1000 : false,
queryKey: ["voted-proposal-ids", account.data],
...queryDependentFn(async () => {
if (typeof account.data === "undefined") {
Expand All @@ -107,25 +112,29 @@ export const votedProposalIdsAtom = atomWithQuery((get) => {
};
});

export const canVoteAtom = atomWithQuery((get) => {
const account = get(defaultAccountAtom);
const api = get(indexerApiAtom);
export const canVoteAtom = atomFamily((proposalStartEpoch: bigint) =>
atomWithQuery((get) => {
const account = get(defaultAccountAtom);
const api = get(indexerApiAtom);

return {
queryKey: ["can-vote"],
enabled: account.isSuccess,
queryFn: async () => {
const all_bonds = await api.apiV1PosBondAddressGet(account.data!.address);
return {
queryKey: ["can-vote"],
enabled: account.isSuccess,
queryFn: async () => {
const all_bonds = await api.apiV1PosBondAddressGet(
account.data!.address
);

return all_bonds.data.results.reduce(
(acc: boolean, current: NamadaIndexerBond) => {
return acc || current.status === NamadaIndexerBondStatusEnum.Active;
},
false
);
},
};
});
return all_bonds.data.results.reduce(
(acc: boolean, current: NamadaIndexerBond) => {
return acc || Number(current.startEpoch) <= proposalStartEpoch;
},
false
);
},
};
})
);

type CreateVoteTxArgs = {
proposalId: bigint;
Expand Down
3 changes: 2 additions & 1 deletion apps/namadillo/src/atoms/validators/functions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
Bond as IndexerBond,
MergedBond as IndexerMergedBond,
Unbond as IndexerUnbond,
Validator as IndexerValidator,
VotingPower as IndexerVotingPower,
Expand Down Expand Up @@ -45,7 +46,7 @@ export const toValidator = (
};

export const toMyValidators = (
indexerBonds: IndexerBond[],
indexerBonds: IndexerBond[] | IndexerMergedBond[],
totalVotingPower: IndexerVotingPower,
epochInfo: EpochInfo,
apr: BigNumber
Expand Down
28 changes: 26 additions & 2 deletions apps/namadillo/src/hooks/useTransactionCallbacks.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { accountBalanceAtom } from "atoms/accounts";
import { shouldUpdateBalanceAtom } from "atoms/etc";
import { useAtomValue, useSetAtom } from "jotai";
import { shouldUpdateBalanceAtom, shouldUpdateProposalAtom } from "atoms/etc";
import { proposalFamily, votedProposalIdsAtom } from "atoms/proposals";
import { createStore, useAtomValue, useSetAtom } from "jotai";
import { useTransactionEventListener } from "utils";

export const useTransactionCallback = (): void => {
const { refetch: refetchBalances } = useAtomValue(accountBalanceAtom);
const shouldUpdateBalance = useSetAtom(shouldUpdateBalanceAtom);
const shouldUpdateProposal = useSetAtom(shouldUpdateProposalAtom);

const onBalanceUpdate = (): void => {
// TODO: refactor this after event subscription is enabled on indexer
Expand All @@ -19,4 +21,26 @@ export const useTransactionCallback = (): void => {
useTransactionEventListener("Bond.Success", onBalanceUpdate);
useTransactionEventListener("Unbond.Success", onBalanceUpdate);
useTransactionEventListener("Withdraw.Success", onBalanceUpdate);

const store = createStore();

useTransactionEventListener("VoteProposal.Success", (args) => {
// TODO: refactor this after event subscription is enabled on indexer
shouldUpdateProposal(true);

const proposalId = args.detail.data[0].proposalId;
const { refetch: refetchProposalFamily } = store.get(
proposalFamily(proposalId)
);
refetchProposalFamily();

const { refetch: refetchVotedProposalIds } =
store.get(votedProposalIdsAtom);
refetchVotedProposalIds();

// Proposal status update takes longer than balance update.
// 12 seconds does not guarantee the status is updated though.
const timePolling = 12 * 1000;
setTimeout(() => shouldUpdateProposal(false), timePolling);
});
};
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ __metadata:
languageName: node
linkType: hard

"@anomaorg/namada-indexer-client@file:../../../namada-indexer-client::locator=%40namada%2Fnamadillo%40workspace%3Aapps%2Fnamadillo":
version: 0.0.22
resolution: "@anomaorg/namada-indexer-client@file:../../../namada-indexer-client#../../../namada-indexer-client::hash=3a5fbb&locator=%40namada%2Fnamadillo%40workspace%3Aapps%2Fnamadillo"
"@anomaorg/namada-indexer-client@npm:0.0.23":
version: 0.0.23
resolution: "@anomaorg/namada-indexer-client@npm:0.0.23"
dependencies:
axios: "npm:^1.6.1"
checksum: 812376e1e7591f5f8f6a4a28c237797bf58aa7cf956f2a4cc373ad2bc4d270da5ec3c80b617a20d5e9c40a949a2d5f73873a08f410607caa426666d6418b3682
checksum: 1249a851ad5ad09daa88bc621fbc33fe520a3f5912ab02d472c4d7b52f26fb83cee2f7818c634a55abb137dfdf5226d0ecd057e24895573199da069a5111e1cd
languageName: node
linkType: hard

Expand Down Expand Up @@ -8448,7 +8448,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@namada/namadillo@workspace:apps/namadillo"
dependencies:
"@anomaorg/namada-indexer-client": ../../../namada-indexer-client
"@anomaorg/namada-indexer-client": "npm:0.0.23"
"@cosmjs/encoding": "npm:^0.32.3"
"@playwright/test": "npm:^1.24.1"
"@release-it/keep-a-changelog": "npm:^5.0.0"
Expand Down

0 comments on commit 00650c0

Please sign in to comment.