Skip to content

Commit c834d5f

Browse files
authored
Merge pull request #43 from privacy-scaling-explorations/fix/nico/ui-secondary-comments
Fix/nico/UI secondary comments
2 parents e38b186 + bcf527a commit c834d5f

File tree

7 files changed

+166
-48
lines changed

7 files changed

+166
-48
lines changed

hooks/useSwitchChain.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { PUBLIC_CHAIN } from "@/constants";
2+
import { useCallback, useMemo } from "react";
3+
import { useSwitchChain } from "wagmi";
4+
import { useAccount } from "wagmi";
5+
6+
export function useSwitchToChain() {
7+
const { switchChain } = useSwitchChain();
8+
const { chain } = useAccount();
9+
10+
const isCorrectChain = useMemo(() => {
11+
if (!chain) return false;
12+
13+
return chain.id === PUBLIC_CHAIN.id;
14+
}, [chain]);
15+
16+
const switchToChain = useCallback(async () => {
17+
if (isCorrectChain) return;
18+
19+
try {
20+
switchChain({ chainId: PUBLIC_CHAIN.id });
21+
} catch (error) {
22+
// eslint-disable-next-line no-console
23+
console.error("Failed to switch chain:", error);
24+
}
25+
}, [isCorrectChain, switchChain]);
26+
return { switchToChain, isCorrectChain };
27+
}

plugins/maciVoting/components/PollCard.tsx

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import { useMaci } from "../hooks/useMaci";
44
import { VoteOption } from "../utils/types";
55
import { PleaseWaitSpinner } from "@/components/please-wait";
66
import { PUBLIC_MACI_ADDRESS } from "@/constants";
7-
import { getPoll, getResults, type IResult } from "@maci-protocol/sdk/browser";
7+
import { getPoll } from "@maci-protocol/sdk/browser";
88
import { useEthersSigner } from "../hooks/useEthersSigner";
99
import { unixTimestampToDate } from "../utils/formatPollDate";
1010
import { useCoordinator } from "../hooks/useCoordinator";
11+
import { useResults } from "../hooks/useResults";
1112

1213
const PollCard = ({ pollId }: { pollId: bigint }) => {
1314
// check if the user joined the poll
@@ -18,8 +19,7 @@ const PollCard = ({ pollId }: { pollId: bigint }) => {
1819
const [voteStartDate, setVoteStartDate] = useState(0);
1920
const [voteEnded, setVoteEnded] = useState(false);
2021
const [voteOption, setVoteOption] = useState<VoteOption | undefined>(undefined);
21-
const [results, setResults] = useState<IResult[] | undefined>(undefined);
22-
const [tallied, setTallied] = useState(false);
22+
const { results, tallied } = useResults(pollId);
2323

2424
const disabled = useMemo(() => {
2525
return isLoading || voteEnded || voteStartDate > Math.round(Date.now() / 1000);
@@ -47,30 +47,8 @@ const PollCard = ({ pollId }: { pollId: bigint }) => {
4747
setVoteEnded(endDate < now);
4848
};
4949

50-
const checkPollTallied = async () => {
51-
const isTallied = await checkIsTallied(Number(pollId));
52-
setTallied(isTallied);
53-
};
54-
55-
const getPollResults = async () => {
56-
const contractResults = await getResults({
57-
maciAddress: PUBLIC_MACI_ADDRESS,
58-
pollId: pollId.toString(),
59-
signer,
60-
});
61-
setResults(contractResults);
62-
};
63-
6450
checkVoteEnded();
65-
66-
if (voteEnded) {
67-
checkPollTallied();
68-
}
69-
70-
if (tallied) {
71-
getPollResults();
72-
}
73-
}, [voteEnded, setVoteEnded, pollId, signer, checkIsTallied, tallied, getResults]);
51+
}, [voteEnded, setVoteEnded, pollId, signer, checkIsTallied, tallied]);
7452

