From f5ceef6aea2c045a584325e053febc4d3c283504 Mon Sep 17 00:00:00 2001 From: Daryl Collins Date: Thu, 20 Jan 2022 20:00:27 -0800 Subject: [PATCH] feat: Update validator detail page to show farmed rewards Also added loading 'dots' so that it is clear when we are still fetching farm details --- .../staking/components/BalanceBox.js | 17 ++-- .../staking/components/Validator.js | 95 ++++++++++++------- 2 files changed, 71 insertions(+), 41 deletions(-) diff --git a/packages/frontend/src/components/staking/components/BalanceBox.js b/packages/frontend/src/components/staking/components/BalanceBox.js index d88bb1f9c7..62d1fa5262 100644 --- a/packages/frontend/src/components/staking/components/BalanceBox.js +++ b/packages/frontend/src/components/staking/components/BalanceBox.js @@ -1,7 +1,7 @@ import BN from 'bn.js'; import React from 'react'; import { Translate } from 'react-localize-redux'; -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; import classNames from '../../../utils/classNames'; import Balance from '../../common/balance/Balance'; @@ -11,7 +11,9 @@ import TokenIcon from '../../send/components/TokenIcon'; import TokenAmount from '../../wallet/TokenAmount'; const Container = styled.div` - border-bottom: 2px solid #F2F2F2; + ${props => !props.hideBorder && css` + border-bottom: 2px solid #F2F2F2; + `} padding: 15px 0; display: flex; @@ -110,14 +112,15 @@ export default function BalanceBox({ disclaimer, linkTo, buttonTestId, - balanceTestId + balanceTestId, + hideBorder = false }) { return ( - +
- - + {title && } + {info && }
@@ -159,4 +162,4 @@ export default function BalanceBox({ } ); -} \ No newline at end of file +} diff --git a/packages/frontend/src/components/staking/components/Validator.js b/packages/frontend/src/components/staking/components/Validator.js index c885c3eceb..ed3ac25713 100644 --- a/packages/frontend/src/components/staking/components/Validator.js +++ b/packages/frontend/src/components/staking/components/Validator.js @@ -18,6 +18,40 @@ import StakingFee from './StakingFee'; const { fetchToken } = tokensActions; +const renderFarmUi = ({ farmList, contractMetadataByContractId, isFarmListLoading }) => { + if(isFarmListLoading) { + // eslint-disable-next-line jsx-a11y/heading-has-content + return

; + } + + return farmList.map(({ token_id, balance }, i) => { + const currentTokenContractMetadata = contractMetadataByContractId[token_id]; + + if (!currentTokenContractMetadata) { + return; + } + + return ( + { + // // TODO claim accrued rewards and redirect home where tokens will be fetched + // return validator.contract.claim({token_id}).then(() => dispatch(redirectTo('/'))); + // }} + button="staking.balanceBox.farm.button" + buttonColor='gray-red' + hideBorder={farmList.length > 1 && i < farmList.length} + /> + ); + }); +}; + export default function Validator({ match, validator, @@ -28,29 +62,39 @@ export default function Validator({ }) { const [confirm, setConfirm] = useState(null); const [farmList, setFarmList] = useState([]); + const [isFarmListLoading, setIsFarmListLoading] = useState(false); const nearAsFT = useNEARAsTokenWithMetadata(); const accountId = useSelector(selectAccountId); - const contractMetadata = useSelector(selectAllContractMetadata); + const contractMetadataByContractId = useSelector(selectAllContractMetadata); const dispatch = useDispatch(); const stakeNotAllowed = !!selectedValidator && selectedValidator !== match.params.validator && !!currentValidators.length; const showConfirmModal = confirm === 'withdraw'; + const stakingPoolHasFarms = validator && validator.version === ValidatorVersion[PROJECT_VALIDATOR_VERSION]; + useEffect(() => { const getFarms = async () => { - const farms = await validator.contract.get_farms({from_index: 0, limit: 300}); - setFarmList(await Promise.all(farms.map(({ token_id }, i) => { - dispatch(fetchToken({contractName: token_id})); - return validator.contract - .get_unclaimed_reward({ account_id: accountId, farm_id: i }) - .catch(() => "0") - .then((balance) => ({ token_id, balance, farm_id: i })); - }))); + setIsFarmListLoading(true); + + try { + const farms = await validator.contract.get_farms({ from_index: 0, limit: 300 }); + + const list = await Promise.all(farms.map(({ token_id }, i) => { + dispatch(fetchToken({ contractName: token_id })); + return validator.contract + .get_unclaimed_reward({ account_id: accountId, farm_id: i }) + .catch(() => "0") + .then((balance) => ({ token_id, balance, farm_id: i })); + })); + + setFarmList(list); + } finally { + setIsFarmListLoading(false); + } }; - if(validator && validator.version === ValidatorVersion[PROJECT_VALIDATOR_VERSION]) { - getFarms(); - } - },[validator]); + if (stakingPoolHasFarms) { getFarms(); } + }, [validator]); const handleStakeAction = async () => { if (showConfirmModal && !loading) { @@ -79,7 +123,7 @@ export default function Validator({

@@ -105,26 +149,9 @@ export default function Validator({ title='staking.balanceBox.unclaimed.title' info='staking.balanceBox.unclaimed.info' token={{...nearAsFT, balance: validator.unclaimed || '0'}} + hideBorder={(stakingPoolHasFarms && isFarmListLoading) || (!isFarmListLoading && farmList.length > 0)} /> - {farmList.map(({ token_id, balance }) => ( - { - // // TODO claim accrued rewards and redirect home where tokens will be fetched - // return validator.contract.claim({token_id}).then(() => dispatch(redirectTo('/'))); - // }} - button="staking.balanceBox.farm.button" - buttonColor='gray-red' - /> - ))} + {renderFarmUi({ farmList, contractMetadataByContractId, isFarmListLoading })} ); -} \ No newline at end of file +}