Skip to content

Commit

Permalink
feat: ITO lazy load history list (#3524)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhouhanseng authored Jun 30, 2021
1 parent 07dbc5e commit 119ee53
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 16 deletions.
7 changes: 2 additions & 5 deletions packages/maskbook/src/plugins/ITO/UI/PoolInList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { useI18N } from '../../../utils'
import { MSG_DELIMITER } from '../constants'
import { useAvailabilityComputed } from '../hooks/useAvailabilityComputed'
import { usePoolTradeInfo } from '../hooks/usePoolTradeInfo'
import { ITO_Status, JSON_PayloadInMask } from '../types'
import { ITO_Status, JSON_PayloadInMask, PoolSubgraph } from '../types'
import { useDestructCallback } from '../hooks/useDestructCallback'
import { useTransactionDialog } from '../../../web3/hooks/useTransactionDialog'

Expand Down Expand Up @@ -107,10 +107,7 @@ const useStyles = makeStyles((theme) => ({
},
}))

export interface PoolInListProps {
pool: JSON_PayloadInMask
exchange_in_volumes: string[]
exchange_out_volumes: string[]
export interface PoolInListProps extends PoolSubgraph {
onSend?: (pool: JSON_PayloadInMask) => void
onRetry: () => void
}
Expand Down
14 changes: 11 additions & 3 deletions packages/maskbook/src/plugins/ITO/UI/PoolList.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { useAccount } from '@masknet/web3-shared'
import { Box, CircularProgress, makeStyles, Typography } from '@material-ui/core'
import { useAllPoolsAsSeller } from '../hooks/useAllPoolsAsSeller'
import { useScrollBottomEvent } from '@masknet/shared'
import type { JSON_PayloadInMask } from '../types'
import { PoolInList } from './PoolInList'
import { useRef, useState, useCallback } from 'react'

const useStyles = makeStyles((theme) => ({
root: {
Expand All @@ -28,11 +30,16 @@ export interface PoolListProps {
export function PoolList(props: PoolListProps) {
const classes = useStyles()
const account = useAccount()
const { value: pools = [], loading, retry } = useAllPoolsAsSeller(account)
const [page, setPage] = useState(0)
const { value: pools = [], loading, retry } = useAllPoolsAsSeller(account, page)

const containerRef = useRef<HTMLDivElement>(null)
const addPage = useCallback(() => setPage(page + 1), [page])
useScrollBottomEvent(containerRef, addPage)

return (
<div className={classes.root}>
{loading ? (
<div className={classes.root} ref={containerRef}>
{loading && page === 0 ? (
<Box className={classes.content}>
<CircularProgress />
</Box>
Expand All @@ -45,6 +52,7 @@ export function PoolList(props: PoolListProps) {
{pools.map((x) => (
<PoolInList key={x.pool.pid} {...x} onSend={props.onSend} onRetry={retry} />
))}
{loading && page > 0 ? <CircularProgress /> : null}
</div>
)}
</div>
Expand Down
6 changes: 4 additions & 2 deletions packages/maskbook/src/plugins/ITO/apis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,16 @@ export async function getPool(pid: string) {
return payloadIntoMask(data.pool)
}

export async function getAllPoolsAsSeller(address: string) {
export async function getAllPoolsAsSeller(address: string, page: number) {
const response = await fetch(getITOConstants(currentChainIdSettings.value).SUBGRAPH_URL, {
method: 'POST',
mode: 'cors',
body: stringify({
query: `
{
sellInfos (where: { seller: "${address.toLowerCase()}" }) {
sellInfos ( orderBy: timestamp, orderDirection: desc, first: 50, skip: ${
page * 50
}, where: { seller: "${address.toLowerCase()}" }) {
pool {
${POOL_FIELDS}
exchange_in_volumes
Expand Down
12 changes: 8 additions & 4 deletions packages/maskbook/src/plugins/ITO/hooks/useAllPoolsAsSeller.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { useAsyncRetry } from 'react-use'
import { PluginITO_RPC } from '../messages'
import type { PoolSubgraph } from '../types'
import { useRef } from 'react'

export function useAllPoolsAsSeller(address: string) {
export function useAllPoolsAsSeller(address: string, page: number) {
const allPoolsRef = useRef<PoolSubgraph[]>([])
return useAsyncRetry(async () => {
const pools = await PluginITO_RPC.getAllPoolsAsSeller(address)
return pools.reverse()
}, [address])
const pools = await PluginITO_RPC.getAllPoolsAsSeller(address, page)
allPoolsRef.current = allPoolsRef.current.concat(pools)
return allPoolsRef.current
}, [address, page])
}
4 changes: 2 additions & 2 deletions packages/maskbook/src/plugins/ITO/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ export async function getPool(pid: string) {
return poolFromChain
}

export async function getAllPoolsAsSeller(address: string) {
export async function getAllPoolsAsSeller(address: string, page: number) {
const chainId = currentChainIdSettings.value
const poolsFromChain = await subgraph.getAllPoolsAsSeller(address)
const poolsFromChain = await subgraph.getAllPoolsAsSeller(address, page)
const poolsFromDB = await database.getPoolsFromDB(poolsFromChain.map((x) => x.pool.pid))
return poolsFromChain
.map((x) => {
Expand Down
6 changes: 6 additions & 0 deletions packages/maskbook/src/plugins/ITO/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ export interface JSON_PayloadInMask {
test_nums?: number[]
}

export interface PoolSubgraph {
pool: JSON_PayloadInMask
exchange_in_volumes: string[]
exchange_out_volumes: string[]
}

//#region TokenOutMask
export type TokenOutMask = Omit<NativeTokenDetailed | ERC20TokenDetailed, 'chainId'> & {
chain_id: ChainId
Expand Down
1 change: 1 addition & 0 deletions packages/shared/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './useValueRef'
export * from './useObservableMapSet'
export * from './useMenu'
export * from './useScrollBottomEvent'
23 changes: 23 additions & 0 deletions packages/shared/src/hooks/useScrollBottomEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useLayoutEffect, RefObject, useCallback } from 'react'
import { debounce } from 'lodash-es'

export function useScrollBottomEvent(ref: RefObject<HTMLDivElement>, cb: () => void) {
const onScroll = useCallback(
debounce(function (_ev: Event) {
// ev.currentTarget is always null when applies debounce().
const ev = _ev as Event & { path: HTMLDivElement[] }
const element = ev.path[0]
// On some device, there's a slight deviation between `scrollHeight` and `offsetHeight + scrollTop`
const isBottomArrived = Math.abs(element.scrollHeight - element.offsetHeight - element.scrollTop) < 2
if (isBottomArrived) cb()
}, 300),
[cb],
)

useLayoutEffect(() => {
if (!ref.current) return
ref.current.addEventListener('scroll', onScroll)
// useLayoutEffect() to remove the listener before changes painted on screen.
return () => ref.current!.removeEventListener('scroll', onScroll)
}, [onScroll])
}

0 comments on commit 119ee53

Please sign in to comment.