diff --git a/src/graphql/data/nft/Details.ts b/src/graphql/data/nft/Details.ts index a42634f20b..703bddf947 100644 --- a/src/graphql/data/nft/Details.ts +++ b/src/graphql/data/nft/Details.ts @@ -1,7 +1,8 @@ import { parseEther } from '@ethersproject/units' import graphql from 'babel-plugin-relay/macro' 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' @@ -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 { - const queryData = useLazyLoadQuery(detailsQuery, { - address, - tokenId, - }) + const queryData = useLazyLoadQuery( + detailsQuery, + { + address, + tokenId, + }, + { fetchPolicy: 'store-or-network' } + ) const asset = queryData.nftAssets?.edges[0]?.node const collection = asset?.collection diff --git a/src/graphql/data/nft/NftBalance.ts b/src/graphql/data/nft/NftBalance.ts index cfc5936e7c..e9371b1c08 100644 --- a/src/graphql/data/nft/NftBalance.ts +++ b/src/graphql/data/nft/NftBalance.ts @@ -1,7 +1,9 @@ import graphql from 'babel-plugin-relay/macro' import { parseEther } from 'ethers/lib/utils' +import { DEFAULT_WALLET_ASSET_QUERY_AMOUNT } from 'nft/components/profile/view/ProfilePage' 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 { NftBalanceQuery } from './__generated__/NftBalanceQuery.graphql' @@ -111,26 +113,54 @@ const nftBalanceQuery = graphql` type NftBalanceQueryAsset = NonNullable< NonNullable['edges']>[number] > -// -// export type TokenQueryData = NonNullable[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( ownerAddress: string, collectionFilters?: string[], + assetsFilter?: { address: string; tokenId: string }[], first?: number, after?: string, last?: number, before?: string ) { - const queryData = useLazyLoadQuery(nftBalanceQuery, { - ownerAddress, - filter: { - addresses: collectionFilters, + const queryData = useLazyLoadQuery( + nftBalanceQuery, + { + ownerAddress, + filter: + assetsFilter && assetsFilter.length > 0 + ? { + assets: assetsFilter, + } + : { + addresses: collectionFilters, + }, + first, + after, + last, + before, }, - first, - after, - last, - before, - }) + { fetchPolicy: 'store-or-network' } + ) const { data, hasNext, loadNext, isLoadingNext } = usePaginationFragment( nftBalancePaginationQuery, queryData diff --git a/src/nft/components/profile/view/ProfilePage.tsx b/src/nft/components/profile/view/ProfilePage.tsx index 55efe38314..569d66d50d 100644 --- a/src/nft/components/profile/view/ProfilePage.tsx +++ b/src/nft/components/profile/view/ProfilePage.tsx @@ -20,9 +20,14 @@ import { } from 'nft/hooks' import { ScreenBreakpointsPaddings } from 'nft/pages/collection/index.css' import { OSCollectionsFetcher } from 'nft/queries' -import { TokenType } from 'nft/types' -import { UniformHeight, UniformHeights } from 'nft/types' -import { ProfilePageStateType, WalletAsset, WalletCollection } from 'nft/types' +import { + ProfilePageStateType, + TokenType, + UniformHeight, + UniformHeights, + WalletAsset, + WalletCollection, +} from 'nft/types' import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react' import InfiniteScroll from 'react-infinite-scroll-component' import { useQuery } from 'react-query' @@ -109,7 +114,7 @@ export const ProfilePage = () => { walletAssets: ownerAssets, loadNext, hasNext, - } = useNftBalanceQuery(address, collectionFilters, DEFAULT_WALLET_ASSET_QUERY_AMOUNT) + } = useNftBalanceQuery(address, collectionFilters, [], DEFAULT_WALLET_ASSET_QUERY_AMOUNT) useEffect(() => { ownerCollections && setWalletCollections(ownerCollections) diff --git a/src/nft/pages/asset/Asset.tsx b/src/nft/pages/asset/Asset.tsx index fae8d3d163..bd21d5cd0c 100644 --- a/src/nft/pages/asset/Asset.tsx +++ b/src/nft/pages/asset/Asset.tsx @@ -1,9 +1,10 @@ import { Trace } from '@uniswap/analytics' 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 { AssetDetailsLoading } from 'nft/components/details/AssetDetailsLoading' import { AssetPriceDetails } from 'nft/components/details/AssetPriceDetails' -import { useMemo } from 'react' +import { Suspense, useMemo } from 'react' import { useParams } from 'react-router-dom' import styled from 'styled-components/macro' @@ -60,4 +61,15 @@ const Asset = () => { ) } -export default Asset +const AssetPage = () => { + const { tokenId, contractAddress } = useParams() + useLoadDetailsQuery(contractAddress, tokenId) + + return ( + }> + + + ) +} + +export default AssetPage diff --git a/src/nft/pages/profile/profile.tsx b/src/nft/pages/profile/profile.tsx index 25f37c9ff1..e12fb00b42 100644 --- a/src/nft/pages/profile/profile.tsx +++ b/src/nft/pages/profile/profile.tsx @@ -1,16 +1,18 @@ import { Trace } from '@uniswap/analytics' import { PageName } from '@uniswap/analytics-events' import { useWeb3React } from '@web3-react/core' +import { useLoadNftBalanceQuery } from 'graphql/data/nft/NftBalance' import { Box } from 'nft/components/Box' import { Center, Column, Row } from 'nft/components/Flex' import { ChevronLeftIcon, XMarkIcon } from 'nft/components/icons' import { ListPage } from 'nft/components/profile/list/ListPage' 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 { themeVars } from 'nft/css/sprinkles.css' import { useBag, useNFTList, useProfilePageState, useSellAsset, useWalletCollections } from 'nft/hooks' import { ListingStatus, ProfilePageStateType } from 'nft/types' -import { useEffect } from 'react' +import { Suspense, useEffect } from 'react' import { useNavigate } from 'react-router-dom' import { useToggleWalletModal } from 'state/application/hooks' @@ -18,7 +20,7 @@ import * as styles from './sell.css' const SHOPPING_BAG_WIDTH = 360 -const Profile = () => { +const ProfileContent = () => { const sellPageState = useProfilePageState((state) => state.state) const setSellPageState = useProfilePageState((state) => state.setProfilePageState) const removeAllMarketplaceWarnings = useSellAsset((state) => state.removeAllMarketplaceWarnings) @@ -88,4 +90,15 @@ const Profile = () => { ) } +const Profile = () => { + const { account } = useWeb3React() + useLoadNftBalanceQuery(account, []) + + return ( + }> + + + ) +} + export default Profile