7553
useEffect(() => {
7654
setPollId(pollId);

plugins/maciVoting/components/finalize/finalizeAction.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
import { useMemo } from "react";
1+
import { useCallback, useMemo } from "react";
22
import { useCoordinator } from "../../hooks/useCoordinator";
33
import { Button } from "@aragon/ods";
44
import { PleaseWaitSpinner } from "@/components/please-wait";
55
import { If } from "@/components/if";
6+
import { useRouter } from "next/router";
67

78
interface IFinalizeActionProps {
89
pollId: number;
910
}
1011

1112
export const FinalizeAction: React.FC<IFinalizeActionProps> = ({ pollId }) => {
13+
const router = useRouter();
1214
const { finalizeStatus, finalizeProposal } = useCoordinator();
1315

1416
const finalizationMessage = useMemo(() => {
@@ -28,13 +30,18 @@ export const FinalizeAction: React.FC<IFinalizeActionProps> = ({ pollId }) => {
2830
}
2931
}, [finalizeStatus]);
3032

33+
const onClickFinalize = useCallback(async () => {
34+
await finalizeProposal(pollId);
35+
router.reload();
36+
}, [finalizeProposal, pollId, router]);
37+
3138
return (
3239
<div className="overflow-hidden rounded-xl bg-neutral-0 pb-2 shadow-neutral">
3340
<If condition={finalizeStatus !== "submitted"}>
3441
<div className="flex flex-col gap-y-2 px-4 py-4 md:gap-y-3 md:px-6 md:py-6">
3542
<div className="flex justify-between gap-x-2 gap-y-2">
3643
<p className="text-xl leading-tight text-neutral-800 md:text-2xl">Finalize Poll</p>
37-
<Button size="md" disabled={finalizeStatus !== "notStarted"} onClick={() => finalizeProposal(pollId)}>
44+
<Button size="md" disabled={finalizeStatus !== "notStarted"} onClick={onClickFinalize}>
3845
Finalize
3946
</Button>
4047
</div>

plugins/maciVoting/contexts/MaciContext.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,10 @@ export const MaciProvider = ({ children }: { children: ReactNode }) => {
268268

269269
let voteOptionIndex: bigint;
270270
switch (option) {
271-
case VoteOption.No:
271+
case VoteOption.Yes:
272272
voteOptionIndex = 0n;
273273
break;
274-
case VoteOption.Yes:
274+
case VoteOption.No:
275275
voteOptionIndex = 1n;
276276
break;
277277
case VoteOption.Abstain:
@@ -477,7 +477,8 @@ export const MaciProvider = ({ children }: { children: ReactNode }) => {
477477
return;
478478
}
479479

480-
if (!pollId) {
480+
// if it is the first poll then !pollId = false because !0n = false
481+
if (!pollId && pollId !== 0n) {
481482
return;
482483
}
483484

plugins/maciVoting/hooks/useProposalVariantStatus.tsx

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { useState, useEffect } from "react";
22
import { type Proposal } from "@/plugins/maciVoting/utils/types";
33
import { type ProposalStatus } from "@aragon/ods";
44
import dayjs from "dayjs";
5+
import { useCoordinator } from "./useCoordinator";
6+
import { useResults } from "./useResults";
57

68
export const useProposalVariantStatus = (proposal: Proposal) => {
79
const [status, setStatus] = useState({ variant: "", label: "" });
@@ -24,24 +26,48 @@ export const useProposalVariantStatus = (proposal: Proposal) => {
2426

2527
export const useProposalStatus = (proposal: Proposal) => {
2628
const [status, setStatus] = useState<ProposalStatus>();
29+
const { checkIsTallied } = useCoordinator();
30+
const { results } = useResults(proposal ? proposal.pollId : undefined);
2731

2832
useEffect(() => {
29-
if (!proposal || !proposal?.parameters || !proposal?.tally) return;
30-
31-
const isExecuted = proposal.executed;
32-
const endDate = dayjs(Number(proposal.parameters.endDate) * 1000);
33-
const isActive = dayjs().isBefore(endDate);
34-
35-
if (isExecuted) {
36-
setStatus("executed");
37-
} else if (isActive) {
38-
setStatus("active");
39-
} else if (!isActive) {
40-
setStatus("rejected");
41-
} else {
42-
setStatus("accepted");
43-
}
44-
}, [proposal, proposal?.tally, proposal?.executed]);
33+
(async () => {
34+
if (!proposal || !proposal?.parameters || !proposal?.tally) return;
35+
36+
const isExecuted = proposal.executed;
37+
const endDate = dayjs(Number(proposal.parameters.endDate) * 1000);
38+
const isActive = dayjs().isBefore(endDate);
39+
const isTallied = await checkIsTallied(Number(proposal.pollId));
40+
41+
if (isExecuted) {
42+
setStatus("executed");
43+
} else if (isActive) {
44+
setStatus("active");
45+
} else if (!isTallied) {
46+
setStatus("pending");
47+
} else if (isTallied) {
48+
if (!results) {
49+
setStatus("pending");
50+
return;
51+
}
52+
53+
const yesFlag = results[0].isSet;
54+
const noFlag = results[1].isSet;
55+
56+
if (!yesFlag && !noFlag) {
57+
setStatus("pending");
58+
}
59+
60+
const yesVotes = results[0].value;
61+
const noVotes = results[1].value;
62+
63+
if (yesVotes > noVotes) {
64+
setStatus("accepted");
65+
} else {
66+
setStatus("rejected");
67+
}
68+
}
69+
})();
70+
}, [proposal, checkIsTallied, results]);
4571

4672
return status;
4773
};
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { PUBLIC_MACI_ADDRESS } from "@/constants";
2+
import { getPoll, getResults, type IResult } from "@maci-protocol/sdk/browser";
3+
import { useEffect, useState } from "react";
4+
import { useEthersSigner } from "./useEthersSigner";
5+
import { useCoordinator } from "./useCoordinator";
6+
7+
export const useResults = (pollId?: bigint) => {
8+
const { checkIsTallied } = useCoordinator();
9+
const signer = useEthersSigner();
10+
11+
const [results, setResults] = useState<IResult[] | undefined>(undefined);
12+
const [tallied, setTallied] = useState(false);
13+
14+
useEffect(() => {
15+
(async () => {
16+
if (!signer || !pollId) {
17+
return;
18+
}
19+
20+
try {
21+
const { endDate } = await getPoll({
22+
maciAddress: PUBLIC_MACI_ADDRESS,
23+
pollId,
24+
signer,
25+
});
26+
const now = Math.round(Date.now() / 1000);
27+
const voteEnded = Number(endDate) < now;
28+
if (!voteEnded) {
29+
setTallied(false);
30+
return;
31+
}
32+
33+
const isTallied = await checkIsTallied(Number(pollId));
34+
setTallied(isTallied);
35+
} catch (error) {
36+
// eslint-disable-next-line no-console
37+
console.log(error);
38+
// TODO: handle error if poll does not exist
39+
//console.log(error.message);
40+
return;
41+
}
42+
})();
43+
}, [checkIsTallied, pollId, signer]);
44+
45+
useEffect(() => {
46+
(async () => {
47+
if (!signer || !pollId) {
48+
return;
49+
}
50+
51+
if (!tallied) {
52+
return;
53+
}
54+
55+
try {
56+
const resultsData = await getResults({
57+
maciAddress: PUBLIC_MACI_ADDRESS,
58+
pollId: pollId.toString(),
59+
signer,
60+
});
61+
62+
setResults(resultsData);
63+
} catch (err) {
64+
// eslint-disable-next-line no-console
65+
console.error("Error fetching results:", err);
66+
}
67+
})();
68+
}, [pollId, signer, checkIsTallied, tallied]);
69+
70+
return { results, tallied };
71+
};

plugins/maciVoting/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,22 @@ import ProposalCreate from "./pages/new";
33
import ProposalList from "./pages/proposal-list";
44
import ProposalDetail from "./pages/proposal";
55
import { useUrl } from "@/hooks/useUrl";
6-
import type { ReactNode } from "react";
6+
import { useEffect, type ReactNode } from "react";
77
import { MaciProvider } from "./contexts/MaciContext";
88
import { CoordinatorProvider } from "./contexts/CoordinatorContext";
9+
import { useSwitchToChain } from "@/hooks/useSwitchChain";
910
export default function PluginPage() {
11+
const { isCorrectChain, switchToChain } = useSwitchToChain();
1012
// Select the inner pages to display depending on the URL hash
1113
const { hash } = useUrl();
1214
let content: ReactNode;
1315

16+
useEffect(() => {
17+
if (!isCorrectChain) {
18+
switchToChain();
19+
}
20+
}, [isCorrectChain, switchToChain]);
21+
1422
if (!hash || hash === "#/") content = <ProposalList />;
1523
else if (hash === "#/new") content = <ProposalCreate />;
1624
else if (hash.startsWith("#/proposals/")) {

0 commit comments

Comments
 (0)