parent
d9113fb6d4
commit
397b9d423e
@ -116,28 +116,15 @@ export default function TokenTable() {
|
||||
<GridContainer>
|
||||
<HeaderRow />
|
||||
<TokenDataContainer>
|
||||
{tokens.map((token, index) => {
|
||||
if (tokens.length === index + 1) {
|
||||
return (
|
||||
<LoadedRow
|
||||
key={token?.name}
|
||||
tokenListIndex={index}
|
||||
tokenListLength={tokens?.length ?? 0}
|
||||
token={token}
|
||||
ref={lastTokenRef}
|
||||
/>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<LoadedRow
|
||||
key={token?.name}
|
||||
tokenListIndex={index}
|
||||
tokenListLength={tokens?.length ?? 0}
|
||||
token={token}
|
||||
/>
|
||||
)
|
||||
}
|
||||
})}
|
||||
{tokens.map((token, index) => (
|
||||
<LoadedRow
|
||||
key={token?.name}
|
||||
tokenListIndex={index}
|
||||
tokenListLength={tokens?.length ?? 0}
|
||||
token={token}
|
||||
ref={tokens.length === index + 1 ? lastTokenRef : undefined}
|
||||
/>
|
||||
))}
|
||||
{loading && LoadingMoreRows}
|
||||
</TokenDataContainer>
|
||||
</GridContainer>
|
||||
|
@ -113,7 +113,6 @@ const tokenQuery = graphql`
|
||||
`
|
||||
|
||||
export function useTokenQuery(address: string, chain: Chain, timePeriod: TimePeriod) {
|
||||
//const cachedTopToken = cachedTopTokens[address]
|
||||
const data = useLazyLoadQuery<TokenQuery>(tokenQuery, {
|
||||
contract: { address, chain },
|
||||
duration: toHistoryDuration(timePeriod),
|
||||
|
@ -18,9 +18,8 @@ import { toHistoryDuration, useCurrentChainName } from './util'
|
||||
export function usePrefetchTopTokens() {
|
||||
const duration = toHistoryDuration(useAtomValue(filterTimeAtom))
|
||||
const chain = useCurrentChainName()
|
||||
|
||||
const top100 = useLazyLoadQuery<TopTokens100Query>(topTokens100Query, { duration, chain })
|
||||
return top100
|
||||
const args = useMemo(() => ({ chain, duration }), [chain, duration])
|
||||
return useLazyLoadQuery<TopTokens100Query>(topTokens100Query, args)
|
||||
}
|
||||
|
||||
const topTokens100Query = graphql`
|
||||
@ -131,59 +130,62 @@ function toContractInput(token: PrefetchedTopToken) {
|
||||
}
|
||||
|
||||
export type TopToken = NonNullable<TopTokens_TokensQuery['response']['tokens']>[number]
|
||||
export function useTopTokens(prefetchedData: TopTokens100Query['response']) {
|
||||
interface UseTopTokensReturnValue {
|
||||
loading: boolean
|
||||
tokens: TopToken[]
|
||||
loadMoreTokens: () => void
|
||||
}
|
||||
export function useTopTokens(prefetchedData: TopTokens100Query['response']): UseTopTokensReturnValue {
|
||||
const duration = toHistoryDuration(useAtomValue(filterTimeAtom))
|
||||
const environment = useRelayEnvironment()
|
||||
const [tokens, setTokens] = useState<TopToken[]>()
|
||||
const [tokens, setTokens] = useState<TopToken[]>([])
|
||||
|
||||
const [page, setPage] = useState(1)
|
||||
const prefetchedSelectedTokens = useFilteredTokens(useSortedTokens(prefetchedData.topTokens))
|
||||
const [page, setPage] = useState(0)
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
const appendTokens = useCallback(
|
||||
(newTokens: TopToken[]) => {
|
||||
setTokens(
|
||||
Object.values(
|
||||
tokens
|
||||
.concat(newTokens)
|
||||
.reduce((acc, token) => (token?.address ? { ...acc, [token.address]: token } : acc), {})
|
||||
)
|
||||
)
|
||||
},
|
||||
[tokens]
|
||||
)
|
||||
const loadMoreTokens = useCallback(() => setPage(page + 1), [page])
|
||||
|
||||
// TopTokens should ideally be fetched with usePaginationFragment. The backend does not current support graphql cursors;
|
||||
// in the meantime, fetchQuery is used, as other relay hooks do not allow the refreshing and lazy loading we need
|
||||
const loadTokens = useCallback(
|
||||
(contracts: ContractInput[], onSuccess: (data: TopTokens_TokensQuery['response'] | undefined) => void) => {
|
||||
fetchQuery<TopTokens_TokensQuery>(
|
||||
environment,
|
||||
tokensQuery,
|
||||
{ contracts, duration },
|
||||
{ fetchPolicy: 'store-or-network' }
|
||||
)
|
||||
.toPromise()
|
||||
.then(onSuccess)
|
||||
},
|
||||
[duration, environment]
|
||||
const prefetchedSelectedTokens = useFilteredTokens(useSortedTokens(prefetchedData.topTokens))
|
||||
const contracts: ContractInput[] = useMemo(
|
||||
() => prefetchedSelectedTokens.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE).map(toContractInput),
|
||||
[page, prefetchedSelectedTokens]
|
||||
)
|
||||
|
||||
const loadMoreTokens = useCallback(() => {
|
||||
setLoading(true)
|
||||
const contracts = prefetchedSelectedTokens.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE).map(toContractInput)
|
||||
loadTokens(contracts, (data) => {
|
||||
if (data?.tokens) {
|
||||
setTokens([...(tokens ?? []), ...data.tokens])
|
||||
setLoading(false)
|
||||
setPage(page + 1)
|
||||
}
|
||||
})
|
||||
}, [loadTokens, page, prefetchedSelectedTokens, tokens])
|
||||
|
||||
// Reset count when filters are changed
|
||||
useEffect(() => {
|
||||
setLoading(true)
|
||||
setTokens([])
|
||||
const contracts = prefetchedSelectedTokens.slice(0, PAGE_SIZE).map(toContractInput)
|
||||
loadTokens(contracts, (data) => {
|
||||
if (data?.tokens) {
|
||||
// @ts-ignore prevent typescript from complaining about readonly data
|
||||
setTokens(data.tokens)
|
||||
const subscription = fetchQuery<TopTokens_TokensQuery>(
|
||||
environment,
|
||||
tokensQuery,
|
||||
{ contracts, duration },
|
||||
{ fetchPolicy: 'store-or-network' }
|
||||
).subscribe({
|
||||
start() {
|
||||
setLoading(true)
|
||||
},
|
||||
complete() {
|
||||
setLoading(false)
|
||||
setPage(1)
|
||||
}
|
||||
},
|
||||
next(data) {
|
||||
appendTokens(data.tokens as TopToken[])
|
||||
},
|
||||
})
|
||||
}, [loadTokens, prefetchedSelectedTokens])
|
||||
return subscription.unsubscribe
|
||||
}, [appendTokens, contracts, duration, environment])
|
||||
|
||||
return { loading, tokens, loadMoreTokens }
|
||||
return { loading, tokens: useFilteredTokens(useSortedTokens(tokens)) as TopToken[], loadMoreTokens }
|
||||
}
|
||||
|
||||
export const tokensQuery = graphql`
|
||||
|
Loading…
Reference in New Issue
Block a user