import * as React from "react"; import { compose } from "redux"; import { BigNumber, TxHash } from "@joincivil/typescript-types"; import { TwoStepEthTransaction } from "@joincivil/core"; import { ChallengeRevealVoteCard as ChallengeRevealVoteCardComponent, ModalContent, ModalUnorderedList, ModalListItem, RevealVoteSuccessIcon, PhaseWithExpiryProps, ListingDetailPhaseCardComponentProps, ChallengePhaseProps, RevealVoteProps, } from "@joincivil/components"; import { getLocalDateTimeStrings, urlConstants as links, Parameters } from "@joincivil/utils"; import { CivilHelper, CivilHelperContext } from "../../apis/CivilHelper"; import { fetchSalt } from "../../helpers/salt"; import { fetchVote } from "../../helpers/vote"; import { ChallengeContainerProps, connectChallengePhase, ParametersProps } from "../utility/HigherOrderComponents"; import { InjectedTransactionStatusModalProps, hasTransactionStatusModals, TransactionStatusModalContentMap, } from "../utility/TransactionStatusModalsHOC"; import { ChallengeDetailProps, ChallengeVoteState } from "./ChallengeDetail"; const ChallengeRevealVoteCard = compose< React.ComponentType< ListingDetailPhaseCardComponentProps & PhaseWithExpiryProps & ChallengePhaseProps & ChallengeContainerProps & RevealVoteProps > >(connectChallengePhase)(ChallengeRevealVoteCardComponent); enum TransactionTypes { REVEAL_VOTE = "REVEAL_VOTE", } const transactionLabels = { [TransactionTypes.REVEAL_VOTE]: "Confirm Vote", }; const transactionRejectionContent = { [TransactionTypes.REVEAL_VOTE]: [ "Your vote was not confirmed", "To confirm your vote, you need to confirm the transaction in your MetaMask wallet.", ], }; const transactionErrorContent = { [TransactionTypes.REVEAL_VOTE]: [ "The was an problem with revealing your vote", <> Please check the following and retry your transaction Your vote selection matches the vote you committed Your secret phrase is correct , ], }; const transactionStatusModalConfig = { transactionLabels, transactionRejectionContent, transactionErrorContent, }; interface RevealCardKeyState { key: number; } class ChallengeRevealVote extends React.Component< ChallengeDetailProps & InjectedTransactionStatusModalProps & ParametersProps, ChallengeVoteState & RevealCardKeyState > { public static contextType = CivilHelperContext; public context: CivilHelper; constructor(props: ChallengeDetailProps & InjectedTransactionStatusModalProps & ParametersProps) { super(props); this.state = { voteOption: this.getVoteOption(), salt: fetchSalt(this.props.challengeID, this.props.user), isReviewVoteModalOpen: false, numTokens: undefined, key: new Date().valueOf(), }; } public componentWillMount(): void { const transactionSuccessContent = this.getTransactionSuccessContent(); this.props.setTransactions(this.getTransactions()); this.props.setTransactionStatusModalConfig({ transactionSuccessContent, }); this.props.setHandleTransactionSuccessButtonClick(this.handleRevealVoteSuccessClose); } public render(): JSX.Element | null { const endTime = this.props.challenge.poll.revealEndDate.toNumber(); const phaseLength = this.props.parameters.get(Parameters.revealStageLen).toNumber(); const secondaryPhaseLength = this.props.parameters.get(Parameters.commitStageLen).toNumber(); const challenge = this.props.challenge; const userHasRevealedVote = this.props.userChallengeData && !!this.props.userChallengeData.didUserReveal; const userHasCommittedVote = this.props.userChallengeData && !!this.props.userChallengeData.didUserCommit; const transactions = this.getTransactions(); if (!challenge) { return null; } return ( <> ); } private getVoteOption(): string | undefined { const fetchedVote = fetchVote(this.props.challengeID, this.props.user); let voteOption; if (fetchedVote) { voteOption = fetchedVote.toString(); } return voteOption; } private getTransactionSuccessContent = (): TransactionStatusModalContentMap => { const endTime = getLocalDateTimeStrings(this.props.challenge.poll.revealEndDate.toNumber()); return { [TransactionTypes.REVEAL_VOTE]: [ <>
Thanks for confirming your vote.
, <> We are still waiting for all voters to confirm their votes. Please check back after{" "} {endTime[0]} {endTime[1]} {" "} to see voting results. Thank you for your patience! , ], }; }; private getTransactions = (): any => { return [ { transaction: async () => { this.props.updateTransactionStatusModalsState({ isWaitingTransactionModalOpen: true, isTransactionProgressModalOpen: false, isTransactionSuccessModalOpen: false, transactionType: TransactionTypes.REVEAL_VOTE, }); return this.revealVoteOnChallenge(); }, handleTransactionHash: (txHash: TxHash) => { this.props.updateTransactionStatusModalsState({ isWaitingTransactionModalOpen: false, isTransactionProgressModalOpen: true, }); }, postTransaction: () => { this.props.updateTransactionStatusModalsState({ isWaitingTransactionModalOpen: false, isTransactionProgressModalOpen: false, isTransactionSuccessModalOpen: true, }); }, handleTransactionError: this.props.handleTransactionError, }, ]; }; private handleRevealVoteSuccessClose = (): void => { this.props.updateTransactionStatusModalsState({ isTransactionSuccessModalOpen: false }); this.setState({ isReviewVoteModalOpen: false, key: new Date().valueOf() }); }; private revealVoteOnChallenge = async (): Promise> => { const voteOption: BigNumber = new BigNumber(this.state.voteOption as string); const salt: BigNumber = new BigNumber(this.state.salt as string); return this.context.revealVote(this.props.challengeID, voteOption, salt); }; private updateRevealVoteState = (data: any, callback?: () => void): void => { if (callback) { this.setState({ ...data }, callback); } else { this.setState({ ...data }); } }; } export default compose>( hasTransactionStatusModals(transactionStatusModalConfig), )(ChallengeRevealVote);