fix loading state flashing in pool page

This commit is contained in:
Moody Salem 2021-04-23 21:12:34 -05:00
parent bff3811faf
commit 77fa61495f
No known key found for this signature in database
GPG Key ID: 8CB5CD10385138DB
5 changed files with 35 additions and 46 deletions

@ -51,9 +51,8 @@ export default function PositionList({ positions }: PositionListProps) {
<div>{t('Fees Earned')}</div> <div>{t('Fees Earned')}</div>
</DesktopHeader> </DesktopHeader>
<MobileHeader>Your positions</MobileHeader> <MobileHeader>Your positions</MobileHeader>
{positions.map((p, i) => { {positions.map((p) => {
const key = `${i}-${p.nonce.toString()} ${p.token0} ${p.token1} ${p.tokensOwed0} ${p.tokensOwed1}` return <PositionListItem key={p.tokenId.toString()} positionDetails={p} />
return <PositionListItem key={key} positionDetails={p} />
})} })}
</> </>
) )

@ -3,12 +3,12 @@ import { usePool } from 'hooks/usePools'
import { PositionDetails } from 'types/position' import { PositionDetails } from 'types/position'
import { useCurrency } from './Tokens' import { useCurrency } from './Tokens'
export const useDerivedPositionInfo = ( export function useDerivedPositionInfo(
positionDetails: PositionDetails | undefined positionDetails: PositionDetails | undefined
): { ): {
position: Position | undefined position: Position | undefined
pool: Pool | undefined pool: Pool | undefined
} => { } {
const currency0 = useCurrency(positionDetails?.token0) const currency0 = useCurrency(positionDetails?.token0)
const currency1 = useCurrency(positionDetails?.token1) const currency1 = useCurrency(positionDetails?.token1)
@ -19,7 +19,7 @@ export const useDerivedPositionInfo = (
if (pool && positionDetails) { if (pool && positionDetails) {
position = new Position({ position = new Position({
pool, pool,
liquidity: positionDetails.liquidity, liquidity: positionDetails.liquidity.toString(),
tickLower: positionDetails.tickLower, tickLower: positionDetails.tickLower,
tickUpper: positionDetails.tickUpper, tickUpper: positionDetails.tickUpper,
}) })

@ -6,14 +6,13 @@ import { BigNumber } from '@ethersproject/bignumber'
interface UseV3PositionsResults { interface UseV3PositionsResults {
loading: boolean loading: boolean
error: boolean
positions: PositionDetails[] | undefined positions: PositionDetails[] | undefined
} }
function useV3PositionsFromTokenIds(tokenIds: BigNumber[] | undefined): UseV3PositionsResults { function useV3PositionsFromTokenIds(tokenIds: BigNumber[] | undefined): UseV3PositionsResults {
const positionManager = useV3NFTPositionManagerContract() const positionManager = useV3NFTPositionManagerContract()
const inputs = useMemo(() => (tokenIds ? tokenIds.map((tokenId) => [BigNumber.from(tokenId)]) : []), [tokenIds]) const inputs = useMemo(() => (tokenIds ? tokenIds.map((tokenId) => [BigNumber.from(tokenId)]) : []), [tokenIds])
const results = useSingleContractMultipleData(positionManager ?? undefined, 'positions', inputs) const results = useSingleContractMultipleData(positionManager, 'positions', inputs)
const loading = useMemo(() => results.some(({ loading }) => loading), [results]) const loading = useMemo(() => results.some(({ loading }) => loading), [results])
const error = useMemo(() => results.some(({ error }) => error), [results]) const error = useMemo(() => results.some(({ error }) => error), [results])
@ -45,14 +44,12 @@ function useV3PositionsFromTokenIds(tokenIds: BigNumber[] | undefined): UseV3Pos
return { return {
loading, loading,
error,
positions: positions?.map((position, i) => ({ ...position, tokenId: inputs[i][0] })), positions: positions?.map((position, i) => ({ ...position, tokenId: inputs[i][0] })),
} }
} }
interface UseV3PositionResults { interface UseV3PositionResults {
loading: boolean loading: boolean
error: boolean
position: PositionDetails | undefined position: PositionDetails | undefined
} }
@ -60,7 +57,6 @@ export function useV3PositionFromTokenId(tokenId: BigNumber | undefined): UseV3P
const position = useV3PositionsFromTokenIds(tokenId ? [tokenId] : undefined) const position = useV3PositionsFromTokenIds(tokenId ? [tokenId] : undefined)
return { return {
loading: position.loading, loading: position.loading,
error: position.error,
position: position.positions?.[0], position: position.positions?.[0],
} }
} }
@ -68,11 +64,9 @@ export function useV3PositionFromTokenId(tokenId: BigNumber | undefined): UseV3P
export function useV3Positions(account: string | null | undefined): UseV3PositionsResults { export function useV3Positions(account: string | null | undefined): UseV3PositionsResults {
const positionManager = useV3NFTPositionManagerContract() const positionManager = useV3NFTPositionManagerContract()
const { loading: balanceLoading, error: balanceError, result: balanceResult } = useSingleCallResult( const { loading: balanceLoading, result: balanceResult } = useSingleCallResult(positionManager, 'balanceOf', [
positionManager, account ?? undefined,
'balanceOf', ])
[account ?? undefined]
)
// we don't expect any account balance to ever exceed the bounds of max safe int // we don't expect any account balance to ever exceed the bounds of max safe int
const accountBalance: number | undefined = balanceResult?.[0]?.toNumber() const accountBalance: number | undefined = balanceResult?.[0]?.toNumber()
@ -89,6 +83,7 @@ export function useV3Positions(account: string | null | undefined): UseV3Positio
}, [account, accountBalance]) }, [account, accountBalance])
const tokenIdResults = useSingleContractMultipleData(positionManager, 'tokenOfOwnerByIndex', tokenIdsArgs) const tokenIdResults = useSingleContractMultipleData(positionManager, 'tokenOfOwnerByIndex', tokenIdsArgs)
const someTokenIdsLoading = useMemo(() => tokenIdResults.some(({ loading }) => loading), [tokenIdResults])
const tokenIds = useMemo(() => { const tokenIds = useMemo(() => {
if (account) { if (account) {
@ -100,15 +95,10 @@ export function useV3Positions(account: string | null | undefined): UseV3Positio
return [] return []
}, [account, tokenIdResults]) }, [account, tokenIdResults])
const positionsResults = useV3PositionsFromTokenIds(tokenIds) const { positions, loading: positionsLoading } = useV3PositionsFromTokenIds(tokenIds)
// wrap the return value
const loading = balanceLoading || positionsResults.loading
const error = balanceError || positionsResults.error
return { return {
loading: loading || positionsResults.loading, loading: someTokenIdsLoading || balanceLoading || positionsLoading,
error: error || positionsResults.error, positions,
positions: loading || error ? undefined : positionsResults.positions,
} }
} }

@ -1,4 +1,4 @@
import React, { useContext, useMemo } from 'react' import React, { useContext } from 'react'
import { ButtonGray, ButtonPrimary } from 'components/Button' import { ButtonGray, ButtonPrimary } from 'components/Button'
import { AutoColumn } from 'components/Column' import { AutoColumn } from 'components/Column'
import { FlyoutAlignment, NewMenu } from 'components/Menu' import { FlyoutAlignment, NewMenu } from 'components/Menu'
@ -88,9 +88,9 @@ export default function Pool() {
const { t } = useTranslation() const { t } = useTranslation()
const theme = useContext(ThemeContext) const theme = useContext(ThemeContext)
const { positions } = useV3Positions(account) const { positions, loading: positionsLoading } = useV3Positions(account)
const hasPositions = useMemo(() => Boolean(positions && positions.length > 0), [positions]) const hasPositions = Boolean(positions && positions.length > 0)
const hasV2Liquidity = true const hasV2Liquidity = true
const showMigrateHeaderLink = Boolean(hasV2Liquidity && hasPositions) const showMigrateHeaderLink = Boolean(hasV2Liquidity && hasPositions)
@ -160,9 +160,24 @@ export default function Pool() {
</TitleRow> </TitleRow>
<MainContentWrapper> <MainContentWrapper>
{hasPositions && positions ? ( {positionsLoading ? (
<LoadingRows>
<div />
<div />
<div />
<div />
<div />
<div />
<div />
<div />
<div />
<div />
<div />
<div />
</LoadingRows>
) : positions && positions.length > 0 ? (
<PositionList positions={positions} /> <PositionList positions={positions} />
) : positions && !hasPositions ? ( ) : (
<NoLiquidity> <NoLiquidity>
<TYPE.largeHeader color={theme.text3} textAlign="center"> <TYPE.largeHeader color={theme.text3} textAlign="center">
<Inbox /> <Inbox />
@ -186,21 +201,6 @@ export default function Pool() {
) )
)} )}
</NoLiquidity> </NoLiquidity>
) : (
<LoadingRows>
<div />
<div />
<div />
<div />
<div />
<div />
<div />
<div />
<div />
<div />
<div />
<div />
</LoadingRows>
)} )}
</MainContentWrapper> </MainContentWrapper>
</AutoColumn> </AutoColumn>

@ -1,8 +1,8 @@
import { BigNumberish } from '@ethersproject/bignumber' import { BigNumber } from '@ethersproject/bignumber'
export interface PositionDetails { export interface PositionDetails {
nonce: BigNumber nonce: BigNumber
tokenId: BigNumberish | undefined tokenId: BigNumber
operator: string operator: string
token0: string token0: string
token1: string token1: string