From db471d988ad10bbd168372e045f18cc0414b59c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rn=20Andre=20Tangen=20=40gorillatron?= Date: Tue, 28 Nov 2023 12:16:47 +0100 Subject: [PATCH] implement ability to re cast votes during voting period if already voted --- components/court/CourtVoteForm.tsx | 11 ++++-- components/court/CourtVoteRevealForm.tsx | 4 +-- lib/state/court/useVoteOutcome.ts | 16 +++++++-- pages/court/[caseid].tsx | 45 ++++++++++++++++++++---- 4 files changed, 63 insertions(+), 13 deletions(-) diff --git a/components/court/CourtVoteForm.tsx b/components/court/CourtVoteForm.tsx index 6d530f606..11680b0ca 100644 --- a/components/court/CourtVoteForm.tsx +++ b/components/court/CourtVoteForm.tsx @@ -21,11 +21,13 @@ import { HiOutlineDocumentDownload } from "react-icons/hi"; export type CourtVoteFormProps = { caseId: number; market: FullMarketFragment; + onVote?: () => void; }; export const CourtVoteForm: React.FC = ({ caseId, market, + onVote, }) => { const [sdk, id] = useSdkv2(); const queryClient = useQueryClient(); @@ -65,6 +67,7 @@ export const CourtVoteForm: React.FC = ({ commitVote(); queryClient.invalidateQueries([id, voteDrawsRootKey, caseId]); queryClient.invalidateQueries([id, voteDrawsRootKey, "all"]); + onVote?.(); }, }, ); @@ -82,7 +85,7 @@ export const CourtVoteForm: React.FC = ({
{ @@ -142,8 +145,10 @@ export const CourtVoteForm: React.FC = ({ vote_item = VoteItem::Outcome(OutcomeReport::Categorical( - {vote.CategoricalOutcome[1]})) {"->"}{" "} - {market.categories?.[vote.CategoricalOutcome[1]].ticker} + {vote?.CategoricalOutcome[1] ?? "null"})) {"->"}{" "} + {vote + ? market.categories?.[vote.CategoricalOutcome[1]]?.ticker + : "--"}
salt ={" "} diff --git a/components/court/CourtVoteRevealForm.tsx b/components/court/CourtVoteRevealForm.tsx index 84d66b1b3..c37b5fbdb 100644 --- a/components/court/CourtVoteRevealForm.tsx +++ b/components/court/CourtVoteRevealForm.tsx @@ -54,7 +54,7 @@ export const CourtVoteRevealForm: React.FC = ({ const { send, isReady, isLoading, isBroadcasting } = useExtrinsic( () => { - if (isRpcSdk(sdk) && salt) { + if (isRpcSdk(sdk) && salt && vote) { return sdk.api.tx.court.revealVote( caseId, { @@ -128,7 +128,7 @@ export const CourtVoteRevealForm: React.FC = ({
void; commitVote: () => void; + unCommitVote: () => void; }; export type UseCourtVoteProps = { caseId: number; marketId: number; - defaultValue: CategoricalAssetId; + defaultValue?: CategoricalAssetId; }; const courtVotesAtom = persistentAtom< @@ -70,10 +71,21 @@ export const useCourtVote = ({ })); }; + const unCommitVote = () => { + setCourtVotes((prev) => ({ + ...prev, + [id]: { + ...prev[id], + committed: false, + }, + })); + }; + return { vote: vote?.assetId ?? defaultValue, committed: vote?.committed ?? false, setVote, commitVote, + unCommitVote, }; }; diff --git a/pages/court/[caseid].tsx b/pages/court/[caseid].tsx index 1e6a29773..06ad90bde 100644 --- a/pages/court/[caseid].tsx +++ b/pages/court/[caseid].tsx @@ -30,9 +30,9 @@ import { useRouter } from "next/router"; import { NextPage } from "next/types"; import NotFoundPage from "pages/404"; import { IGetPlaiceholderReturn, getPlaiceholder } from "plaiceholder"; -import { useMemo } from "react"; +import { useMemo, useState } from "react"; import { AiOutlineEye } from "react-icons/ai"; -import { LuVote } from "react-icons/lu"; +import { LuReplace, LuVote } from "react-icons/lu"; import { PiBooks } from "react-icons/pi"; import { DAY_SECONDS, @@ -43,6 +43,8 @@ import { } from "lib/constants"; import { CourtAppealForm } from "components/court/CourtAppealForm"; import { CourtDocsArticle } from "components/court/learn/CourtDocsArticle"; +import { useCourtVote } from "lib/state/court/useVoteOutcome"; +import { useConfirmation } from "lib/state/confirm-modal/useConfirmation"; const QuillViewer = dynamic(() => import("../../components/ui/QuillViewer"), { ssr: false, @@ -160,28 +162,59 @@ const CasePage: NextPage = ({ } }, [time, market, courtCase]); + const { prompt } = useConfirmation(); + const [recastVoteEnabled, setRecastVoteEnabled] = useState(false); + + const { unCommitVote } = useCourtVote({ + caseId, + marketId: market.marketId, + }); + + const onClickRecastVote = async () => { + if ( + await prompt({ + title: "Recast Vote", + description: "Are you sure you want to recast your vote?", + }) + ) { + unCommitVote(); + setRecastVoteEnabled(true); + } + }; + + const onVote = () => { + setRecastVoteEnabled(false); + }; + const actionSection = ( <> {stage?.type === "vote" && ( <> - {isDrawnJuror && ( + {(isDrawnJuror || recastVoteEnabled) && ( <> - + )} - {hasSecretVote && ( + {hasSecretVote && !recastVoteEnabled && (

You have voted

-

+

Your vote is secret during voting, but when court goes into aggregation you can reveal your vote to the public by coming back to this page.

+
)}