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]
+ );
+}
|