Commit 27768300 authored by Max Alekseenko's avatar Max Alekseenko

dapps lazy loading

parent b7597493
...@@ -5,12 +5,12 @@ import { useInView } from 'react-intersection-observer'; ...@@ -5,12 +5,12 @@ import { useInView } from 'react-intersection-observer';
const STEP = 10; const STEP = 10;
const MIN_ITEMS_NUM = 50; const MIN_ITEMS_NUM = 50;
export default function useLazyRenderedList(list: Array<unknown>, isEnabled: boolean) { export default function useLazyRenderedList(list: Array<unknown>, isEnabled: boolean, minItemsNum: number = MIN_ITEMS_NUM) {
const [ renderedItemsNum, setRenderedItemsNum ] = React.useState(MIN_ITEMS_NUM); const [ renderedItemsNum, setRenderedItemsNum ] = React.useState(minItemsNum);
const { ref, inView } = useInView({ const { ref, inView } = useInView({
rootMargin: '200px', rootMargin: '200px',
triggerOnce: false, triggerOnce: false,
skip: !isEnabled || list.length <= MIN_ITEMS_NUM, skip: !isEnabled || list.length <= minItemsNum,
}); });
React.useEffect(() => { React.useEffect(() => {
......
import { Grid } from '@chakra-ui/react'; import { Grid, Box } from '@chakra-ui/react';
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import type { MouseEvent } from 'react'; import type { MouseEvent } from 'react';
import type { MarketplaceAppWithSecurityReport, ContractListTypes, AppRating } from 'types/client/marketplace'; import type { MarketplaceAppWithSecurityReport, ContractListTypes, AppRating } from 'types/client/marketplace';
import useLazyRenderedList from 'lib/hooks/useLazyRenderedList';
import * as mixpanel from 'lib/mixpanel/index'; import * as mixpanel from 'lib/mixpanel/index';
import EmptySearchResult from './EmptySearchResult'; import EmptySearchResult from './EmptySearchResult';
...@@ -30,6 +31,8 @@ const MarketplaceList = ({ ...@@ -30,6 +31,8 @@ const MarketplaceList = ({
apps, showAppInfo, favoriteApps, onFavoriteClick, isLoading, selectedCategoryId, apps, showAppInfo, favoriteApps, onFavoriteClick, isLoading, selectedCategoryId,
onAppClick, showContractList, userRatings, rateApp, isSendingRating, isRatingLoading, canRate, onAppClick, showContractList, userRatings, rateApp, isSendingRating, isRatingLoading, canRate,
}: Props) => { }: Props) => {
const { cutRef, renderedItemsNum } = useLazyRenderedList(apps, !isLoading, 16);
const handleInfoClick = useCallback((id: string) => { const handleInfoClick = useCallback((id: string) => {
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'More button', Info: id, Source: 'Discovery view' }); mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, { Type: 'More button', Info: id, Source: 'Discovery view' });
showAppInfo(id); showAppInfo(id);
...@@ -40,42 +43,45 @@ const MarketplaceList = ({ ...@@ -40,42 +43,45 @@ const MarketplaceList = ({
}, [ onFavoriteClick ]); }, [ onFavoriteClick ]);
return apps.length > 0 ? ( return apps.length > 0 ? (
<Grid <>
templateColumns={{ <Grid
md: 'repeat(auto-fill, minmax(230px, 1fr))', templateColumns={{
lg: 'repeat(auto-fill, minmax(260px, 1fr))', md: 'repeat(auto-fill, minmax(230px, 1fr))',
}} lg: 'repeat(auto-fill, minmax(260px, 1fr))',
autoRows="1fr" }}
gap={{ base: '16px', md: '24px' }} autoRows="1fr"
> gap={{ base: '16px', md: '24px' }}
{ apps.map((app, index) => ( >
<MarketplaceAppCard { apps.slice(0, renderedItemsNum).map((app, index) => (
key={ app.id + (isLoading ? index : '') } <MarketplaceAppCard
onInfoClick={ handleInfoClick } key={ app.id + (isLoading ? index : '') }
id={ app.id } onInfoClick={ handleInfoClick }
external={ app.external } id={ app.id }
url={ app.url } external={ app.external }
title={ app.title } url={ app.url }
logo={ app.logo } title={ app.title }
logoDarkMode={ app.logoDarkMode } logo={ app.logo }
shortDescription={ app.shortDescription } logoDarkMode={ app.logoDarkMode }
categories={ app.categories } shortDescription={ app.shortDescription }
isFavorite={ favoriteApps.includes(app.id) } categories={ app.categories }
onFavoriteClick={ handleFavoriteClick } isFavorite={ favoriteApps.includes(app.id) }
isLoading={ isLoading } onFavoriteClick={ handleFavoriteClick }
internalWallet={ app.internalWallet } isLoading={ isLoading }
onAppClick={ onAppClick } internalWallet={ app.internalWallet }
securityReport={ app.securityReport } onAppClick={ onAppClick }
showContractList={ showContractList } securityReport={ app.securityReport }
rating={ app.rating } showContractList={ showContractList }
userRating={ userRatings[app.id] } rating={ app.rating }
rateApp={ rateApp } userRating={ userRatings[app.id] }
isSendingRating={ isSendingRating } rateApp={ rateApp }
isRatingLoading={ isRatingLoading } isSendingRating={ isSendingRating }
canRate={ canRate } isRatingLoading={ isRatingLoading }
/> canRate={ canRate }
)) } />
</Grid> )) }
</Grid>
<Box ref={ cutRef } h={ 0 }/>
</>
) : ( ) : (
<EmptySearchResult selectedCategoryId={ selectedCategoryId } favoriteApps={ favoriteApps }/> <EmptySearchResult selectedCategoryId={ selectedCategoryId } favoriteApps={ favoriteApps }/>
); );
......
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