From f86cc1a689a8a0d6472607a5daa046788dd97ba1 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Fri, 4 Dec 2020 16:21:50 +0100 Subject: [PATCH] Small target opts (incl. non-selected sorting) (#4159) * Small target opts (incl. non-selected sorting) * Remove last dangling validatorPayment --- packages/page-staking/src/Targets/Summary.tsx | 18 +++++- .../page-staking/src/Targets/Validator.tsx | 10 +--- packages/page-staking/src/Targets/index.tsx | 5 +- packages/page-staking/src/types.ts | 5 -- packages/page-staking/src/useSortedTargets.ts | 58 ++++++------------- packages/react-components/src/AccountName.tsx | 4 ++ .../react-components/src/AddressSmall.tsx | 4 +- 7 files changed, 42 insertions(+), 62 deletions(-) diff --git a/packages/page-staking/src/Targets/Summary.tsx b/packages/page-staking/src/Targets/Summary.tsx index a2b82ee9ea..9319aed6c7 100644 --- a/packages/page-staking/src/Targets/Summary.tsx +++ b/packages/page-staking/src/Targets/Summary.tsx @@ -4,7 +4,11 @@ import BN from 'bn.js'; import React, { useMemo } from 'react'; +import type { DeriveSessionIndexes } from '@polkadot/api-derive/types'; +import type { Option } from '@polkadot/types'; +import type { Balance } from '@polkadot/types/interfaces'; import { CardSummary, SummaryBox } from '@polkadot/react-components'; +import { useApi, useCall } from '@polkadot/react-hooks'; import { FormatBalance } from '@polkadot/react-query'; import { useTranslation } from '../translate'; @@ -12,7 +16,6 @@ import { useTranslation } from '../translate'; interface Props { avgStaked?: BN; lowStaked?: BN; - lastReward?: BN; numNominators?: number; numValidators?: number; stakedReturn: number; @@ -20,8 +23,19 @@ interface Props { totalStaked?: BN; } -function Summary ({ avgStaked, lastReward, lowStaked, numNominators, numValidators, stakedReturn, totalIssuance, totalStaked }: Props): React.ReactElement { +const transformReward = { + transform: (optBalance: Option) => optBalance.unwrapOrDefault() +}; + +const transformEra = { + transform: ({ activeEra }: DeriveSessionIndexes) => activeEra.gtn(0) ? activeEra.subn(1) : undefined +}; + +function Summary ({ avgStaked, lowStaked, numNominators, numValidators, stakedReturn, totalIssuance, totalStaked }: Props): React.ReactElement { const { t } = useTranslation(); + const { api } = useApi(); + const lastEra = useCall(api.derive.session.indexes, undefined, transformEra); + const lastReward = useCall(lastEra && api.query.staking.erasValidatorReward, [lastEra], transformReward); const progressStake = useMemo( () => totalIssuance && totalStaked && totalStaked.gtn(0) diff --git a/packages/page-staking/src/Targets/Validator.tsx b/packages/page-staking/src/Targets/Validator.tsx index 4a5a4a1f3e..59b1c6067b 100644 --- a/packages/page-staking/src/Targets/Validator.tsx +++ b/packages/page-staking/src/Targets/Validator.tsx @@ -67,7 +67,7 @@ function Validator ({ allSlashes, canSelect, filterName, info, isNominated, isSe return null; } - const { accountId, bondOther, bondOwn, bondTotal, commissionPer, isCommission, isElected, isFavorite, key, lastPayout, numNominators, rankOverall, stakedReturnCmp, validatorPayment } = info; + const { accountId, bondOther, bondOwn, bondTotal, commissionPer, isCommission, isElected, isFavorite, key, lastPayout, numNominators, rankOverall, stakedReturnCmp } = info; return ( @@ -125,13 +125,7 @@ function Validator ({ allSlashes, canSelect, filterName, info, isNominated, isSe {numNominators || ''} {nominatedBy.length || ''} - - { - isCommission - ? `${commissionPer.toFixed(2)}%` - : - } - + {isCommission && `${commissionPer.toFixed(2)}%`} {!bondTotal.isZero() && } {!bondOwn.isZero() && } {!bondOther.isZero() && } diff --git a/packages/page-staking/src/Targets/index.tsx b/packages/page-staking/src/Targets/index.tsx index 5f40cd1c1b..c9a1b07c18 100644 --- a/packages/page-staking/src/Targets/index.tsx +++ b/packages/page-staking/src/Targets/index.tsx @@ -169,7 +169,7 @@ function selectProfitable (list: ValidatorInfo[]): string[] { return result; } -function Targets ({ className = '', isInElection, ownStashes, targets: { avgStaked, inflation: { stakedReturn }, lastReward, lowStaked, medianComm, nominators, totalIssuance, totalStaked, validatorIds, validators }, toggleFavorite }: Props): React.ReactElement { +function Targets ({ className = '', isInElection, ownStashes, targets: { avgStaked, inflation: { stakedReturn }, lowStaked, medianComm, nominators, totalIssuance, totalStaked, validatorIds, validators }, toggleFavorite }: Props): React.ReactElement { const { t } = useTranslation(); const { api } = useApi(); const allSlashes = useAvailableSlashes(); @@ -270,7 +270,7 @@ function Targets ({ className = '', isInElection, ownStashes, targets: { avgStak <>{labelsRef.current[header]}, `${sorted ? `isClickable ${sortBy === header ? 'highlight--border' : ''} number` : 'number'} ${CLASSES[header] || ''}`, 1, - () => _sort(header as 'rankComm') + () => _sort(header as 'rankOverall') ]), [], [] @@ -337,7 +337,6 @@ function Targets ({ className = '', isInElection, ownStashes, targets: { avgStak
ValidatorInfo { @@ -62,24 +58,18 @@ function sortValidators (list: ValidatorInfo[]): ValidatorInfo[] { .map(mapIndex('rankBondOwn')) .sort((a, b) => b.bondTotal.cmp(a.bondTotal)) .map(mapIndex('rankBondTotal')) - .sort((a, b) => b.validatorPayment.cmp(a.validatorPayment)) - .map(mapIndex('rankPayment')) + // .sort((a, b) => b.validatorPayment.cmp(a.validatorPayment)) + // .map(mapIndex('rankPayment')) .sort((a, b) => a.stakedReturnCmp - b.stakedReturnCmp) .map(mapIndex('rankReward')) // ignored, not used atm // .sort((a, b) => b.numNominators - a.numNominators) // .map(mapIndex('rankNumNominators')) - .sort((a, b): number => { - const cmp = b.stakedReturnCmp - a.stakedReturnCmp; - - return cmp !== 0 - ? cmp - : a.rankReward === b.rankReward - ? a.rankPayment === b.rankPayment - ? b.rankBondTotal - a.rankBondTotal - : b.rankPayment - a.rankPayment - : b.rankReward - a.rankReward; - }) + .sort((a, b) => + (b.stakedReturnCmp - a.stakedReturnCmp) || + (a.commissionPer - b.commissionPer) || + (b.rankBondTotal - a.rankBondTotal) + ) .map(mapIndex('rankOverall')) .sort((a, b) => a.isFavorite === b.isFavorite @@ -88,7 +78,7 @@ function sortValidators (list: ValidatorInfo[]): ValidatorInfo[] { ); } -function extractSingle (allAccounts: string[], derive: DeriveStakingElected | DeriveStakingWaiting, favorites: string[], perValidatorReward: BN, { activeEra, eraLength, lastEra, sessionLength }: LastEra, historyDepth?: BN): [ValidatorInfo[], string[]] { +function extractSingle (allAccounts: string[], derive: DeriveStakingElected | DeriveStakingWaiting, favorites: string[], { activeEra, eraLength, lastEra, sessionLength }: LastEra, historyDepth?: BN): [ValidatorInfo[], string[]] { const nominators: Record = {}; const emptyExposure = registry.createType('Exposure'); const earliestEra = historyDepth && lastEra.sub(historyDepth).addn(1); @@ -102,9 +92,6 @@ function extractSingle (allAccounts: string[], derive: DeriveStakingElected | De bondTotal = bondOwn = stakingLedger.total.unwrap(); } - const validatorPayment = (validatorPrefs as unknown as ValidatorPrefsTo196).validatorPayment - ? (validatorPrefs as unknown as ValidatorPrefsTo196).validatorPayment.unwrap() as BN - : validatorPrefs.commission.unwrap().mul(perValidatorReward).div(PERBILL); const key = accountId.toString(); const lastEraPayout = !lastEra.isZero() ? stakingLedger.claimedRewards[stakingLedger.claimedRewards.length - 1] @@ -148,16 +135,12 @@ function extractSingle (allAccounts: string[], derive: DeriveStakingElected | De rankBondOther: 0, rankBondOwn: 0, rankBondTotal: 0, - rankComm: 0, rankNumNominators: 0, rankOverall: 0, - rankPayment: 0, rankReward: 0, - rewardSplit: perValidatorReward.sub(validatorPayment), skipRewards, stakedReturn: 0, stakedReturnCmp: 0, - validatorPayment, validatorPrefs }; }); @@ -165,10 +148,9 @@ function extractSingle (allAccounts: string[], derive: DeriveStakingElected | De return [list, Object.keys(nominators)]; } -function extractInfo (api: ApiPromise, allAccounts: string[], electedDerive: DeriveStakingElected, waitingDerive: DeriveStakingWaiting, favorites: string[], totalIssuance: BN, lastEraInfo: LastEra, lastReward: BN, historyDepth?: BN): Partial { - const perValidatorReward = lastReward.divn(electedDerive.info.length); - const [elected, nominators] = extractSingle(allAccounts, electedDerive, favorites, perValidatorReward, lastEraInfo, historyDepth); - const [waiting] = extractSingle(allAccounts, waitingDerive, favorites, perValidatorReward, lastEraInfo); +function extractInfo (api: ApiPromise, allAccounts: string[], electedDerive: DeriveStakingElected, waitingDerive: DeriveStakingWaiting, favorites: string[], totalIssuance: BN, lastEraInfo: LastEra, historyDepth?: BN): Partial { + const [elected, nominators] = extractSingle(allAccounts, electedDerive, favorites, lastEraInfo, historyDepth); + const [waiting] = extractSingle(allAccounts, waitingDerive, favorites, lastEraInfo); const activeTotals = elected .filter(({ isActive }) => isActive) .map(({ bondTotal }) => bondTotal) @@ -215,19 +197,14 @@ function extractInfo (api: ApiPromise, allAccounts: string[], electedDerive: Der } const transformEra = { - transform: ({ activeEra, activeEraStart, eraLength, sessionLength }: DeriveSessionInfo): LastEra => ({ + transform: ({ activeEra, eraLength, sessionLength }: DeriveSessionInfo): LastEra => ({ activeEra, eraLength, - lastEra: activeEra.gtn(0) ? activeEra.subn(1) : BN_ZERO, - lastEraEnd: activeEra.gtn(0) && activeEraStart.isSome ? activeEraStart.unwrap() : BN_ZERO, + lastEra: activeEra.isZero() ? BN_ZERO : activeEra.subn(1), sessionLength }) }; -const transformReward = { - transform: (optBalance: Option) => optBalance.unwrapOrDefault() -}; - export default function useSortedTargets (favorites: string[]): SortedTargets { const { api } = useApi(); const { allAccounts } = useAccounts(); @@ -236,14 +213,13 @@ export default function useSortedTargets (favorites: string[]): SortedTargets { const electedInfo = useCall(api.derive.staking.electedInfo); const waitingInfo = useCall(api.derive.staking.waitingInfo); const lastEraInfo = useCall(api.derive.session.info, undefined, transformEra); - const lastReward = useCall(lastEraInfo && api.query.staking.erasValidatorReward, [lastEraInfo?.lastEra], transformReward); const partial = useMemo( - () => electedInfo && lastEraInfo && lastReward && totalIssuance && waitingInfo - ? extractInfo(api, allAccounts, electedInfo, waitingInfo, favorites, totalIssuance, lastEraInfo, lastReward, historyDepth) + () => electedInfo && lastEraInfo && totalIssuance && waitingInfo + ? extractInfo(api, allAccounts, electedInfo, waitingInfo, favorites, totalIssuance, lastEraInfo, historyDepth) : EMPTY_PARTIAL, - [api, allAccounts, electedInfo, favorites, historyDepth, lastEraInfo, lastReward, totalIssuance, waitingInfo] + [api, allAccounts, electedInfo, favorites, historyDepth, lastEraInfo, totalIssuance, waitingInfo] ); - return { inflation: { inflation: 0, stakedReturn: 0 }, medianComm: 0, ...partial, lastReward }; + return { inflation: { inflation: 0, stakedReturn: 0 }, medianComm: 0, ...partial }; } diff --git a/packages/react-components/src/AccountName.tsx b/packages/react-components/src/AccountName.tsx index 027cdd8d4c..365ff055c7 100644 --- a/packages/react-components/src/AccountName.tsx +++ b/packages/react-components/src/AccountName.tsx @@ -183,7 +183,9 @@ function AccountName ({ children, className = '', defaultName, label, onClick, o } export default React.memo(styled(AccountName)(({ theme }: ThemeProps) => ` + align-items: center; border: 1px dotted transparent; + display: inline-flex; vertical-align: middle; white-space: nowrap; @@ -198,6 +200,8 @@ export default React.memo(styled(AccountName)(({ theme }: ThemeProps) => ` width: 100%; .name { + align-items: center; + display: inline-flex; font-weight: 400 !important; filter: grayscale(100%); line-height: 1; diff --git a/packages/react-components/src/AddressSmall.tsx b/packages/react-components/src/AddressSmall.tsx index a41dd626c0..35d7c25a29 100644 --- a/packages/react-components/src/AddressSmall.tsx +++ b/packages/react-components/src/AddressSmall.tsx @@ -42,8 +42,7 @@ function AddressSmall ({ children, className = '', defaultName, onClickName, ove export default React.memo(styled(AddressSmall)` white-space: nowrap; - .ui--IdentityIcon, - .ui--AccountName { + .ui--IdentityIcon{ vertical-align: middle; } @@ -52,7 +51,6 @@ export default React.memo(styled(AddressSmall)` } .ui--AccountName { - display: inline-block; max-width: 26rem; overflow: hidden;