import * as React from "react";
import { compose } from "redux";
import { BigNumber, TxHash } from "@joincivil/typescript-types";
import { TwoStepEthTransaction } from "@joincivil/core";
import {
ChallengeProposalRevealVote as ChallengeProposalRevealVoteComponent,
TChallengeProposalRevealVoteProps as ChallengeProposalRevealVoteComponentProps,
ModalContent,
ModalUnorderedList,
ModalListItem,
} from "@joincivil/components";
import { getLocalDateTimeStrings, urlConstants as links } from "@joincivil/utils";
import {
InjectedTransactionStatusModalProps,
hasTransactionStatusModals,
TransactionStatusModalContentMap,
} from "../utility/TransactionStatusModalsHOC";
import { fetchSalt } from "../../helpers/salt";
import { fetchVote } from "../../helpers/vote";
import { ChallengeDetailProps, ChallengeVoteState } from "./ChallengeProposalDetail";
import { CivilHelperContext, CivilHelper } from "../../apis/CivilHelper";
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,
};
class ChallengeProposalRevealVote extends React.Component<
ChallengeDetailProps & ChallengeProposalRevealVoteComponentProps & InjectedTransactionStatusModalProps,
ChallengeVoteState
> {
public static contextType = CivilHelperContext;
public context: CivilHelper;
constructor(
props: ChallengeDetailProps & ChallengeProposalRevealVoteComponentProps & InjectedTransactionStatusModalProps,
) {
super(props);
this.state = {
isReviewVoteModalOpen: false,
voteOption: this.getVoteOption(),
salt: fetchSalt(this.props.challengeID, this.props.user),
numTokens: undefined,
};
}
public componentWillMount(): void {
this.props.setTransactions(this.getTransactions());
this.props.setHandleTransactionSuccessButtonClick(this.props.handleClose);
const transactionSuccessContent = this.getTransactionSuccessContent();
this.props.setTransactionStatusModalConfig({
transactionSuccessContent,
});
}
public render(): JSX.Element {
const revealVoteProps = {
...this.props,
onInputChange: this.updateRevealVoteState,
voteOption: this.state.voteOption,
salt: this.state.salt,
challengeID: this.props.challengeID.toString(),
transactions: this.getTransactions(),
votingSmartContractFaqURL: links.FAQ_WHAT_IS_PLCR_CONTRACT,
postExecuteTransactions: this.onRevealVoteSuccess,
};
return ;
}
private getVoteOption(): string | undefined {
const fetchedVote = fetchVote(this.props.challengeID, this.props.user);
let voteOption;
if (fetchedVote) {
voteOption = fetchedVote.toString();
}
return voteOption;
}
private updateRevealVoteState = (data: any, callback?: () => void): void => {
if (callback) {
this.setState({ ...data }, callback);
} else {
this.setState({ ...data });
}
};
private getTransactions = (): any[] => {
return [
{
transaction: async () => {
this.props.updateTransactionStatusModalsState({
isWaitingTransactionModalOpen: true,
isTransactionProgressModalOpen: false,
isTransactionSuccessModalOpen: false,
isTransactionErrorModalOpen: false,
isTransactionRejectionModalOpen: false,
transactionType: TransactionTypes.REVEAL_VOTE,
});
return this.revealVoteOnChallenge();
},
handleTransactionHash: (txHash: TxHash) => {
this.props.updateTransactionStatusModalsState({
isWaitingTransactionModalOpen: false,
isTransactionProgressModalOpen: true,
});
},
handleTransactionError: this.props.handleTransactionError,
},
];
};
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 onRevealVoteSuccess = (): void => {
this.props.updateTransactionStatusModalsState({
isWaitingTransactionModalOpen: false,
isTransactionProgressModalOpen: false,
isTransactionSuccessModalOpen: true,
});
this.props.handleClose();
};
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);
};
}
export default compose>(
hasTransactionStatusModals(transactionStatusModalConfig),
)(ChallengeProposalRevealVote);