From 45bc5fc6f11dcd03ca31a4f4535585fc3e506210 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Fri, 24 Jan 2020 16:20:57 +0100 Subject: [PATCH] Apply Vote conviction (#2197) --- .../app-democracy/src/Overview/Referendum.tsx | 11 ++-- .../app-democracy/src/Overview/Voting.tsx | 43 +++++++++++---- packages/react-params/src/Param/Vote.tsx | 54 +++++++++++++++---- 3 files changed, 84 insertions(+), 24 deletions(-) diff --git a/packages/app-democracy/src/Overview/Referendum.tsx b/packages/app-democracy/src/Overview/Referendum.tsx index 45ffeae11a..5ef61df7a5 100644 --- a/packages/app-democracy/src/Overview/Referendum.tsx +++ b/packages/app-democracy/src/Overview/Referendum.tsx @@ -51,16 +51,21 @@ function Referendum ({ className, idNumber, value }: Props): React.ReactElement< useEffect((): void => { if (votesFor) { const newState: State = votesFor.reduce((state, { balance, vote }): State => { + const isDefault = vote.conviction.index === 0; + const counted = balance + .muln(isDefault ? 1 : vote.conviction.index) + .divn(isDefault ? 10 : 1); + if (vote.isAye) { state.voteCountAye++; - state.votedAye = state.votedAye.add(balance); + state.votedAye = state.votedAye.add(counted); } else { state.voteCountNay++; - state.votedNay = state.votedNay.add(balance); + state.votedNay = state.votedNay.add(counted); } state.voteCount++; - state.votedTotal = state.votedTotal.add(balance); + state.votedTotal = state.votedTotal.add(counted); return state; }, { diff --git a/packages/app-democracy/src/Overview/Voting.tsx b/packages/app-democracy/src/Overview/Voting.tsx index ab155f4cdd..298305fa82 100644 --- a/packages/app-democracy/src/Overview/Voting.tsx +++ b/packages/app-democracy/src/Overview/Voting.tsx @@ -4,13 +4,18 @@ import { PropIndex, Proposal } from '@polkadot/types/interfaces'; -import React, { useState } from 'react'; -import { Button, Modal, ProposedAction, VoteAccount, VoteActions, VoteToggle } from '@polkadot/react-components'; -import { useAccounts } from '@polkadot/react-hooks'; +import React, { useMemo, useState } from 'react'; +import { Button, Dropdown, Modal, ProposedAction, VoteAccount, VoteActions, VoteToggle } from '@polkadot/react-components'; +import { useAccounts, useToggle } from '@polkadot/react-hooks'; import { isBoolean } from '@polkadot/util'; import { useTranslation } from '../translate'; +interface Option { + text: string; + value: number; +} + interface Props { proposal?: Proposal; referendumId: PropIndex; @@ -20,14 +25,25 @@ export default function Voting ({ proposal, referendumId }: Props): React.ReactE const { t } = useTranslation(); const { hasAccounts } = useAccounts(); const [accountId, setAccountId] = useState(null); - const [isVotingOpen, setIsVotingOpen] = useState(false); - const [voteValue, setVoteValue] = useState(true); + const [conviction, setConviction] = useState(0); + const [isVotingOpen, toggleVoting] = useToggle(); + const [aye, setVoteValue] = useState(true); + const convictionOpts = useMemo((): Option[] => { + return [ + { text: t('0.1x of voting balance, no lockup period'), value: 0 }, + { text: t('1x of voting balance, locked for 1x enactment'), value: 1 }, + { text: t('2x of voting balance, locked for 2x enactment'), value: 2 }, + { text: t('3x of voting balance, locked for 4x enactment'), value: 3 }, + { text: t('4x of voting balance, locked for 8x enactment'), value: 4 }, + { text: t('5x of voting balance, locked for 16x enactment'), value: 5 }, + { text: t('6x of voting balance, locked for 32x enactment'), value: 6 } + ]; + }, [t]); if (!hasAccounts) { return null; } - const _toggleVoting = (): void => setIsVotingOpen(!isVotingOpen); const _onChangeVote = (vote?: boolean): void => setVoteValue(isBoolean(vote) ? vote : true); return ( @@ -45,13 +61,20 @@ export default function Voting ({ proposal, referendumId }: Props): React.ReactE + @@ -60,7 +83,7 @@ export default function Voting ({ proposal, referendumId }: Props): React.ReactE icon='check' isPrimary label={t('Vote')} - onClick={_toggleVoting} + onClick={toggleVoting} /> ); diff --git a/packages/react-params/src/Param/Vote.tsx b/packages/react-params/src/Param/Vote.tsx index 9c6e885027..9dc8595087 100644 --- a/packages/react-params/src/Param/Vote.tsx +++ b/packages/react-params/src/Param/Vote.tsx @@ -5,18 +5,19 @@ import { Props } from '../types'; import BN from 'bn.js'; -import React from 'react'; +import React, { useMemo } from 'react'; import { GenericVote } from '@polkadot/types'; import { Dropdown } from '@polkadot/react-components'; +import { useTranslation } from '../translate'; import Bare from './Bare'; -const options = [ - { text: 'Nay', value: 0 }, - { text: 'Aye', value: -1 } -]; +interface Option { + text: string; + value: number; +} -function onChange ({ onChange }: Props): (_: number) => void { +function doChange (onChange?: (value: any) => void): (_: number) => void { return function (value: number): void { onChange && onChange({ isValid: true, @@ -25,13 +26,33 @@ function onChange ({ onChange }: Props): (_: number) => void { }; } -export default function Vote (props: Props): React.ReactElement { - const { className, defaultValue: { value }, isDisabled, isError, label, style, withLabel } = props; +export default function Vote ({ className, defaultValue: { value }, isDisabled, isError, onChange, style, withLabel }: Props): React.ReactElement { + const { t } = useTranslation(); + const optAye = useMemo((): Option[] => { + return [ + { text: t('Nay'), value: 0 }, + { text: t('Aye'), value: -1 } + ]; + }, [t]); + const optConv = useMemo((): Option[] => { + return [ + { text: t('None'), value: 0 }, + { text: t('Locked1x'), value: 1 }, + { text: t('Locked2x'), value: 2 }, + { text: t('Locked3x'), value: 3 }, + { text: t('Locked4x'), value: 4 }, + { text: t('Locked5x'), value: 5 }, + { text: t('Locked6x'), value: 6 } + ]; + }, [t]); const defaultValue = value instanceof BN ? value.toNumber() : value instanceof GenericVote ? (value.isAye ? -1 : 0) : value as number; + const defaultConv = value instanceof GenericVote + ? value.conviction.index + : 0; return ( { defaultValue={defaultValue} isDisabled={isDisabled} isError={isError} - label={label} - options={options} - onChange={onChange(props)} + label={t('aye: bool')} + options={optAye} + onChange={doChange(onChange)} withLabel={withLabel} /> + {isDisabled && ( + + )} ); }