Apply Vote conviction (#2197)
This commit is contained in:
parent
f2e85b9c98
commit
45bc5fc6f1
@ -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;
|
||||
}, {
|
||||
|
||||
@ -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<string | null>(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
|
||||
<VoteAccount onChange={setAccountId} />
|
||||
<VoteToggle
|
||||
onChange={_onChangeVote}
|
||||
value={voteValue}
|
||||
value={aye}
|
||||
/>
|
||||
<Dropdown
|
||||
help={t('The conviction to use for this vote, with an appropriate lock period.')}
|
||||
label={t('conviction')}
|
||||
onChange={setConviction}
|
||||
options={convictionOpts}
|
||||
value={conviction}
|
||||
/>
|
||||
</Modal.Content>
|
||||
<VoteActions
|
||||
accountId={accountId}
|
||||
onClick={_toggleVoting}
|
||||
params={[referendumId, voteValue]}
|
||||
onClick={toggleVoting}
|
||||
params={[referendumId, { aye, conviction }]}
|
||||
tx='democracy.vote'
|
||||
/>
|
||||
</Modal>
|
||||
@ -60,7 +83,7 @@ export default function Voting ({ proposal, referendumId }: Props): React.ReactE
|
||||
icon='check'
|
||||
isPrimary
|
||||
label={t('Vote')}
|
||||
onClick={_toggleVoting}
|
||||
onClick={toggleVoting}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -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<Props> {
|
||||
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<Props> {
|
||||
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 (
|
||||
<Bare
|
||||
@ -43,11 +64,22 @@ export default function Vote (props: Props): React.ReactElement<Props> {
|
||||
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 && (
|
||||
<Dropdown
|
||||
className='full'
|
||||
defaultValue={defaultConv}
|
||||
isDisabled={isDisabled}
|
||||
isError={isError}
|
||||
label={t('conviction: Conviction')}
|
||||
options={optConv}
|
||||
withLabel={withLabel}
|
||||
/>
|
||||
)}
|
||||
</Bare>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user