From 837dd58c6115bdcab3928bc88c35043bb52a03c8 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 30 Nov 2020 01:50:32 +0100 Subject: [PATCH] Recent payouts toggle (#4108) * Recent payouts toggle * operator exposure * media--* * extra toggle padding * align --- .../page-staking/src/Targets/Validator.tsx | 4 +-- packages/page-staking/src/Targets/index.tsx | 35 +++++++++++++++---- packages/page-staking/src/index.tsx | 4 ++- packages/react-hooks/src/index.ts | 1 + packages/react-hooks/src/useBlocksPerDays.ts | 23 ++++++++++++ 5 files changed, 57 insertions(+), 10 deletions(-) create mode 100644 packages/react-hooks/src/useBlocksPerDays.ts diff --git a/packages/page-staking/src/Targets/Validator.tsx b/packages/page-staking/src/Targets/Validator.tsx index 09de9f05c7..485e4c8776 100644 --- a/packages/page-staking/src/Targets/Validator.tsx +++ b/packages/page-staking/src/Targets/Validator.tsx @@ -121,7 +121,7 @@ function Validator ({ allSlashes, canSelect, filterName, info, isNominated, isSe )} {numNominators || ''} - + { isCommission ? `${commissionPer.toFixed(2)}%` @@ -129,7 +129,7 @@ function Validator ({ allSlashes, canSelect, filterName, info, isNominated, isSe } {!bondTotal.isZero() && } - {!bondOwn.isZero() && } + {!bondOwn.isZero() && } {!bondOther.isZero() && } {(stakedReturnCmp > 0) && <>{stakedReturnCmp.toFixed(2)}%} diff --git a/packages/page-staking/src/Targets/index.tsx b/packages/page-staking/src/Targets/index.tsx index b899453261..72b6871586 100644 --- a/packages/page-staking/src/Targets/index.tsx +++ b/packages/page-staking/src/Targets/index.tsx @@ -9,7 +9,7 @@ import BN from 'bn.js'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import styled from 'styled-components'; import { Button, Icon, Table, Toggle } from '@polkadot/react-components'; -import { useApi, useAvailableSlashes, useCall } from '@polkadot/react-hooks'; +import { useApi, useAvailableSlashes, useBlocksPerDays, useCall } from '@polkadot/react-hooks'; import ElectionBanner from '../ElectionBanner'; import Filtering from '../Filtering'; @@ -31,10 +31,13 @@ interface Props { } interface Flags { + daysPayout: BN; + isBabe: boolean; maxPaid: BN | undefined; withElected: boolean; withGroup: boolean; withIdentity: boolean; + withPayout: boolean; withoutComm: boolean; withoutOver: boolean; } @@ -46,15 +49,18 @@ interface SortState { const CLASSES: Record = { rankBondOther: 'media--1600', + rankBondOwn: 'media--900', + rankComm: 'media--1100', rankNumNominators: 'media--1200' }; const MAX_COMM_FILTER = 20; +const MAX_DAYS = 7; const SORT_KEYS = ['rankNumNominators', 'rankComm', 'rankBondTotal', 'rankBondOwn', 'rankBondOther', 'rankOverall']; -function filterValidators (validators: ValidatorInfo[], allIdentity: Record, { maxPaid, withElected, withGroup, withIdentity, withoutComm, withoutOver }: Flags): ValidatorInfo[] { +function filterValidators (validators: ValidatorInfo[], allIdentity: Record, { daysPayout, isBabe, maxPaid, withElected, withGroup, withIdentity, withPayout, withoutComm, withoutOver }: Flags): ValidatorInfo[] { const parentIds: string[] = []; - return validators.filter(({ accountId, commissionPer, isElected, isFavorite, numNominators }): boolean => { + return validators.filter(({ accountId, commissionPer, isElected, isFavorite, lastPayout, numNominators }): boolean => { if (isFavorite) { return true; } @@ -63,8 +69,9 @@ function filterValidators (validators: ValidatorInfo[], allIdentity: Record([]); const [{ isQueryFiltered, nameFilter }, setNameFilter] = useState({ isQueryFiltered: false, nameFilter: '' }); const [withElected, setWithElected] = useState(false); const [withGroup, setWithGroup] = useState(true); const [withIdentity, setWithIdentity] = useState(false); + const [withPayout, setWithPayout] = useState(true); const [withoutComm, setWithoutComm] = useState(true); const [withoutOver, setWithoutOver] = useState(true); const [{ sortBy, sortFromMax }, setSortBy] = useState({ sortBy: 'rankOverall', sortFromMax: true }); @@ -158,15 +167,18 @@ function Targets ({ className = '', isInElection, ownStashes, targets: { avgStak const flags = useMemo( () => ({ + daysPayout, + isBabe: !!api.consts.babe, isQueryFiltered, maxPaid: api.consts.staking?.maxNominatorRewardedPerValidator, withElected, withGroup, withIdentity, + withPayout, withoutComm, withoutOver }), - [api, isQueryFiltered, withElected, withGroup, withIdentity, withoutComm, withoutOver] + [api, daysPayout, isQueryFiltered, withElected, withGroup, withIdentity, withPayout, withoutComm, withoutOver] ); const filtered = useMemo( @@ -242,7 +254,7 @@ function Targets ({ className = '', isInElection, ownStashes, targets: { avgStak > ('limit single operator exposure')} + label={t('limit operator exposure')} onChange={setWithGroup} value={withGroup} /> @@ -252,6 +264,15 @@ function Targets ({ className = '', isInElection, ownStashes, targets: { avgStak onChange={setWithoutComm} value={withoutComm} /> + {api.consts.babe && ( + // FIXME have some sane era defaults for Aura + ('recent payouts')} + onChange={setWithPayout} + value={withPayout} + /> + )} ('no oversubscribed')} @@ -266,7 +287,7 @@ function Targets ({ className = '', isInElection, ownStashes, targets: { avgStak /> - ), [nameFilter, _setNameFilter, t, withElected, withGroup, withIdentity, withoutComm, withoutOver]); + ), [api, nameFilter, _setNameFilter, t, withElected, withGroup, withIdentity, withPayout, withoutComm, withoutOver]); const displayList = isQueryFiltered ? validators diff --git a/packages/page-staking/src/index.tsx b/packages/page-staking/src/index.tsx index cdecfe5810..336a390e9a 100644 --- a/packages/page-staking/src/index.tsx +++ b/packages/page-staking/src/index.tsx @@ -194,7 +194,9 @@ export default React.memo(styled(StakingApp)(({ theme }: ThemeProps) => ` } .staking--optionsBar { - text-align: right; + margin: 0.5rem 0 1rem; + text-align: center; + white-space: normal; .staking--buttonToggle { display: inline-block; diff --git a/packages/react-hooks/src/index.ts b/packages/react-hooks/src/index.ts index 65071bcbfd..0aaa05c7df 100644 --- a/packages/react-hooks/src/index.ts +++ b/packages/react-hooks/src/index.ts @@ -8,6 +8,7 @@ export { useAddresses } from './useAddresses'; export { useApi } from './useApi'; export { useAvailableSlashes } from './useAvailableSlashes'; export { useBlockTime } from './useBlockTime'; +export { useBlocksPerDays } from './useBlocksPerDays'; export { useCacheKey } from './useCacheKey'; export { useCall } from './useCall'; export { useContracts } from './useContracts'; diff --git a/packages/react-hooks/src/useBlocksPerDays.ts b/packages/react-hooks/src/useBlocksPerDays.ts new file mode 100644 index 0000000000..566c8e8009 --- /dev/null +++ b/packages/react-hooks/src/useBlocksPerDays.ts @@ -0,0 +1,23 @@ +// Copyright 2017-2020 @polkadot/app-democracy authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import BN from 'bn.js'; +import { useMemo } from 'react'; +import { useApi } from '@polkadot/react-hooks'; + +const DEFAULT_TIME = new BN(6000); +const A_DAY = new BN(24 * 60 * 60 * 1000); + +export function useBlocksPerDays (days = 1): BN { + const { api } = useApi(); + + return useMemo( + () => A_DAY.muln(days).div( + api.consts.babe?.expectedBlockTime || + api.consts.difficulty?.targetBlockTime || + api.consts.timestamp?.minimumPeriod.muln(2) || + DEFAULT_TIME + ), + [api, days] + ); +}