From 276d0eecd1979efde9e0f4fa6532aee1ee6ac8f7 Mon Sep 17 00:00:00 2001 From: NeOMakinG <14963751+NeOMakinG@users.noreply.github.com> Date: Mon, 21 Oct 2024 23:39:05 +0800 Subject: [PATCH] fix: infinite scroll not working if screen is very big on wallet (#7971) --- .../ProviderDetails/WalletLpByAsset.tsx | 4 ++- .../ProviderDetails/WalletStakingByAsset.tsx | 4 ++- src/components/MarketsTable.tsx | 4 ++- src/components/ReactTable/InfiniteTable.tsx | 31 +++++++++++++++++-- .../TransactionHistoryList.tsx | 5 ++- .../useInfiniteScroll/useInfiniteScroll.tsx | 31 +++++++++++++++++-- .../components/AccountList/AccountTable.tsx | 5 ++- 7 files changed, 74 insertions(+), 10 deletions(-) diff --git a/src/components/EarnDashboard/components/ProviderDetails/WalletLpByAsset.tsx b/src/components/EarnDashboard/components/ProviderDetails/WalletLpByAsset.tsx index ea871b468b8..f6ff537824b 100644 --- a/src/components/EarnDashboard/components/ProviderDetails/WalletLpByAsset.tsx +++ b/src/components/EarnDashboard/components/ProviderDetails/WalletLpByAsset.tsx @@ -54,7 +54,9 @@ export const WalletLpByAsset: React.FC = ({ opportunities [groupedItems], ) - const { next, data, hasMore } = useInfiniteScroll(flatItems) + const { next, data, hasMore } = useInfiniteScroll({ + array: flatItems, + }) const handleClick = useCallback( (opportunity: LpEarnOpportunityType, action: DefiAction) => { diff --git a/src/components/EarnDashboard/components/ProviderDetails/WalletStakingByAsset.tsx b/src/components/EarnDashboard/components/ProviderDetails/WalletStakingByAsset.tsx index 6379cde5447..231ff4e8f6c 100644 --- a/src/components/EarnDashboard/components/ProviderDetails/WalletStakingByAsset.tsx +++ b/src/components/EarnDashboard/components/ProviderDetails/WalletStakingByAsset.tsx @@ -56,7 +56,9 @@ export const WalletStakingByAsset: React.FC = ({ o () => groupedItems.flatMap(item => (Array.isArray(item) ? item.flat() : [item])), [groupedItems], ) - const { next, data, hasMore } = useInfiniteScroll(flatItems) + const { next, data, hasMore } = useInfiniteScroll({ + array: flatItems, + }) const handleClick = useCallback( (opportunity: StakingEarnOpportunityType, action: DefiAction) => { diff --git a/src/components/MarketsTable.tsx b/src/components/MarketsTable.tsx index 3abf18265b3..2ef9707a867 100644 --- a/src/components/MarketsTable.tsx +++ b/src/components/MarketsTable.tsx @@ -37,7 +37,9 @@ export const MarketsTable: React.FC = memo(({ rows, onRowClic const marketDataUserCurrencyById = useAppSelector(selectMarketDataUserCurrency) const isMarketDataLoaded = useAppSelector(selectIsMarketDataLoaded) - const { hasMore, next, data } = useInfiniteScroll(rows) + const { hasMore, next, data } = useInfiniteScroll({ + array: rows, + }) const handleTradeClick = useCallback( (e: React.MouseEvent) => { e.stopPropagation() diff --git a/src/components/ReactTable/InfiniteTable.tsx b/src/components/ReactTable/InfiniteTable.tsx index 77edaf46e4f..1b4fece2581 100644 --- a/src/components/ReactTable/InfiniteTable.tsx +++ b/src/components/ReactTable/InfiniteTable.tsx @@ -1,6 +1,7 @@ import { ArrowDownIcon, ArrowUpIcon } from '@chakra-ui/icons' import type { TableProps } from '@chakra-ui/react' import { + Button, Flex, Skeleton, Table, @@ -18,7 +19,6 @@ import InfiniteScroll from 'react-infinite-scroll-component' import { useTranslate } from 'react-polyglot' import type { Column, Row, TableState } from 'react-table' import { useExpanded, useSortBy, useTable } from 'react-table' -import { RawText } from 'components/Text' type ReactTableProps = { columns: Column[] @@ -39,8 +39,23 @@ type ReactTableProps = { const tdStyle = { padding: 0 } const tableSize = { base: 'sm', md: 'md' } +const SCROLL_TRESHOLD = 0.4 -const loader = Loading... +const Loader = () => { + const translate = useTranslate() + + return ( + + ) +} export const InfiniteTable = ({ columns, @@ -138,6 +153,8 @@ export const InfiniteTable = ({ visibleColumns.length, ]) + const loader = useMemo(() => , []) + return ( ({ dataLength={data.length} loader={loader} scrollableTarget={scrollableTarget} + hasChildren={true} + scrollThreshold={SCROLL_TRESHOLD} > - +
{displayHeaders && ( {headerGroups.map(headerGroup => ( diff --git a/src/components/TransactionHistory/TransactionHistoryList.tsx b/src/components/TransactionHistory/TransactionHistoryList.tsx index bace90515f6..11165a0f096 100644 --- a/src/components/TransactionHistory/TransactionHistoryList.tsx +++ b/src/components/TransactionHistory/TransactionHistoryList.tsx @@ -17,7 +17,10 @@ type TransactionHistoryListProps = { export const TransactionHistoryList: React.FC = memo( ({ txIds, useCompactMode = false, initialTxsCount }) => { - const { next, data, hasMore } = useInfiniteScroll(txIds, initialTxsCount) + const { next, data, hasMore } = useInfiniteScroll({ + array: txIds, + initialTxsCount, + }) const isAnyTxHistoryApiQueryPending = useAppSelector(selectIsAnyTxHistoryApiQueryPending) const translate = useTranslate() diff --git a/src/hooks/useInfiniteScroll/useInfiniteScroll.tsx b/src/hooks/useInfiniteScroll/useInfiniteScroll.tsx index 74c2a95c674..e38e494f160 100644 --- a/src/hooks/useInfiniteScroll/useInfiniteScroll.tsx +++ b/src/hooks/useInfiniteScroll/useInfiniteScroll.tsx @@ -1,8 +1,18 @@ -import { useCallback, useMemo, useState } from 'react' +import { useCallback, useEffect, useMemo, useState } from 'react' const defaultAmount = 20 -export const useInfiniteScroll = (array: T[], initialTxsCount?: number) => { +type UseInfiniteScrollProps = { + array: T[] + initialTxsCount?: number + isScrollable?: boolean +} + +export const useInfiniteScroll = ({ + array, + initialTxsCount, + isScrollable = false, +}: UseInfiniteScrollProps) => { const [amount, setAmount] = useState(initialTxsCount ?? defaultAmount) const next = useCallback(() => { @@ -12,6 +22,23 @@ export const useInfiniteScroll = (array: T[], initialTxsCount?: n const data = useMemo(() => array.slice(0, amount), [amount, array]) const hasMore = useMemo(() => array.length !== data.length, [data, array]) + useEffect(() => { + if (!isScrollable) return + + const firstLoaderItem = document.querySelector('.infinite-table tbody tr:last-of-type') + const scrollContainer = document.querySelector('html') + + if (!firstLoaderItem || !scrollContainer) { + return + } + if ( + // The loading will continue only when the loader element appears on the scroll-container. + firstLoaderItem.getBoundingClientRect().top < window.innerHeight + ) { + next() + } + }, [hasMore, isScrollable, next]) + return { next, data, diff --git a/src/pages/Dashboard/components/AccountList/AccountTable.tsx b/src/pages/Dashboard/components/AccountList/AccountTable.tsx index 3990dc13357..0f084c074aa 100644 --- a/src/pages/Dashboard/components/AccountList/AccountTable.tsx +++ b/src/pages/Dashboard/components/AccountList/AccountTable.tsx @@ -34,7 +34,10 @@ export const AccountTable = memo(() => { const sortedRows = useMemo(() => { return rowData.sort((a, b) => Number(b.fiatAmount) - Number(a.fiatAmount)) }, [rowData]) - const { hasMore, next, data } = useInfiniteScroll(sortedRows) + const { hasMore, next, data } = useInfiniteScroll({ + array: sortedRows, + isScrollable: true, + }) const textColor = useColorModeValue('black', 'white') const [isLargerThanMd] = useMediaQuery(`(min-width: ${breakpoints['md']})`, { ssr: false }) const history = useHistory()