diff --git a/src/custom/components/CowBalanceButton/index.tsx b/src/custom/components/CowBalanceButton/index.tsx index d90af3b36f..4265972b37 100644 --- a/src/custom/components/CowBalanceButton/index.tsx +++ b/src/custom/components/CowBalanceButton/index.tsx @@ -1,5 +1,5 @@ import { Trans } from '@lingui/macro' -import styled from 'styled-components/macro' +import styled, { css } from 'styled-components/macro' import CowProtocolLogo from 'components/CowProtocolLogo' import { useCombinedBalance } from 'state/cowToken/hooks' import { ChainId } from 'state/lists/actions/actionsMod' @@ -7,7 +7,7 @@ import { formatMax, formatSmartLocaleAware } from 'utils/format' import { AMOUNT_PRECISION } from 'constants/index' import { COW } from 'constants/tokens' -export const Wrapper = styled.div` +export const Wrapper = styled.div<{ isLoading: boolean }>` ${({ theme }) => theme.card.boxShadow}; color: ${({ theme }) => theme.text1}; padding: 0 12px; @@ -20,6 +20,35 @@ export const Wrapper = styled.div` border-radius: 12px; pointer-events: auto; + ${({ theme, isLoading }) => + isLoading && + css` + overflow: hidden; + &::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + transform: translateX(-100%); + background-image: linear-gradient( + 90deg, + rgba(255, 255, 255, 0) 0, + ${theme.shimmer1} 20%, + ${theme.shimmer2} 60%, + rgba(255, 255, 255, 0) + ); + animation: shimmer 2s infinite; + content: ''; + } + + @keyframes shimmer { + 100% { + transform: translateX(100%); + } + } + `} + > b { margin: 0 0 0 5px; color: inherit; @@ -48,13 +77,13 @@ interface CowBalanceButtonProps { const COW_DECIMALS = COW[ChainId.MAINNET].decimals export default function CowBalanceButton({ onClick }: CowBalanceButtonProps) { - const combinedBalance = useCombinedBalance() + const { balance, isLoading } = useCombinedBalance() - const formattedBalance = formatSmartLocaleAware(combinedBalance, AMOUNT_PRECISION) - const formattedMaxBalance = formatMax(combinedBalance, COW_DECIMALS) + const formattedBalance = formatSmartLocaleAware(balance, AMOUNT_PRECISION) + const formattedMaxBalance = formatMax(balance, COW_DECIMALS) return ( - + {formattedBalance || 0} diff --git a/src/custom/hooks/useCowBalanceAndSubsidy.ts b/src/custom/hooks/useCowBalanceAndSubsidy.ts index c2e8da086f..1cf835d428 100644 --- a/src/custom/hooks/useCowBalanceAndSubsidy.ts +++ b/src/custom/hooks/useCowBalanceAndSubsidy.ts @@ -1,37 +1,13 @@ import { useMemo } from 'react' import { BigNumber } from 'bignumber.js' -import { JSBI } from '@uniswap/sdk' -import { CurrencyAmount } from '@uniswap/sdk-core' - import { getDiscountFromBalance } from 'components/CowSubsidyModal/utils' -import { useVCowData } from 'state/cowToken/hooks' -import { useTokenBalance } from 'state/wallet/hooks' -import { useActiveWeb3React } from 'hooks/web3' - -import { COW } from 'constants/tokens' -import { SupportedChainId } from 'constants/chains' +import { useCombinedBalance } from 'state/cowToken/hooks' import { COW_SUBSIDY_DATA } from 'components/CowSubsidyModal/constants' const ZERO_BALANCE_SUBSIDY = { subsidy: { tier: 0, discount: COW_SUBSIDY_DATA[0][1] }, balance: undefined } export default function useCowBalanceAndSubsidy() { - const { account, chainId } = useActiveWeb3React() - // vcow balance - const { total: vCowBalance } = useVCowData() - // Cow balanc - const cowBalance = useTokenBalance(account || undefined, chainId ? COW[chainId] : undefined) - - const balance = useMemo(() => { - if (vCowBalance && cowBalance) { - const totalBalance = JSBI.add(vCowBalance.quotient, cowBalance.quotient) - - // COW and vCOW safely have the same identifying properties: decimals - // so we make JSBI maths and create a new currency as adding vCow and Cow throws and exception - return CurrencyAmount.fromRawAmount(COW[chainId || SupportedChainId.MAINNET], totalBalance) - } else { - return cowBalance || vCowBalance - } - }, [chainId, cowBalance, vCowBalance]) + const { balance } = useCombinedBalance() return useMemo(() => { if (!balance || balance?.equalTo('0')) return ZERO_BALANCE_SUBSIDY diff --git a/src/custom/state/cowToken/hooks.ts b/src/custom/state/cowToken/hooks.ts index 9fb46c13ba..ab87dcab01 100644 --- a/src/custom/state/cowToken/hooks.ts +++ b/src/custom/state/cowToken/hooks.ts @@ -15,6 +15,8 @@ import { OperationType } from 'components/TransactionConfirmationModal' import { APPROVE_GAS_LIMIT_DEFAULT } from 'hooks/useApproveCallback/useApproveCallbackMod' import { useTokenBalance } from 'state/wallet/hooks' import { useAllocation } from 'pages/Profile/LockedGnoVesting/hooks' +import { SupportedChainId } from 'constants/chains' +import JSBI from 'jsbi' export type SetSwapVCowStatusCallback = (payload: SwapVCowStatus) => void @@ -166,16 +168,26 @@ export function useCowBalance() { * Hook that returns combined vCOW + COW balance + vCow from locked GNO */ export function useCombinedBalance() { + const { chainId, account } = useActiveWeb3React() const { total: vCowBalance } = useVCowData() const lockedGnoBalance = useAllocation() const cowBalance = useCowBalance() return useMemo(() => { - if (!vCowBalance || !cowBalance || !lockedGnoBalance) { - return + let tmpBalance = JSBI.BigInt(0) + + const isLoading = account && (!vCowBalance || !lockedGnoBalance || !cowBalance) ? true : false + + const cow = COW[chainId || SupportedChainId.MAINNET] + + if (account) { + if (vCowBalance) tmpBalance = JSBI.add(tmpBalance, vCowBalance.quotient) + if (lockedGnoBalance) tmpBalance = JSBI.add(tmpBalance, lockedGnoBalance.quotient) + if (cowBalance) tmpBalance = JSBI.add(tmpBalance, cowBalance.quotient) } - const sum = vCowBalance.asFraction.add(cowBalance.asFraction).add(lockedGnoBalance.asFraction) - return CurrencyAmount.fromRawAmount(cowBalance.currency, sum.quotient) - }, [cowBalance, vCowBalance, lockedGnoBalance]) + const balance = CurrencyAmount.fromRawAmount(cow, tmpBalance) + + return { balance, isLoading } + }, [vCowBalance, lockedGnoBalance, cowBalance, chainId, account]) }