Commit cd3cff02 authored by Charles Bachmeier's avatar Charles Bachmeier Committed by GitHub

chore: remove graphql feature flag and old query methods (#6384)

* remove graphql feature flag and old query methods

* remove unused fn

* remove redundant names, simplify import

* explicit var naming

* column

* add comment

* update flag check

* undo

* visit /swap in uni search test

* empty array base

---------
Co-authored-by: default avatarCharles Bachmeier <charlie@genie.xyz>
parent 90546fd8
import { BaseVariant, FeatureFlag, featureFlagSettings, useUpdateFlag } from 'featureFlags' import { BaseVariant, FeatureFlag, featureFlagSettings, useUpdateFlag } from 'featureFlags'
import { DetailsV2Variant, useDetailsV2Flag } from 'featureFlags/flags/nftDetails' import { DetailsV2Variant, useDetailsV2Flag } from 'featureFlags/flags/nftDetails'
import { NftGraphqlVariant, useNftGraphqlFlag } from 'featureFlags/flags/nftlGraphql'
import { PayWithAnyTokenVariant, usePayWithAnyTokenFlag } from 'featureFlags/flags/payWithAnyToken' import { PayWithAnyTokenVariant, usePayWithAnyTokenFlag } from 'featureFlags/flags/payWithAnyToken'
import { SwapWidgetVariant, useSwapWidgetFlag } from 'featureFlags/flags/swapWidget' import { SwapWidgetVariant, useSwapWidgetFlag } from 'featureFlags/flags/swapWidget'
import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc' import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc'
...@@ -216,12 +215,6 @@ export default function FeatureFlagModal() { ...@@ -216,12 +215,6 @@ export default function FeatureFlagModal() {
featureFlag={FeatureFlag.swapWidget} featureFlag={FeatureFlag.swapWidget}
label="Swap Widget" label="Swap Widget"
/> />
<FeatureFlagOption
variant={NftGraphqlVariant}
value={useNftGraphqlFlag()}
featureFlag={FeatureFlag.nftGraphql}
label="Migrate NFT read endpoints to GQL"
/>
<FeatureFlagOption <FeatureFlagOption
variant={DetailsV2Variant} variant={DetailsV2Variant}
value={useDetailsV2Flag()} value={useDetailsV2Flag()}
......
...@@ -4,7 +4,6 @@ import { sendAnalyticsEvent, Trace, TraceEvent, useTrace } from '@uniswap/analyt ...@@ -4,7 +4,6 @@ import { sendAnalyticsEvent, Trace, TraceEvent, useTrace } from '@uniswap/analyt
import { BrowserEvent, InterfaceElementName, InterfaceEventName, InterfaceSectionName } from '@uniswap/analytics-events' import { BrowserEvent, InterfaceElementName, InterfaceEventName, InterfaceSectionName } from '@uniswap/analytics-events'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import clsx from 'clsx' import clsx from 'clsx'
import { useNftGraphqlEnabled } from 'featureFlags/flags/nftlGraphql'
import { useCollectionSearch } from 'graphql/data/nft/CollectionSearch' import { useCollectionSearch } from 'graphql/data/nft/CollectionSearch'
import { useSearchTokens } from 'graphql/data/SearchTokens' import { useSearchTokens } from 'graphql/data/SearchTokens'
import useDebounce from 'hooks/useDebounce' import useDebounce from 'hooks/useDebounce'
...@@ -16,9 +15,7 @@ import { Row } from 'nft/components/Flex' ...@@ -16,9 +15,7 @@ import { Row } from 'nft/components/Flex'
import { magicalGradientOnHover } from 'nft/css/common.css' import { magicalGradientOnHover } from 'nft/css/common.css'
import { useIsMobile, useIsTablet } from 'nft/hooks' import { useIsMobile, useIsTablet } from 'nft/hooks'
import { useIsNavSearchInputVisible } from 'nft/hooks/useIsNavSearchInputVisible' import { useIsNavSearchInputVisible } from 'nft/hooks/useIsNavSearchInputVisible'
import { fetchSearchCollections } from 'nft/queries'
import { ChangeEvent, useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react' import { ChangeEvent, useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react'
import { useQuery } from 'react-query'
import { useLocation } from 'react-router-dom' import { useLocation } from 'react-router-dom'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
...@@ -52,44 +49,20 @@ export const SearchBar = () => { ...@@ -52,44 +49,20 @@ export const SearchBar = () => {
const { pathname } = useLocation() const { pathname } = useLocation()
const isMobile = useIsMobile() const isMobile = useIsMobile()
const isTablet = useIsTablet() const isTablet = useIsTablet()
const isNftGraphqlEnabled = useNftGraphqlEnabled()
const isNavSearchInputVisible = useIsNavSearchInputVisible() const isNavSearchInputVisible = useIsNavSearchInputVisible()
useOnClickOutside(searchRef, () => { useOnClickOutside(searchRef, () => {
isOpen && toggleOpen() isOpen && toggleOpen()
}) })
const { data: queryCollections, isLoading: queryCollectionsAreLoading } = useQuery( const { data: collections, loading: collectionsAreLoading } = useCollectionSearch(debouncedSearchValue)
['searchCollections', debouncedSearchValue],
() => fetchSearchCollections(debouncedSearchValue),
{
refetchOnWindowFocus: false,
refetchOnMount: false,
refetchOnReconnect: false,
enabled: !!debouncedSearchValue.length,
}
)
const { data: gqlCollections, loading: gqlCollectionsAreLoading } = useCollectionSearch(debouncedSearchValue)
const { gatedCollections, gatedCollectionsAreLoading } = useMemo(() => {
return isNftGraphqlEnabled
? {
gatedCollections: gqlCollections,
gatedCollectionsAreLoading: gqlCollectionsAreLoading,
}
: {
gatedCollections: queryCollections,
gatedCollectionsAreLoading: queryCollectionsAreLoading,
}
}, [gqlCollections, gqlCollectionsAreLoading, isNftGraphqlEnabled, queryCollections, queryCollectionsAreLoading])
const { chainId } = useWeb3React() const { chainId } = useWeb3React()
const { data: tokens, loading: tokensAreLoading } = useSearchTokens(debouncedSearchValue, chainId ?? 1) const { data: tokens, loading: tokensAreLoading } = useSearchTokens(debouncedSearchValue, chainId ?? 1)
const isNFTPage = useIsNftPage() const isNFTPage = useIsNftPage()
const [reducedTokens, reducedCollections] = organizeSearchResults(isNFTPage, tokens ?? [], gatedCollections ?? []) const [reducedTokens, reducedCollections] = organizeSearchResults(isNFTPage, tokens ?? [], collections ?? [])
// close dropdown on escape // close dropdown on escape
useEffect(() => { useEffect(() => {
...@@ -105,7 +78,7 @@ export const SearchBar = () => { ...@@ -105,7 +78,7 @@ export const SearchBar = () => {
return () => { return () => {
document.removeEventListener('keydown', escapeKeyDownHandler) document.removeEventListener('keydown', escapeKeyDownHandler)
} }
}, [isOpen, toggleOpen, gatedCollections]) }, [isOpen, toggleOpen, collections])
// clear searchbar when changing pages // clear searchbar when changing pages
useEffect(() => { useEffect(() => {
...@@ -227,7 +200,7 @@ export const SearchBar = () => { ...@@ -227,7 +200,7 @@ export const SearchBar = () => {
collections={reducedCollections} collections={reducedCollections}
queryText={debouncedSearchValue} queryText={debouncedSearchValue}
hasInput={debouncedSearchValue.length > 0} hasInput={debouncedSearchValue.length > 0}
isLoading={tokensAreLoading || gatedCollectionsAreLoading} isLoading={tokensAreLoading || collectionsAreLoading}
/> />
)} )}
</Box> </Box>
......
...@@ -4,7 +4,6 @@ import { InterfaceSectionName, NavBarSearchTypes } from '@uniswap/analytics-even ...@@ -4,7 +4,6 @@ import { InterfaceSectionName, NavBarSearchTypes } from '@uniswap/analytics-even
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import Badge from 'components/Badge' import Badge from 'components/Badge'
import { SupportedChainId } from 'constants/chains' import { SupportedChainId } from 'constants/chains'
import { useNftGraphqlEnabled } from 'featureFlags/flags/nftlGraphql'
import { HistoryDuration, SafetyLevel } from 'graphql/data/__generated__/types-and-hooks' import { HistoryDuration, SafetyLevel } from 'graphql/data/__generated__/types-and-hooks'
import { useTrendingCollections } from 'graphql/data/nft/TrendingCollections' import { useTrendingCollections } from 'graphql/data/nft/TrendingCollections'
import { SearchToken } from 'graphql/data/SearchTokens' import { SearchToken } from 'graphql/data/SearchTokens'
...@@ -13,11 +12,8 @@ import { useIsNftPage } from 'hooks/useIsNftPage' ...@@ -13,11 +12,8 @@ import { useIsNftPage } from 'hooks/useIsNftPage'
import { Box } from 'nft/components/Box' import { Box } from 'nft/components/Box'
import { Column, Row } from 'nft/components/Flex' import { Column, Row } from 'nft/components/Flex'
import { subheadSmall } from 'nft/css/common.css' import { subheadSmall } from 'nft/css/common.css'
import { fetchTrendingCollections } from 'nft/queries' import { GenieCollection, TrendingCollection } from 'nft/types'
import { GenieCollection, TimePeriod, TrendingCollection } from 'nft/types'
import { formatEthPrice } from 'nft/utils/currency'
import { ReactNode, useEffect, useMemo, useState } from 'react' import { ReactNode, useEffect, useMemo, useState } from 'react'
import { useQuery } from 'react-query'
import { useLocation } from 'react-router-dom' import { useLocation } from 'react-router-dom'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { ThemedText } from 'theme' import { ThemedText } from 'theme'
...@@ -149,34 +145,30 @@ export const SearchBarDropdown = ({ ...@@ -149,34 +145,30 @@ export const SearchBarDropdown = ({
const { pathname } = useLocation() const { pathname } = useLocation()
const { chainId } = useWeb3React() const { chainId } = useWeb3React()
const isNFTPage = useIsNftPage() const isNFTPage = useIsNftPage()
const isNftGraphqlEnabled = useNftGraphqlEnabled()
const isTokenPage = pathname.includes('/tokens') const isTokenPage = pathname.includes('/tokens')
const [resultsState, setResultsState] = useState<ReactNode>() const [resultsState, setResultsState] = useState<ReactNode>()
const { data: trendingCollectionResults, isLoading: trendingCollectionsAreLoading } = useQuery( const { data: trendingCollections, loading: trendingCollectionsAreLoading } = useTrendingCollections(
['trendingCollections', 'eth', 'twenty_four_hours'], 3,
() => fetchTrendingCollections({ volumeType: 'eth', timePeriod: 'ONE_DAY' as TimePeriod, size: 3 }) HistoryDuration.Day
) )
const { data: gqlData, loading } = useTrendingCollections(3, HistoryDuration.Day) const formattedTrendingCollections = useMemo(() => {
return !trendingCollectionsAreLoading
const trendingCollections = useMemo(() => { ? trendingCollections
const gatedTrendingCollections = isNftGraphqlEnabled ? gqlData : trendingCollectionResults ?.map((collection) => ({
return gatedTrendingCollections && (!isNftGraphqlEnabled || !loading)
? gatedTrendingCollections
.map((collection) => ({
...collection, ...collection,
collectionAddress: collection.address, collectionAddress: collection.address,
floorPrice: isNftGraphqlEnabled ? collection.floor : formatEthPrice(collection.floor?.toString()), floorPrice: collection.floor,
stats: { stats: {
total_supply: collection.totalSupply, total_supply: collection.totalSupply,
one_day_change: collection.floorChange, one_day_change: collection.floorChange,
floor_price: isNftGraphqlEnabled ? collection.floor : formatEthPrice(collection.floor?.toString()), floor_price: collection.floor,
}, },
})) }))
.slice(0, isNFTPage ? 3 : 2) .slice(0, isNFTPage ? 3 : 2) ?? []
: [...Array<GenieCollection>(isNFTPage ? 3 : 2)] : [...Array<GenieCollection>(isNFTPage ? 3 : 2)]
}, [gqlData, isNFTPage, isNftGraphqlEnabled, loading, trendingCollectionResults]) }, [trendingCollections, isNFTPage, trendingCollectionsAreLoading])
const { data: trendingTokenData } = useTrendingTokens(useWeb3React().chainId) const { data: trendingTokenData } = useTrendingTokens(useWeb3React().chainId)
...@@ -189,7 +181,7 @@ export const SearchBarDropdown = ({ ...@@ -189,7 +181,7 @@ export const SearchBarDropdown = ({
const totalSuggestions = hasInput const totalSuggestions = hasInput
? tokens.length + collections.length ? tokens.length + collections.length
: Math.min(shortenedHistory.length, 2) + : Math.min(shortenedHistory.length, 2) +
(isNFTPage || !isTokenPage ? trendingCollections?.length ?? 0 : 0) + (isNFTPage || !isTokenPage ? formattedTrendingCollections?.length ?? 0 : 0) +
(isTokenPage || !isNFTPage ? trendingTokens?.length ?? 0 : 0) (isTokenPage || !isNFTPage ? trendingTokens?.length ?? 0 : 0)
// Navigate search results via arrow keys // Navigate search results via arrow keys
...@@ -324,7 +316,7 @@ export const SearchBarDropdown = ({ ...@@ -324,7 +316,7 @@ export const SearchBarDropdown = ({
startingIndex={shortenedHistory.length + (isNFTPage ? 0 : trendingTokens?.length ?? 0)} startingIndex={shortenedHistory.length + (isNFTPage ? 0 : trendingTokens?.length ?? 0)}
setHoveredIndex={setHoveredIndex} setHoveredIndex={setHoveredIndex}
toggleOpen={toggleOpen} toggleOpen={toggleOpen}
suggestions={trendingCollections as unknown as GenieCollection[]} suggestions={formattedTrendingCollections as unknown as GenieCollection[]}
eventProperties={{ eventProperties={{
suggestion_type: NavBarSearchTypes.COLLECTION_TRENDING, suggestion_type: NavBarSearchTypes.COLLECTION_TRENDING,
...eventProperties, ...eventProperties,
...@@ -343,8 +335,7 @@ export const SearchBarDropdown = ({ ...@@ -343,8 +335,7 @@ export const SearchBarDropdown = ({
isLoading, isLoading,
tokens, tokens,
collections, collections,
trendingCollections, formattedTrendingCollections,
trendingCollectionsAreLoading,
trendingTokens, trendingTokens,
trendingTokenData, trendingTokenData,
hoveredIndex, hoveredIndex,
...@@ -358,6 +349,7 @@ export const SearchBarDropdown = ({ ...@@ -358,6 +349,7 @@ export const SearchBarDropdown = ({
totalSuggestions, totalSuggestions,
trace, trace,
searchHistory, searchHistory,
trendingCollectionsAreLoading,
]) ])
const showBNBComingSoonBadge = chainId === SupportedChainId.BNB && !isLoading const showBNBComingSoonBadge = chainId === SupportedChainId.BNB && !isLoading
......
...@@ -8,6 +8,5 @@ export enum FeatureFlag { ...@@ -8,6 +8,5 @@ export enum FeatureFlag {
fiatOnRampButtonOnSwap = 'fiat_on_ramp_button_on_swap_page', fiatOnRampButtonOnSwap = 'fiat_on_ramp_button_on_swap_page',
swapWidget = 'swap_widget_replacement_enabled', swapWidget = 'swap_widget_replacement_enabled',
statsigDummy = 'web_dummy_gate_amplitude_id', statsigDummy = 'web_dummy_gate_amplitude_id',
nftGraphql = 'nft_graphql_migration',
detailsV2 = 'details_v2', detailsV2 = 'details_v2',
} }
import { BaseVariant, FeatureFlag, useBaseFlag } from '../index'
export function useNftGraphqlFlag(): BaseVariant {
return useBaseFlag(FeatureFlag.nftGraphql)
}
export function useNftGraphqlEnabled(): boolean {
return useNftGraphqlFlag() === BaseVariant.Enabled
}
export { BaseVariant as NftGraphqlVariant }
import { isAddress } from '@ethersproject/address' import { isAddress } from '@ethersproject/address'
import { useNftGraphqlEnabled } from 'featureFlags/flags/nftlGraphql'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { GenieCollection } from 'nft/types' import { GenieCollection } from 'nft/types'
import { blocklistedCollections } from 'nft/utils' import { blocklistedCollections } from 'nft/utils'
...@@ -80,9 +79,8 @@ function useCollectionQuerySearch(query: string, skip?: boolean): useCollectionS ...@@ -80,9 +79,8 @@ function useCollectionQuerySearch(query: string, skip?: boolean): useCollectionS
} }
export function useCollectionSearch(queryOrAddress: string): useCollectionSearchReturnProps { export function useCollectionSearch(queryOrAddress: string): useCollectionSearchReturnProps {
const isNftGraphqlEnabled = useNftGraphqlEnabled()
const isName = !isAddress(queryOrAddress.toLowerCase()) const isName = !isAddress(queryOrAddress.toLowerCase())
const queryResult = useCollectionQuerySearch(queryOrAddress, isNftGraphqlEnabled ? !isName : true) const queryResult = useCollectionQuerySearch(queryOrAddress, /* skip= */ !isName)
const addressResult = useCollection(queryOrAddress, isNftGraphqlEnabled ? isName : true) const addressResult = useCollection(queryOrAddress, /* skip= */ isName)
return isName ? queryResult : { data: [addressResult.data], loading: addressResult.loading } return isName ? queryResult : { data: [addressResult.data], loading: addressResult.loading }
} }
import { WatchQueryFetchPolicy } from '@apollo/client' import { WatchQueryFetchPolicy } from '@apollo/client'
import { useNftGraphqlEnabled } from 'featureFlags/flags/nftlGraphql'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { ActivityEvent } from 'nft/types' import { ActivityEvent } from 'nft/types'
import { useCallback, useMemo } from 'react' import { useCallback, useMemo } from 'react'
...@@ -71,13 +70,11 @@ gql` ...@@ -71,13 +70,11 @@ gql`
` `
export function useNftActivity(filter: NftActivityFilterInput, first?: number, fetchPolicy?: WatchQueryFetchPolicy) { export function useNftActivity(filter: NftActivityFilterInput, first?: number, fetchPolicy?: WatchQueryFetchPolicy) {
const isNftGraphqlEnabled = useNftGraphqlEnabled()
const { data, loading, fetchMore, error } = useNftActivityQuery({ const { data, loading, fetchMore, error } = useNftActivityQuery({
variables: { variables: {
filter, filter,
first, first,
}, },
skip: !isNftGraphqlEnabled,
fetchPolicy, fetchPolicy,
}) })
......
import { useNftGraphqlEnabled } from 'featureFlags/flags/nftlGraphql'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { TrendingCollection } from 'nft/types' import { TrendingCollection } from 'nft/types'
import { useMemo } from 'react' import { useMemo } from 'react'
...@@ -53,13 +52,11 @@ gql` ...@@ -53,13 +52,11 @@ gql`
` `
export function useTrendingCollections(size: number, timePeriod: HistoryDuration) { export function useTrendingCollections(size: number, timePeriod: HistoryDuration) {
const isNftGraphqlEnabled = useNftGraphqlEnabled()
const { data, loading, error } = useTrendingCollectionsQuery({ const { data, loading, error } = useTrendingCollectionsQuery({
variables: { variables: {
size, size,
timePeriod, timePeriod,
}, },
skip: !isNftGraphqlEnabled,
}) })
const trendingCollections: TrendingCollection[] | undefined = useMemo( const trendingCollections: TrendingCollection[] | undefined = useMemo(
......
import { OpacityHoverState } from 'components/Common' import { OpacityHoverState } from 'components/Common'
import { useNftGraphqlEnabled } from 'featureFlags/flags/nftlGraphql'
import { NftActivityType } from 'graphql/data/__generated__/types-and-hooks' import { NftActivityType } from 'graphql/data/__generated__/types-and-hooks'
import { useNftActivity } from 'graphql/data/nft/NftActivity' import { useNftActivity } from 'graphql/data/nft/NftActivity'
import { Box } from 'nft/components/Box' import { Box } from 'nft/components/Box'
import { Column, Row } from 'nft/components/Flex' import { Column, Row } from 'nft/components/Flex'
import { themeVars, vars } from 'nft/css/sprinkles.css' import { themeVars, vars } from 'nft/css/sprinkles.css'
import { useBag, useIsMobile } from 'nft/hooks' import { useBag, useIsMobile } from 'nft/hooks'
import { ActivityFetcher } from 'nft/queries/genie/ActivityFetcher' import { ActivityEvent, ActivityEventType } from 'nft/types'
import { ActivityEvent, ActivityEventResponse, ActivityEventType } from 'nft/types'
import { fetchPrice } from 'nft/utils/fetchPrice' import { fetchPrice } from 'nft/utils/fetchPrice'
import { useCallback, useEffect, useReducer, useState } from 'react' import { useCallback, useEffect, useReducer, useState } from 'react'
import InfiniteScroll from 'react-infinite-scroll-component' import InfiniteScroll from 'react-infinite-scroll-component'
import { useInfiniteQuery } from 'react-query'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { useIsDarkMode } from 'theme/components/ThemeToggle' import { useIsDarkMode } from 'theme/components/ThemeToggle'
...@@ -66,51 +63,13 @@ export const reduceFilters = (state: typeof initialFilterState, action: { eventT ...@@ -66,51 +63,13 @@ export const reduceFilters = (state: typeof initialFilterState, action: { eventT
const baseHref = (event: ActivityEvent) => `/#/nfts/asset/${event.collectionAddress}/${event.tokenId}?origin=activity` const baseHref = (event: ActivityEvent) => `/#/nfts/asset/${event.collectionAddress}/${event.tokenId}?origin=activity`
export const Activity = ({ contractAddress, rarityVerified, collectionName, chainId }: ActivityProps) => { export const Activity = ({ contractAddress, rarityVerified, collectionName, chainId }: ActivityProps) => {
const isNftGraphqlEnabled = useNftGraphqlEnabled()
const [activeFilters, filtersDispatch] = useReducer(reduceFilters, initialFilterState) const [activeFilters, filtersDispatch] = useReducer(reduceFilters, initialFilterState)
const { const {
data: eventsData, nftActivity,
fetchNextPage, hasNext: hasNextActivity,
hasNextPage, loadMore: loadMoreActivities,
isFetchingNextPage, loading: activitiesAreLoading,
isSuccess,
isLoading,
} = useInfiniteQuery<ActivityEventResponse>(
[
'collectionActivity',
{
contractAddress,
activeFilters,
},
],
async ({ pageParam = '' }) => {
return await ActivityFetcher(
contractAddress,
{
eventTypes: Object.keys(activeFilters)
.filter((key) => activeFilters[key as ActivityEventType])
.map((key) => key as ActivityEventType),
},
pageParam
)
},
{
getNextPageParam: (lastPage) => {
return lastPage.events?.length === 25 ? lastPage.cursor : undefined
},
refetchInterval: 15000,
refetchIntervalInBackground: false,
refetchOnWindowFocus: false,
refetchOnMount: false,
}
)
const {
nftActivity: gqlEventsData,
hasNext,
loadMore,
loading,
} = useNftActivity( } = useNftActivity(
{ {
activityTypes: Object.keys(activeFilters) activityTypes: Object.keys(activeFilters)
...@@ -121,18 +80,7 @@ export const Activity = ({ contractAddress, rarityVerified, collectionName, chai ...@@ -121,18 +80,7 @@ export const Activity = ({ contractAddress, rarityVerified, collectionName, chai
25 25
) )
const { events, gatedHasNext, gatedLoadMore, gatedLoading, gatedIsLoadingMore } = { const isLoadingMore = hasNextActivity && nftActivity?.length
events: isNftGraphqlEnabled
? gqlEventsData
: isSuccess
? eventsData?.pages.map((page) => page.events).flat()
: undefined,
gatedHasNext: isNftGraphqlEnabled ? hasNext : hasNextPage,
gatedLoadMore: isNftGraphqlEnabled ? loadMore : fetchNextPage,
gatedLoading: isNftGraphqlEnabled ? loading : isLoading,
gatedIsLoadingMore: isNftGraphqlEnabled ? hasNext && gqlEventsData?.length : isFetchingNextPage,
}
const itemsInBag = useBag((state) => state.itemsInBag) const itemsInBag = useBag((state) => state.itemsInBag)
const addAssetsToBag = useBag((state) => state.addAssetsToBag) const addAssetsToBag = useBag((state) => state.addAssetsToBag)
const removeAssetsFromBag = useBag((state) => state.removeAssetsFromBag) const removeAssetsFromBag = useBag((state) => state.removeAssetsFromBag)
...@@ -173,20 +121,20 @@ export const Activity = ({ contractAddress, rarityVerified, collectionName, chai ...@@ -173,20 +121,20 @@ export const Activity = ({ contractAddress, rarityVerified, collectionName, chai
<Filter eventType={ActivityEventType.Sale} /> <Filter eventType={ActivityEventType.Sale} />
<Filter eventType={ActivityEventType.Transfer} /> <Filter eventType={ActivityEventType.Transfer} />
</Row> </Row>
{gatedLoading ? ( {activitiesAreLoading ? (
<ActivityLoader /> <ActivityLoader />
) : ( ) : (
events && ( nftActivity && (
<Column marginTop="36"> <Column marginTop="36">
<HeaderRow /> <HeaderRow />
<InfiniteScroll <InfiniteScroll
next={gatedLoadMore} next={loadMoreActivities}
hasMore={!!gatedHasNext} hasMore={!!hasNextActivity}
loader={gatedIsLoadingMore ? <ActivityPageLoader rowCount={2} /> : null} loader={isLoadingMore ? <ActivityPageLoader rowCount={2} /> : null}
dataLength={events?.length ?? 0} dataLength={nftActivity?.length ?? 0}
style={{ overflow: 'unset' }} style={{ overflow: 'unset' }}
> >
{events.map( {nftActivity.map(
(event, i) => (event, i) =>
event.eventType && ( event.eventType && (
<Box <Box
......
...@@ -2,7 +2,6 @@ import { sendAnalyticsEvent, useTrace } from '@uniswap/analytics' ...@@ -2,7 +2,6 @@ import { sendAnalyticsEvent, useTrace } from '@uniswap/analytics'
import { InterfacePageName, NFTEventName } from '@uniswap/analytics-events' import { InterfacePageName, NFTEventName } from '@uniswap/analytics-events'
import { ChainId } from '@uniswap/smart-order-router' import { ChainId } from '@uniswap/smart-order-router'
import { MouseoverTooltip } from 'components/Tooltip' import { MouseoverTooltip } from 'components/Tooltip'
import { useNftGraphqlEnabled } from 'featureFlags/flags/nftlGraphql'
import { NftActivityType, OrderStatus } from 'graphql/data/__generated__/types-and-hooks' import { NftActivityType, OrderStatus } from 'graphql/data/__generated__/types-and-hooks'
import { Box } from 'nft/components/Box' import { Box } from 'nft/components/Box'
import { Column, Row } from 'nft/components/Flex' import { Column, Row } from 'nft/components/Flex'
...@@ -26,8 +25,8 @@ import { ...@@ -26,8 +25,8 @@ import {
} from 'nft/types' } from 'nft/types'
import { shortenAddress } from 'nft/utils/address' import { shortenAddress } from 'nft/utils/address'
import { buildActivityAsset } from 'nft/utils/buildActivityAsset' import { buildActivityAsset } from 'nft/utils/buildActivityAsset'
import { formatEth, formatEthPrice } from 'nft/utils/currency' import { formatEth } from 'nft/utils/currency'
import { getTimeDifference, isValidDate } from 'nft/utils/date' import { getTimeDifference } from 'nft/utils/date'
import { putCommas } from 'nft/utils/putCommas' import { putCommas } from 'nft/utils/putCommas'
import { MouseEvent, useMemo, useState } from 'react' import { MouseEvent, useMemo, useState } from 'react'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
...@@ -95,10 +94,9 @@ export const BuyCell = ({ ...@@ -95,10 +94,9 @@ export const BuyCell = ({
isMobile, isMobile,
ethPriceInUSD, ethPriceInUSD,
}: BuyCellProps) => { }: BuyCellProps) => {
const isNftGraphqlEnabled = useNftGraphqlEnabled()
const asset = useMemo( const asset = useMemo(
() => buildActivityAsset(event, collectionName, ethPriceInUSD, isNftGraphqlEnabled), () => buildActivityAsset(event, collectionName, ethPriceInUSD),
[event, collectionName, ethPriceInUSD, isNftGraphqlEnabled] [event, collectionName, ethPriceInUSD]
) )
const isSelected = useMemo(() => { const isSelected = useMemo(() => {
return itemsInBag.some((item) => asset.tokenId === item.asset.tokenId && asset.address === item.asset.address) return itemsInBag.some((item) => asset.tokenId === item.asset.tokenId && asset.address === item.asset.address)
...@@ -187,16 +185,7 @@ const PriceTooltip = ({ price }: { price: string }) => ( ...@@ -187,16 +185,7 @@ const PriceTooltip = ({ price }: { price: string }) => (
) )
export const PriceCell = ({ marketplace, price }: { marketplace?: Markets | string; price?: string | number }) => { export const PriceCell = ({ marketplace, price }: { marketplace?: Markets | string; price?: string | number }) => {
const isNftGraphqlEnabled = useNftGraphqlEnabled() const formattedPrice = useMemo(() => (price ? formatEth(parseFloat(price?.toString())) : null), [price])
const formattedPrice = useMemo(
() =>
price
? isNftGraphqlEnabled
? formatEth(parseFloat(price?.toString()))
: putCommas(formatEthPrice(price.toString()))?.toString()
: null,
[isNftGraphqlEnabled, price]
)
return ( return (
<Row display={{ sm: 'none', md: 'flex' }} gap="8"> <Row display={{ sm: 'none', md: 'flex' }} gap="8">
...@@ -268,25 +257,16 @@ export const EventCell = ({ ...@@ -268,25 +257,16 @@ export const EventCell = ({
price, price,
isMobile, isMobile,
}: EventCellProps) => { }: EventCellProps) => {
const isNftGraphqlEnabled = useNftGraphqlEnabled() const formattedPrice = useMemo(() => (price ? formatEth(parseFloat(price?.toString())) : null), [price])
const formattedPrice = useMemo(
() =>
price
? isNftGraphqlEnabled
? formatEth(parseFloat(price?.toString()))
: putCommas(formatEthPrice(price.toString()))?.toString()
: null,
[isNftGraphqlEnabled, price]
)
return ( return (
<Column height="full" justifyContent="center" gap="4"> <Column height="full" justifyContent="center" gap="4">
<Row className={styles.eventDetail} color={eventColors(eventType)}> <Row className={styles.eventDetail} color={eventColors(eventType)}>
{renderEventIcon(eventType)} {renderEventIcon(eventType)}
{ActivityEventTypeDisplay[eventType]} {ActivityEventTypeDisplay[eventType]}
</Row> </Row>
{eventTimestamp && (isValidDate(eventTimestamp) || isNftGraphqlEnabled) && !isMobile && !eventOnly && ( {eventTimestamp && !isMobile && !eventOnly && (
<Row className={styles.eventTime}> <Row className={styles.eventTime}>
{getTimeDifference(eventTimestamp.toString(), isNftGraphqlEnabled)} {getTimeDifference(eventTimestamp.toString())}
{eventTransactionHash && <ExternalLinkIcon transactionHash={eventTransactionHash} />} {eventTransactionHash && <ExternalLinkIcon transactionHash={eventTransactionHash} />}
</Row> </Row>
)} )}
...@@ -378,7 +358,6 @@ const getItemImage = (tokenMetadata?: TokenMetadata): string | undefined => { ...@@ -378,7 +358,6 @@ const getItemImage = (tokenMetadata?: TokenMetadata): string | undefined => {
export const ItemCell = ({ event, rarityVerified, collectionName, eventTimestamp, isMobile }: ItemCellProps) => { export const ItemCell = ({ event, rarityVerified, collectionName, eventTimestamp, isMobile }: ItemCellProps) => {
const [loaded, setLoaded] = useState(false) const [loaded, setLoaded] = useState(false)
const [noContent, setNoContent] = useState(!getItemImage(event.tokenMetadata)) const [noContent, setNoContent] = useState(!getItemImage(event.tokenMetadata))
const isNftGraphqlEnabled = useNftGraphqlEnabled()
return ( return (
<Row gap="16" overflow="hidden" whiteSpace="nowrap"> <Row gap="16" overflow="hidden" whiteSpace="nowrap">
...@@ -407,10 +386,7 @@ export const ItemCell = ({ event, rarityVerified, collectionName, eventTimestamp ...@@ -407,10 +386,7 @@ export const ItemCell = ({ event, rarityVerified, collectionName, eventTimestamp
collectionName={collectionName} collectionName={collectionName}
/> />
)} )}
{isMobile && {isMobile && eventTimestamp && getTimeDifference(eventTimestamp.toString())}
eventTimestamp &&
(isValidDate(eventTimestamp) || isNftGraphqlEnabled) &&
getTimeDifference(eventTimestamp.toString(), isNftGraphqlEnabled)}
</Column> </Column>
</Row> </Row>
) )
......
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { OpacityHoverState, ScrollBarStyles } from 'components/Common' import { OpacityHoverState, ScrollBarStyles } from 'components/Common'
import { LoadingBubble } from 'components/Tokens/loading' import { LoadingBubble } from 'components/Tokens/loading'
import { useNftGraphqlEnabled } from 'featureFlags/flags/nftlGraphql'
import { EventCell, MarketplaceIcon } from 'nft/components/collection/ActivityCells' import { EventCell, MarketplaceIcon } from 'nft/components/collection/ActivityCells'
import { ActivityEvent } from 'nft/types' import { ActivityEvent } from 'nft/types'
import { shortenAddress } from 'nft/utils/address' import { shortenAddress } from 'nft/utils/address'
import { formatEth, formatEthPrice } from 'nft/utils/currency' import { formatEth } from 'nft/utils/currency'
import { getTimeDifference } from 'nft/utils/date' import { getTimeDifference } from 'nft/utils/date'
import { putCommas } from 'nft/utils/putCommas'
import { ReactNode } from 'react' import { ReactNode } from 'react'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
...@@ -149,17 +147,12 @@ export const LoadingAssetActivity = ({ rowCount }: { rowCount: number }) => { ...@@ -149,17 +147,12 @@ export const LoadingAssetActivity = ({ rowCount }: { rowCount: number }) => {
} }
const AssetActivity = ({ events }: { events: ActivityEvent[] | undefined }) => { const AssetActivity = ({ events }: { events: ActivityEvent[] | undefined }) => {
const isNftGraphqlEnabled = useNftGraphqlEnabled()
return ( return (
<ActivityTable> <ActivityTable>
{events && {events &&
events.map((event, index) => { events.map((event, index) => {
const { eventTimestamp, eventType, fromAddress, marketplace, price, toAddress, transactionHash } = event const { eventTimestamp, eventType, fromAddress, marketplace, price, toAddress, transactionHash } = event
const formattedPrice = price const formattedPrice = price ? formatEth(parseFloat(price ?? '')) : null
? isNftGraphqlEnabled
? formatEth(parseFloat(price ?? ''))
: putCommas(formatEthPrice(price)).toString()
: null
if (!eventType) return null if (!eventType) return null
return ( return (
<TR key={index}> <TR key={index}>
...@@ -195,7 +188,7 @@ const AssetActivity = ({ events }: { events: ActivityEvent[] | undefined }) => { ...@@ -195,7 +188,7 @@ const AssetActivity = ({ events }: { events: ActivityEvent[] | undefined }) => {
</Link> </Link>
)} )}
</TD> </TD>
<TD>{eventTimestamp && getTimeDifference(eventTimestamp.toString(), isNftGraphqlEnabled)}</TD> <TD>{eventTimestamp && getTimeDifference(eventTimestamp.toString())}</TD>
</TR> </TR>
) )
})} })}
......
import { OpacityHoverState, ScrollBarStyles } from 'components/Common' import { OpacityHoverState, ScrollBarStyles } from 'components/Common'
import Resource from 'components/Tokens/TokenDetails/Resource' import Resource from 'components/Tokens/TokenDetails/Resource'
import { MouseoverTooltip } from 'components/Tooltip/index' import { MouseoverTooltip } from 'components/Tooltip/index'
import { useNftGraphqlEnabled } from 'featureFlags/flags/nftlGraphql'
import { NftActivityType } from 'graphql/data/__generated__/types-and-hooks' import { NftActivityType } from 'graphql/data/__generated__/types-and-hooks'
import { useNftActivity } from 'graphql/data/nft/NftActivity' import { useNftActivity } from 'graphql/data/nft/NftActivity'
import { Box } from 'nft/components/Box' import { Box } from 'nft/components/Box'
...@@ -10,16 +9,14 @@ import { LoadingSparkle } from 'nft/components/common/Loading/LoadingSparkle' ...@@ -10,16 +9,14 @@ import { LoadingSparkle } from 'nft/components/common/Loading/LoadingSparkle'
import { AssetPriceDetails } from 'nft/components/details/AssetPriceDetails' import { AssetPriceDetails } from 'nft/components/details/AssetPriceDetails'
import { Center } from 'nft/components/Flex' import { Center } from 'nft/components/Flex'
import { themeVars, vars } from 'nft/css/sprinkles.css' import { themeVars, vars } from 'nft/css/sprinkles.css'
import { ActivityFetcher } from 'nft/queries/genie/ActivityFetcher' import { ActivityEventType, CollectionInfoForAsset, GenieAsset } from 'nft/types'
import { ActivityEventResponse, ActivityEventType, CollectionInfoForAsset, GenieAsset } from 'nft/types'
import { shortenAddress } from 'nft/utils/address' import { shortenAddress } from 'nft/utils/address'
import { formatEth, formatEthPrice } from 'nft/utils/currency' import { formatEth } from 'nft/utils/currency'
import { isAudio } from 'nft/utils/isAudio' import { isAudio } from 'nft/utils/isAudio'
import { isVideo } from 'nft/utils/isVideo' import { isVideo } from 'nft/utils/isVideo'
import { putCommas } from 'nft/utils/putCommas' import { putCommas } from 'nft/utils/putCommas'
import { useCallback, useMemo, useReducer, useState } from 'react' import { useCallback, useMemo, useReducer, useState } from 'react'
import InfiniteScroll from 'react-infinite-scroll-component' import InfiniteScroll from 'react-infinite-scroll-component'
import { useInfiniteQuery, useQuery } from 'react-query'
import { Link as RouterLink } from 'react-router-dom' import { Link as RouterLink } from 'react-router-dom'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { useIsDarkMode } from 'theme/components/ThemeToggle' import { useIsDarkMode } from 'theme/components/ThemeToggle'
...@@ -246,7 +243,6 @@ interface AssetDetailsProps { ...@@ -246,7 +243,6 @@ interface AssetDetailsProps {
} }
export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => { export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => {
const isNftGraphqlEnabled = useNftGraphqlEnabled()
const [dominantColor] = useState<[number, number, number]>([0, 0, 0]) const [dominantColor] = useState<[number, number, number]>([0, 0, 0])
const { rarityProvider } = useMemo( const { rarityProvider } = useMemo(
...@@ -274,34 +270,6 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => { ...@@ -274,34 +270,6 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => {
const { address: contractAddress, tokenId: token_id } = asset const { address: contractAddress, tokenId: token_id } = asset
const { data: priceData } = useQuery<ActivityEventResponse>(
[
'collectionActivity',
{
contractAddress,
},
],
async ({ pageParam = '' }) => {
return await ActivityFetcher(
contractAddress,
{
token_id,
eventTypes: [ActivityEventType.Sale],
},
pageParam,
'1'
)
},
{
getNextPageParam: (lastPage) => {
return lastPage.events?.length === 25 ? lastPage.cursor : undefined
},
refetchInterval: 15000,
refetchIntervalInBackground: false,
refetchOnWindowFocus: false,
refetchOnMount: false,
}
)
const { nftActivity: gqlPriceData } = useNftActivity( const { nftActivity: gqlPriceData } = useNftActivity(
{ {
activityTypes: [NftActivityType.Sale], activityTypes: [NftActivityType.Sale],
...@@ -312,14 +280,8 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => { ...@@ -312,14 +280,8 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => {
'no-cache' 'no-cache'
) )
let formattedPrice const weiPrice = gqlPriceData?.[0]?.price
if (isNftGraphqlEnabled) { const formattedPrice = weiPrice ? formatEth(parseFloat(weiPrice)) : undefined
const weiPrice = gqlPriceData?.[0]?.price
formattedPrice = weiPrice ? formatEth(parseFloat(weiPrice)) : undefined
} else {
const ethPrice = priceData?.events[0]?.price
formattedPrice = ethPrice ? putCommas(formatEthPrice(priceData?.events[0]?.price)).toString() : undefined
}
const [activeFilters, filtersDispatch] = useReducer(reduceFilters, initialFilterState) const [activeFilters, filtersDispatch] = useReducer(reduceFilters, initialFilterState)
const Filter = useCallback( const Filter = useCallback(
...@@ -344,50 +306,11 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => { ...@@ -344,50 +306,11 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => {
) )
const { const {
data: eventsData, nftActivity,
fetchNextPage, hasNext: hasNextActivity,
hasNextPage, loadMore: loadMoreActivities,
isFetchingNextPage, loading: activitiesAreLoading,
isSuccess, error: errorLoadingActivities,
isLoading: isActivityLoading,
} = useInfiniteQuery<ActivityEventResponse>(
[
'collectionActivity',
{
contractAddress,
activeFilters,
token_id,
},
],
async ({ pageParam = '' }) => {
return await ActivityFetcher(
contractAddress,
{
token_id,
eventTypes: Object.keys(activeFilters)
.map((key) => key as ActivityEventType)
.filter((key) => activeFilters[key]),
},
pageParam
)
},
{
getNextPageParam: (lastPage) => {
return lastPage.events?.length === 25 ? lastPage.cursor : undefined
},
refetchInterval: 15000,
refetchIntervalInBackground: false,
refetchOnWindowFocus: false,
refetchOnMount: false,
}
)
const {
nftActivity: gqlEventsData,
hasNext,
loadMore,
loading,
error,
} = useNftActivity( } = useNftActivity(
{ {
activityTypes: Object.keys(activeFilters) activityTypes: Object.keys(activeFilters)
...@@ -399,28 +322,6 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => { ...@@ -399,28 +322,6 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => {
25 25
) )
const { events, gatedHasNext, gatedLoadMore, gatedLoading, gatedSuccess } = useMemo(() => {
return {
events: isNftGraphqlEnabled ? gqlEventsData : eventsData?.pages.map((page) => page.events).flat(),
gatedHasNext: isNftGraphqlEnabled ? hasNext : hasNextPage,
gatedLoadMore: isNftGraphqlEnabled ? loadMore : fetchNextPage,
gatedLoading: isNftGraphqlEnabled ? loading : isActivityLoading,
gatedSuccess: isNftGraphqlEnabled ? !error : isSuccess,
}
}, [
error,
eventsData?.pages,
fetchNextPage,
gqlEventsData,
hasNext,
hasNextPage,
isActivityLoading,
isNftGraphqlEnabled,
isSuccess,
loadMore,
loading,
])
const rarity = asset?.rarity?.providers?.[0] const rarity = asset?.rarity?.providers?.[0]
const [showHolder, setShowHolder] = useState(false) const [showHolder, setShowHolder] = useState(false)
...@@ -482,27 +383,27 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => { ...@@ -482,27 +383,27 @@ export const AssetDetails = ({ asset, collection }: AssetDetailsProps) => {
<Filter eventType={ActivityEventType.Transfer} /> <Filter eventType={ActivityEventType.Transfer} />
<Filter eventType={ActivityEventType.CancelListing} /> <Filter eventType={ActivityEventType.CancelListing} />
</ActivitySelectContainer> </ActivitySelectContainer>
{gatedLoading ? ( {activitiesAreLoading ? (
<LoadingAssetActivity rowCount={10} /> <LoadingAssetActivity rowCount={10} />
) : events && events.length > 0 ? ( ) : nftActivity && nftActivity.length > 0 ? (
<InfiniteScroll <InfiniteScroll
next={gatedLoadMore} next={loadMoreActivities}
hasMore={!!gatedHasNext} hasMore={!!hasNextActivity}
loader={ loader={
isFetchingNextPage && ( activitiesAreLoading && (
<Center> <Center>
<LoadingSparkle /> <LoadingSparkle />
</Center> </Center>
) )
} }
dataLength={events?.length ?? 0} dataLength={nftActivity?.length ?? 0}
scrollableTarget="activityContainer" scrollableTarget="activityContainer"
> >
<AssetActivity events={events} /> <AssetActivity events={nftActivity} />
</InfiniteScroll> </InfiniteScroll>
) : ( ) : (
<> <>
{gatedSuccess && events && ( {!errorLoadingActivities && nftActivity && (
<EmptyActivitiesContainer> <EmptyActivitiesContainer>
<div>No activities yet</div> <div>No activities yet</div>
<Link to={`/nfts/collection/${asset.address}`}>View collection items</Link>{' '} <Link to={`/nfts/collection/${asset.address}`}>View collection items</Link>{' '}
......
import { useNftGraphqlEnabled } from 'featureFlags/flags/nftlGraphql'
import { HistoryDuration } from 'graphql/data/__generated__/types-and-hooks' import { HistoryDuration } from 'graphql/data/__generated__/types-and-hooks'
import { useTrendingCollections } from 'graphql/data/nft/TrendingCollections' import { useTrendingCollections } from 'graphql/data/nft/TrendingCollections'
import { fetchTrendingCollections } from 'nft/queries'
import { TimePeriod } from 'nft/types'
import { calculateCardIndex } from 'nft/utils' import { calculateCardIndex } from 'nft/utils'
import { useCallback, useMemo, useState } from 'react' import { useCallback, useMemo, useState } from 'react'
import { useQuery } from 'react-query'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { opacify } from 'theme/utils' import { opacify } from 'theme/utils'
...@@ -117,34 +113,17 @@ const TRENDING_COLLECTION_SIZE = 5 ...@@ -117,34 +113,17 @@ const TRENDING_COLLECTION_SIZE = 5
const Banner = () => { const Banner = () => {
const navigate = useNavigate() const navigate = useNavigate()
const isNftGraphqlEnabled = useNftGraphqlEnabled()
const { data: trendingCollections } = useTrendingCollections(
const { data } = useQuery(
['trendingCollections'],
() => {
return fetchTrendingCollections({
volumeType: 'eth',
timePeriod: TimePeriod.OneDay,
size: TRENDING_COLLECTION_SIZE + EXCLUDED_COLLECTIONS.length,
})
},
{
refetchOnReconnect: false,
refetchOnWindowFocus: false,
refetchOnMount: false,
}
)
const { data: gqlData } = useTrendingCollections(
TRENDING_COLLECTION_SIZE + EXCLUDED_COLLECTIONS.length, TRENDING_COLLECTION_SIZE + EXCLUDED_COLLECTIONS.length,
HistoryDuration.Day HistoryDuration.Day
) )
const collections = useMemo(() => { const collections = useMemo(() => {
const gatedData = isNftGraphqlEnabled ? gqlData : data return trendingCollections
return gatedData
?.filter((collection) => collection.address && !EXCLUDED_COLLECTIONS.includes(collection.address)) ?.filter((collection) => collection.address && !EXCLUDED_COLLECTIONS.includes(collection.address))
.slice(0, 5) .slice(0, TRENDING_COLLECTION_SIZE)
}, [data, gqlData, isNftGraphqlEnabled]) }, [trendingCollections])
const [activeCollectionIdx, setActiveCollectionIdx] = useState(0) const [activeCollectionIdx, setActiveCollectionIdx] = useState(0)
const onToggleNextSlide = useCallback( const onToggleNextSlide = useCallback(
......
import { formatNumberOrString, NumberType } from '@uniswap/conedison/format' import { formatNumberOrString, NumberType } from '@uniswap/conedison/format'
import { loadingAnimation } from 'components/Loader/styled' import { loadingAnimation } from 'components/Loader/styled'
import { LoadingBubble } from 'components/Tokens/loading' import { LoadingBubble } from 'components/Tokens/loading'
import { useNftGraphqlEnabled } from 'featureFlags/flags/nftlGraphql'
import { useCollection } from 'graphql/data/nft/Collection' import { useCollection } from 'graphql/data/nft/Collection'
import { VerifiedIcon } from 'nft/components/icons' import { VerifiedIcon } from 'nft/components/icons'
import { Markets, TrendingCollection } from 'nft/types' import { Markets, TrendingCollection } from 'nft/types'
import { ethNumberStandardFormatter, formatWeiToDecimal } from 'nft/utils' import { ethNumberStandardFormatter } from 'nft/utils'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { ThemedText } from 'theme/components/text' import { ThemedText } from 'theme/components/text'
...@@ -237,7 +236,6 @@ const MARKETS_ENUM_TO_NAME = { ...@@ -237,7 +236,6 @@ const MARKETS_ENUM_TO_NAME = {
export const CarouselCard = ({ collection, onClick }: CarouselCardProps) => { export const CarouselCard = ({ collection, onClick }: CarouselCardProps) => {
const { data: gqlCollection, loading } = useCollection(collection.address ?? '') const { data: gqlCollection, loading } = useCollection(collection.address ?? '')
const isNftGraphqlEnabled = useNftGraphqlEnabled()
if (loading) return <LoadingCarouselCard /> if (loading) return <LoadingCarouselCard />
...@@ -256,10 +254,7 @@ export const CarouselCard = ({ collection, onClick }: CarouselCardProps) => { ...@@ -256,10 +254,7 @@ export const CarouselCard = ({ collection, onClick }: CarouselCardProps) => {
<TableElement> <TableElement>
{collection.floor && ( {collection.floor && (
<ThemedText.SubHeaderSmall color="userThemeColor"> <ThemedText.SubHeaderSmall color="userThemeColor">
{isNftGraphqlEnabled {ethNumberStandardFormatter(collection.floor)} ETH Floor
? ethNumberStandardFormatter(collection.floor)
: formatWeiToDecimal(collection.floor.toString())}{' '}
ETH Floor
</ThemedText.SubHeaderSmall> </ThemedText.SubHeaderSmall>
)} )}
</TableElement> </TableElement>
......
import { formatEther } from '@ethersproject/units' import { formatEther } from '@ethersproject/units'
import { useNftGraphqlEnabled } from 'featureFlags/flags/nftlGraphql'
import { SquareArrowDownIcon, SquareArrowUpIcon, VerifiedIcon } from 'nft/components/icons' import { SquareArrowDownIcon, SquareArrowUpIcon, VerifiedIcon } from 'nft/components/icons'
import { useIsMobile } from 'nft/hooks' import { useIsMobile } from 'nft/hooks'
import { Denomination } from 'nft/types' import { Denomination } from 'nft/types'
import { volumeFormatter } from 'nft/utils' import { ethNumberStandardFormatter, volumeFormatter } from 'nft/utils'
import { ReactNode } from 'react' import { ReactNode } from 'react'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { ThemedText } from 'theme' import { ThemedText } from 'theme'
import { ethNumberStandardFormatter, formatWeiToDecimal } from '../../../utils/currency'
import * as styles from './Cells.css' import * as styles from './Cells.css'
const TruncatedText = styled.div` const TruncatedText = styled.div`
...@@ -114,13 +112,10 @@ export const EthCell = ({ ...@@ -114,13 +112,10 @@ export const EthCell = ({
denomination: Denomination denomination: Denomination
usdPrice?: number usdPrice?: number
}) => { }) => {
const isNftGraphqlEnabled = useNftGraphqlEnabled() const denominatedValue = getDenominatedValue(denomination, false, value, usdPrice)
const denominatedValue = getDenominatedValue(denomination, !isNftGraphqlEnabled, value, usdPrice)
const formattedValue = denominatedValue const formattedValue = denominatedValue
? denomination === Denomination.ETH ? denomination === Denomination.ETH
? isNftGraphqlEnabled ? ethNumberStandardFormatter(denominatedValue.toString(), false, true, false) + ' ETH'
? ethNumberStandardFormatter(denominatedValue.toString(), false, true, false) + ' ETH'
: formatWeiToDecimal(denominatedValue.toString(), true) + ' ETH'
: ethNumberStandardFormatter(denominatedValue, true, false, true) : ethNumberStandardFormatter(denominatedValue, true, false, true)
: '-' : '-'
......
import { BigNumber } from '@ethersproject/bignumber'
import { useNftGraphqlEnabled } from 'featureFlags/flags/nftlGraphql'
import { CollectionTableColumn, TimePeriod } from 'nft/types' import { CollectionTableColumn, TimePeriod } from 'nft/types'
import { useMemo } from 'react' import { useMemo } from 'react'
import { CellProps, Column, Row } from 'react-table' import { CellProps, Column, Row } from 'react-table'
...@@ -27,19 +25,11 @@ const compareFloats = (a?: number, b?: number): 1 | -1 => { ...@@ -27,19 +25,11 @@ const compareFloats = (a?: number, b?: number): 1 | -1 => {
} }
const CollectionTable = ({ data, timePeriod }: { data: CollectionTableColumn[]; timePeriod: TimePeriod }) => { const CollectionTable = ({ data, timePeriod }: { data: CollectionTableColumn[]; timePeriod: TimePeriod }) => {
const isNftGraphqlEnabled = useNftGraphqlEnabled()
const floorSort = useMemo(() => { const floorSort = useMemo(() => {
return (rowA: Row<CollectionTableColumn>, rowB: Row<CollectionTableColumn>) => { return (rowA: Row<CollectionTableColumn>, rowB: Row<CollectionTableColumn>) => {
if (isNftGraphqlEnabled) { return compareFloats(rowA.original.floor.value, rowB.original.floor.value)
return compareFloats(rowA.original.floor.value, rowB.original.floor.value)
} else {
const aFloor = BigNumber.from(rowA.original.floor.value ?? 0)
const bFloor = BigNumber.from(rowB.original.floor.value ?? 0)
return aFloor.gte(bFloor) ? 1 : -1
}
} }
}, [isNftGraphqlEnabled]) }, [])
const floorChangeSort = useMemo(() => { const floorChangeSort = useMemo(() => {
return (rowA: Row<CollectionTableColumn>, rowB: Row<CollectionTableColumn>) => { return (rowA: Row<CollectionTableColumn>, rowB: Row<CollectionTableColumn>) => {
......
import { OpacityHoverState } from 'components/Common' import { OpacityHoverState } from 'components/Common'
import { useNftGraphqlEnabled } from 'featureFlags/flags/nftlGraphql'
import { HistoryDuration } from 'graphql/data/__generated__/types-and-hooks' import { HistoryDuration } from 'graphql/data/__generated__/types-and-hooks'
import { useTrendingCollections } from 'graphql/data/nft/TrendingCollections' import { useTrendingCollections } from 'graphql/data/nft/TrendingCollections'
import ms from 'ms.macro' import ms from 'ms.macro'
...@@ -10,7 +9,6 @@ import { useQuery } from 'react-query' ...@@ -10,7 +9,6 @@ import { useQuery } from 'react-query'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { ThemedText } from 'theme' import { ThemedText } from 'theme'
import { fetchTrendingCollections } from '../../queries'
import CollectionTable from './CollectionTable' import CollectionTable from './CollectionTable'
const timeOptions: { label: string; value: TimePeriod }[] = [ const timeOptions: { label: string; value: TimePeriod }[] = [
...@@ -90,22 +88,11 @@ function convertTimePeriodToHistoryDuration(timePeriod: TimePeriod): HistoryDura ...@@ -90,22 +88,11 @@ function convertTimePeriodToHistoryDuration(timePeriod: TimePeriod): HistoryDura
const TrendingCollections = () => { const TrendingCollections = () => {
const [timePeriod, setTimePeriod] = useState<TimePeriod>(TimePeriod.OneDay) const [timePeriod, setTimePeriod] = useState<TimePeriod>(TimePeriod.OneDay)
const [isEthToggled, setEthToggled] = useState(true) const [isEthToggled, setEthToggled] = useState(true)
const isNftGraphqlEnabled = useNftGraphqlEnabled()
const { isSuccess, data } = useQuery(
['trendingCollections', timePeriod],
() => {
return fetchTrendingCollections({ volumeType: 'eth', timePeriod, size: 100 })
},
{
refetchOnReconnect: false,
refetchOnWindowFocus: false,
refetchOnMount: false,
refetchInterval: 5000,
}
)
const { data: gqlData, loading } = useTrendingCollections(100, convertTimePeriodToHistoryDuration(timePeriod)) const { data: trendingCollections, loading: trendingCollectionsAreLoading } = useTrendingCollections(
100,
convertTimePeriodToHistoryDuration(timePeriod)
)
const { data: usdPrice } = useQuery(['fetchPrice', {}], () => fetchPrice(), { const { data: usdPrice } = useQuery(['fetchPrice', {}], () => fetchPrice(), {
refetchOnReconnect: false, refetchOnReconnect: false,
...@@ -114,11 +101,9 @@ const TrendingCollections = () => { ...@@ -114,11 +101,9 @@ const TrendingCollections = () => {
refetchInterval: ms`1m`, refetchInterval: ms`1m`,
}) })
const trendingCollections = useMemo(() => { const trendingCollectionColumns = useMemo(() => {
const gatedData = isNftGraphqlEnabled ? gqlData : data if (!trendingCollectionsAreLoading && trendingCollections) {
const dataLoaded = isNftGraphqlEnabled ? !loading : isSuccess return trendingCollections.map((d) => ({
if (dataLoaded && gatedData) {
return gatedData.map((d) => ({
...d, ...d,
collection: { collection: {
name: d.name, name: d.name,
...@@ -144,7 +129,7 @@ const TrendingCollections = () => { ...@@ -144,7 +129,7 @@ const TrendingCollections = () => {
usdPrice, usdPrice,
})) }))
} else return [] as CollectionTableColumn[] } else return [] as CollectionTableColumn[]
}, [isNftGraphqlEnabled, gqlData, data, loading, isSuccess, isEthToggled, usdPrice]) }, [trendingCollections, trendingCollectionsAreLoading, isEthToggled, usdPrice])
return ( return (
<ExploreContainer> <ExploreContainer>
...@@ -178,7 +163,7 @@ const TrendingCollections = () => { ...@@ -178,7 +163,7 @@ const TrendingCollections = () => {
</Selector> </Selector>
</Filter> </Filter>
</FiltersRow> </FiltersRow>
<CollectionTable data={trendingCollections} timePeriod={timePeriod} /> <CollectionTable data={trendingCollectionColumns} timePeriod={timePeriod} />
</ExploreContainer> </ExploreContainer>
) )
} }
......
import { ActivityEventResponse, ActivityFilter } from '../../types'
export const ActivityFetcher = async (
contractAddress: string,
filters?: ActivityFilter,
cursor?: string,
limit?: string
): Promise<ActivityEventResponse> => {
const filterParam =
filters && filters.eventTypes
? `&event_types=${filters.eventTypes?.map((eventType) => `${eventType}`).join(',')}`
: ''
const tokenId = filters?.token_id ? `&token_id=${filters?.token_id}` : ''
const url = `${process.env.REACT_APP_TEMP_API_URL}/nft/collections/${contractAddress}/activity?limit=${
limit ? limit : '25'
}${filterParam}${cursor ? `&cursor=${cursor}` : ''}${tokenId}`
const r = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
})
const data = await r.json()
return data.data
}
import { isAddress } from '@ethersproject/address'
import { blocklistedCollections } from 'nft/utils'
import { GenieCollection } from '../../types'
const MAX_SEARCH_RESULTS = 6
const NFT_API_URL = process.env.REACT_APP_TEMP_API_URL
export const fetchSearchCollections = async (addressOrName: string, recursive = false): Promise<GenieCollection[]> => {
if (!NFT_API_URL) return Promise.resolve([])
const url = `${NFT_API_URL}/nft/searchCollections`
const isName = !isAddress(addressOrName.toLowerCase())
if (!isName && !recursive) {
try {
return await fetchSearchCollections(addressOrName.toLowerCase(), true)
} catch {
return []
}
}
const filters = isName
? {
$or: [{ name: { $regex: addressOrName, $options: 'i' } }],
}
: { address: addressOrName }
const payload = {
filters,
limit: 6,
fields: {
name: 1,
imageUrl: 1,
address: 1,
floorPrice: 1,
},
offset: 0,
}
const r = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
})
if (isName) {
const data = await r.json()
const formattedData = data?.data
? data.data
.filter((collection: { address: string }) => !blocklistedCollections.includes(collection.address))
.map((collection: { stats: Record<string, unknown>; floorPrice: string }) => {
return {
...collection,
stats: {
...collection.stats,
floor_price: collection.floorPrice,
},
}
})
: []
return formattedData.slice(0, MAX_SEARCH_RESULTS)
}
const data = await r.json()
return data.data ? [{ ...data.data[0], stats: { ...data.data[0].stats, floor_price: data.data[0].floorPrice } }] : []
}
import { blocklistedCollections } from 'nft/utils'
import { TimePeriod, TrendingCollection } from '../../types'
const NFT_API_URL = process.env.REACT_APP_TEMP_API_URL
export const fetchTrendingCollections = async (payload: {
volumeType: 'eth' | 'nft'
timePeriod: TimePeriod
size: number
}): Promise<TrendingCollection[]> => {
if (!NFT_API_URL) return Promise.resolve([])
const url = `${NFT_API_URL}/nft/collections/trending`
const r = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
})
const data = await r.json()
return data.filter((collection: { address: string }) => !blocklistedCollections.includes(collection.address)) ?? []
}
export * from './ActivityFetcher'
export * from './CollectionPreviewFetcher' export * from './CollectionPreviewFetcher'
export * from './RouteFetcher' export * from './RouteFetcher'
export * from './SearchCollectionsFetcher'
export * from './TrendingCollectionsFetcher'
import { BigNumber } from '@ethersproject/bignumber'
import { formatEther } from '@ethersproject/units'
import { parseEther } from 'ethers/lib/utils' import { parseEther } from 'ethers/lib/utils'
import { ActivityEvent, GenieAsset } from 'nft/types' import { ActivityEvent, GenieAsset } from 'nft/types'
import { formatEth } from './currency' import { formatEth } from './currency'
export const buildActivityAsset = ( export const buildActivityAsset = (event: ActivityEvent, collectionName: string, ethPriceInUSD: number): GenieAsset => {
event: ActivityEvent, const assetUsdPrice = event.price ? formatEth(parseFloat(event.price) * ethPriceInUSD) : '0'
collectionName: string,
ethPriceInUSD: number,
isNftGraphqlEnabled: boolean
): GenieAsset => {
const assetUsdPrice = event.price
? isNftGraphqlEnabled
? formatEth(parseFloat(event.price) * ethPriceInUSD)
: formatEther(
BigNumber.from(event.price)
.mul(BigNumber.from(Math.trunc(ethPriceInUSD * 100)))
.div(100)
)
: '0'
const weiPrice = isNftGraphqlEnabled ? (event.price ? parseEther(event.price) : '') : event.price const weiPrice = event.price ? parseEther(event.price) : ''
return { return {
address: event.collectionAddress, address: event.collectionAddress,
......
export const isValidDate = (date: number): boolean => { export const getTimeDifference = (eventTimestamp: string) => {
const d = Date.parse(date.toString()) const date = parseFloat(eventTimestamp)
return isNaN(d) ? false : true
}
export const getTimeDifference = (eventTimestamp: string, isNftGraphqlEnabled: boolean) => {
const date = isNftGraphqlEnabled ? parseFloat(eventTimestamp) : new Date(eventTimestamp).getTime()
const diff = new Date().getTime() - date const diff = new Date().getTime() - date
const days = Math.floor(diff / (1000 * 60 * 60 * 24)) const days = Math.floor(diff / (1000 * 60 * 60 * 24))
......
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