Commit 7b086848 authored by Charles Bachmeier's avatar Charles Bachmeier Committed by GitHub

refactor: lazy load asset details and profile page (#5203)

* properly load NFtBalance data

* lazy load asset details

* extend useLoadNftBalance

* handle different balance query formats

* correct load params
parent 77a6d158
import { parseEther } from '@ethersproject/units' import { parseEther } from '@ethersproject/units'
import graphql from 'babel-plugin-relay/macro' import graphql from 'babel-plugin-relay/macro'
import { CollectionInfoForAsset, GenieAsset, SellOrder, TokenType } from 'nft/types' import { CollectionInfoForAsset, GenieAsset, SellOrder, TokenType } from 'nft/types'
import { useLazyLoadQuery } from 'react-relay' import { useEffect } from 'react'
import { useLazyLoadQuery, useQueryLoader } from 'react-relay'
import { DetailsQuery } from './__generated__/DetailsQuery.graphql' import { DetailsQuery } from './__generated__/DetailsQuery.graphql'
...@@ -91,11 +92,24 @@ const detailsQuery = graphql` ...@@ -91,11 +92,24 @@ const detailsQuery = graphql`
} }
` `
export function useLoadDetailsQuery(address?: string, tokenId?: string): void {
const [, loadQuery] = useQueryLoader(detailsQuery)
useEffect(() => {
if (address && tokenId) {
loadQuery({ address, tokenId })
}
}, [address, tokenId, loadQuery])
}
export function useDetailsQuery(address: string, tokenId: string): [GenieAsset, CollectionInfoForAsset] | undefined { export function useDetailsQuery(address: string, tokenId: string): [GenieAsset, CollectionInfoForAsset] | undefined {
const queryData = useLazyLoadQuery<DetailsQuery>(detailsQuery, { const queryData = useLazyLoadQuery<DetailsQuery>(
detailsQuery,
{
address, address,
tokenId, tokenId,
}) },
{ fetchPolicy: 'store-or-network' }
)
const asset = queryData.nftAssets?.edges[0]?.node const asset = queryData.nftAssets?.edges[0]?.node
const collection = asset?.collection const collection = asset?.collection
......
import graphql from 'babel-plugin-relay/macro' import graphql from 'babel-plugin-relay/macro'
import { parseEther } from 'ethers/lib/utils' import { parseEther } from 'ethers/lib/utils'
import { DEFAULT_WALLET_ASSET_QUERY_AMOUNT } from 'nft/components/profile/view/ProfilePage'
import { WalletAsset } from 'nft/types' import { WalletAsset } from 'nft/types'
import { useLazyLoadQuery, usePaginationFragment } from 'react-relay' import { useEffect } from 'react'
import { useLazyLoadQuery, usePaginationFragment, useQueryLoader } from 'react-relay'
import { NftBalancePaginationQuery } from './__generated__/NftBalancePaginationQuery.graphql' import { NftBalancePaginationQuery } from './__generated__/NftBalancePaginationQuery.graphql'
import { NftBalanceQuery } from './__generated__/NftBalanceQuery.graphql' import { NftBalanceQuery } from './__generated__/NftBalanceQuery.graphql'
...@@ -111,26 +113,54 @@ const nftBalanceQuery = graphql` ...@@ -111,26 +113,54 @@ const nftBalanceQuery = graphql`
type NftBalanceQueryAsset = NonNullable< type NftBalanceQueryAsset = NonNullable<
NonNullable<NonNullable<NftBalanceQuery_nftBalances$data['nftBalances']>['edges']>[number] NonNullable<NonNullable<NftBalanceQuery_nftBalances$data['nftBalances']>['edges']>[number]
> >
//
// export type TokenQueryData = NonNullable<TokenQuery$data['tokens']>[number] export function useLoadNftBalanceQuery(
ownerAddress?: string,
collectionAddress?: string | string[],
tokenId?: string
): void {
const [, loadQuery] = useQueryLoader(nftBalanceQuery)
useEffect(() => {
if (ownerAddress) {
loadQuery({
ownerAddress,
filter: tokenId
? { assets: [{ address: collectionAddress, tokenId }] }
: { addresses: Array.isArray(collectionAddress) ? collectionAddress : [collectionAddress] },
first: tokenId ? 1 : DEFAULT_WALLET_ASSET_QUERY_AMOUNT,
})
}
}, [ownerAddress, loadQuery, collectionAddress, tokenId])
}
export function useNftBalanceQuery( export function useNftBalanceQuery(
ownerAddress: string, ownerAddress: string,
collectionFilters?: string[], collectionFilters?: string[],
assetsFilter?: { address: string; tokenId: string }[],
first?: number, first?: number,
after?: string, after?: string,
last?: number, last?: number,
before?: string before?: string
) { ) {
const queryData = useLazyLoadQuery<NftBalanceQuery>(nftBalanceQuery, { const queryData = useLazyLoadQuery<NftBalanceQuery>(
nftBalanceQuery,
{
ownerAddress, ownerAddress,
filter: { filter:
assetsFilter && assetsFilter.length > 0
? {
assets: assetsFilter,
}
: {
addresses: collectionFilters, addresses: collectionFilters,
}, },
first, first,
after, after,
last, last,
before, before,
}) },
{ fetchPolicy: 'store-or-network' }
)
const { data, hasNext, loadNext, isLoadingNext } = usePaginationFragment<NftBalancePaginationQuery, any>( const { data, hasNext, loadNext, isLoadingNext } = usePaginationFragment<NftBalancePaginationQuery, any>(
nftBalancePaginationQuery, nftBalancePaginationQuery,
queryData queryData
......
...@@ -20,9 +20,14 @@ import { ...@@ -20,9 +20,14 @@ import {
} from 'nft/hooks' } from 'nft/hooks'
import { ScreenBreakpointsPaddings } from 'nft/pages/collection/index.css' import { ScreenBreakpointsPaddings } from 'nft/pages/collection/index.css'
import { OSCollectionsFetcher } from 'nft/queries' import { OSCollectionsFetcher } from 'nft/queries'
import { TokenType } from 'nft/types' import {
import { UniformHeight, UniformHeights } from 'nft/types' ProfilePageStateType,
import { ProfilePageStateType, WalletAsset, WalletCollection } from 'nft/types' TokenType,
UniformHeight,
UniformHeights,
WalletAsset,
WalletCollection,
} from 'nft/types'
import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react' import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'
import InfiniteScroll from 'react-infinite-scroll-component' import InfiniteScroll from 'react-infinite-scroll-component'
import { useQuery } from 'react-query' import { useQuery } from 'react-query'
...@@ -109,7 +114,7 @@ export const ProfilePage = () => { ...@@ -109,7 +114,7 @@ export const ProfilePage = () => {
walletAssets: ownerAssets, walletAssets: ownerAssets,
loadNext, loadNext,
hasNext, hasNext,
} = useNftBalanceQuery(address, collectionFilters, DEFAULT_WALLET_ASSET_QUERY_AMOUNT) } = useNftBalanceQuery(address, collectionFilters, [], DEFAULT_WALLET_ASSET_QUERY_AMOUNT)
useEffect(() => { useEffect(() => {
ownerCollections && setWalletCollections(ownerCollections) ownerCollections && setWalletCollections(ownerCollections)
......
import { Trace } from '@uniswap/analytics' import { Trace } from '@uniswap/analytics'
import { PageName } from '@uniswap/analytics-events' import { PageName } from '@uniswap/analytics-events'
import { useDetailsQuery } from 'graphql/data/nft/Details' import { useDetailsQuery, useLoadDetailsQuery } from 'graphql/data/nft/Details'
import { AssetDetails } from 'nft/components/details/AssetDetails' import { AssetDetails } from 'nft/components/details/AssetDetails'
import { AssetDetailsLoading } from 'nft/components/details/AssetDetailsLoading'
import { AssetPriceDetails } from 'nft/components/details/AssetPriceDetails' import { AssetPriceDetails } from 'nft/components/details/AssetPriceDetails'
import { useMemo } from 'react' import { Suspense, useMemo } from 'react'
import { useParams } from 'react-router-dom' import { useParams } from 'react-router-dom'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
...@@ -60,4 +61,15 @@ const Asset = () => { ...@@ -60,4 +61,15 @@ const Asset = () => {
) )
} }
export default Asset const AssetPage = () => {
const { tokenId, contractAddress } = useParams()
useLoadDetailsQuery(contractAddress, tokenId)
return (
<Suspense fallback={<AssetDetailsLoading />}>
<Asset />
</Suspense>
)
}
export default AssetPage
import { Trace } from '@uniswap/analytics' import { Trace } from '@uniswap/analytics'
import { PageName } from '@uniswap/analytics-events' import { PageName } from '@uniswap/analytics-events'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { useLoadNftBalanceQuery } from 'graphql/data/nft/NftBalance'
import { Box } from 'nft/components/Box' import { Box } from 'nft/components/Box'
import { Center, Column, Row } from 'nft/components/Flex' import { Center, Column, Row } from 'nft/components/Flex'
import { ChevronLeftIcon, XMarkIcon } from 'nft/components/icons' import { ChevronLeftIcon, XMarkIcon } from 'nft/components/icons'
import { ListPage } from 'nft/components/profile/list/ListPage' import { ListPage } from 'nft/components/profile/list/ListPage'
import { ProfilePage } from 'nft/components/profile/view/ProfilePage' import { ProfilePage } from 'nft/components/profile/view/ProfilePage'
import { ProfilePageLoadingSkeleton } from 'nft/components/profile/view/ProfilePageLoadingSkeleton'
import { buttonMedium, headlineMedium, headlineSmall } from 'nft/css/common.css' import { buttonMedium, headlineMedium, headlineSmall } from 'nft/css/common.css'
import { themeVars } from 'nft/css/sprinkles.css' import { themeVars } from 'nft/css/sprinkles.css'
import { useBag, useNFTList, useProfilePageState, useSellAsset, useWalletCollections } from 'nft/hooks' import { useBag, useNFTList, useProfilePageState, useSellAsset, useWalletCollections } from 'nft/hooks'
import { ListingStatus, ProfilePageStateType } from 'nft/types' import { ListingStatus, ProfilePageStateType } from 'nft/types'
import { useEffect } from 'react' import { Suspense, useEffect } from 'react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { useToggleWalletModal } from 'state/application/hooks' import { useToggleWalletModal } from 'state/application/hooks'
...@@ -18,7 +20,7 @@ import * as styles from './sell.css' ...@@ -18,7 +20,7 @@ import * as styles from './sell.css'
const SHOPPING_BAG_WIDTH = 360 const SHOPPING_BAG_WIDTH = 360
const Profile = () => { const ProfileContent = () => {
const sellPageState = useProfilePageState((state) => state.state) const sellPageState = useProfilePageState((state) => state.state)
const setSellPageState = useProfilePageState((state) => state.setProfilePageState) const setSellPageState = useProfilePageState((state) => state.setProfilePageState)
const removeAllMarketplaceWarnings = useSellAsset((state) => state.removeAllMarketplaceWarnings) const removeAllMarketplaceWarnings = useSellAsset((state) => state.removeAllMarketplaceWarnings)
...@@ -88,4 +90,15 @@ const Profile = () => { ...@@ -88,4 +90,15 @@ const Profile = () => {
) )
} }
const Profile = () => {
const { account } = useWeb3React()
useLoadNftBalanceQuery(account, [])
return (
<Suspense fallback={<ProfilePageLoadingSkeleton />}>
<ProfileContent />
</Suspense>
)
}
export default Profile export default Profile
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment