diff options
author | Eugene Sokolov <eug-vs@keemail.me> | 2020-08-16 23:52:59 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-16 23:52:59 +0300 |
commit | a2288ab4786d9886245df6c92b4fbbe5be0e7a5f (patch) | |
tree | 180722a3b885ebc0ba5411030a696bc7a0b75464 /src | |
parent | 1db77b9cc96ee8f7c014f383ae71da0d225a6d6a (diff) | |
parent | e5d067dcc433e7086845946946f632565b2d5e1c (diff) | |
download | which-ui-a2288ab4786d9886245df6c92b4fbbe5be0e7a5f.tar.gz |
Merge pull request #86 from which-ecosystem/pagination
PollsList gradual load (pseudo-pagination)
Diffstat (limited to 'src')
-rw-r--r-- | src/components/PollCard/PollCard.tsx | 2 | ||||
-rw-r--r-- | src/components/PollsList/PollsList.tsx | 64 | ||||
-rw-r--r-- | src/containers/Page/Page.tsx | 30 |
3 files changed, 66 insertions, 30 deletions
diff --git a/src/components/PollCard/PollCard.tsx b/src/components/PollCard/PollCard.tsx index 749c6b7..80a1386 100644 --- a/src/components/PollCard/PollCard.tsx +++ b/src/components/PollCard/PollCard.tsx @@ -94,7 +94,7 @@ const PollCard: React.FC<PropTypes> = React.memo(({ poll, setPoll }) => { const dominant: Which = left.votes >= right.votes ? 'left' : 'right'; return ( - <Card> + <Card elevation={3}> <UserStrip user={author} info={date} /> <div className={classes.media}> <CardActionArea onDoubleClick={handleLeft} className={classes.media}> diff --git a/src/components/PollsList/PollsList.tsx b/src/components/PollsList/PollsList.tsx index 41f9966..039639d 100644 --- a/src/components/PollsList/PollsList.tsx +++ b/src/components/PollsList/PollsList.tsx @@ -1,6 +1,13 @@ -import React, { useCallback } from 'react'; +import React, { useCallback, useState, useMemo } from 'react'; +import { + WindowScroller, + AutoSizer, + List, + InfiniteLoader +} from 'react-virtualized'; +import _ from 'lodash'; import { Poll } from 'which-types'; -import { WindowScroller, AutoSizer, List } from 'react-virtualized'; + import RenderItem from './RenderItem'; interface PropTypes { @@ -8,7 +15,11 @@ interface PropTypes { mutate: (polls: Poll[], refetch: boolean) => void; } +const PAGE_SIZE = 10; + const PollsList: React.FC<PropTypes> = ({ polls, mutate }) => { + const [displayCount, setDisplayCount] = useState<number>(PAGE_SIZE); + const rowRenderer = useCallback(({ index, style, key }) => ( <RenderItem polls={polls} @@ -20,6 +31,18 @@ const PollsList: React.FC<PropTypes> = ({ polls, mutate }) => { /> ), [polls, mutate]); + const loadMoreRows = useCallback(async () => { + setDisplayCount(previousCount => previousCount + PAGE_SIZE); + }, []); + + const isRowLoaded = useCallback(({ index }) => { + return index < displayCount - 1 || displayCount === polls.length; + }, [displayCount, polls]); + + const rowCount = useMemo(() => { + return _.min([displayCount, polls.length]) || polls.length; + }, [displayCount, polls.length]); + return ( <WindowScroller> {({ @@ -32,19 +55,30 @@ const PollsList: React.FC<PropTypes> = ({ polls, mutate }) => { <AutoSizer disableHeight> {({ width }) => ( <div ref={registerChild}> - <List - autoHeight - height={height} - isScrolling={isScrolling} - onScroll={onChildScroll} - rowCount={polls.length} - rowHeight={550} - rowRenderer={rowRenderer} - scrollTop={scrollTop} - width={width} - containerStyle={{ pointerEvents: 'auto' }} - overscanRowCount={2} - /> + <InfiniteLoader + isRowLoaded={isRowLoaded} + loadMoreRows={loadMoreRows} + rowCount={rowCount} + threshold={1} + > + {({ onRowsRendered, registerChild: ref }) => ( + <List + autoHeight + height={height} + isScrolling={isScrolling} + onScroll={onChildScroll} + rowCount={rowCount} + rowHeight={550} + rowRenderer={rowRenderer} + scrollTop={scrollTop} + width={width} + containerStyle={{ pointerEvents: 'auto' }} + overscanRowCount={2} + onRowsRendered={onRowsRendered} + ref={ref} + /> + )} + </InfiniteLoader> </div> )} </AutoSizer> diff --git a/src/containers/Page/Page.tsx b/src/containers/Page/Page.tsx index a1d6456..4aa48eb 100644 --- a/src/containers/Page/Page.tsx +++ b/src/containers/Page/Page.tsx @@ -22,6 +22,10 @@ const useStyles = makeStyles(theme => ({ } })); +const ErrorFallback: React.FC = () => ( + <EmptyState variant="error" message="Try reloading the page." /> +); + const Page: React.FC = () => { const classes = useStyles(); const theme = useTheme(); @@ -35,26 +39,24 @@ const Page: React.FC = () => { }, [history]); return ( - <ErrorBoundary - FallbackComponent={() => <EmptyState variant="error" message="Try reloading the page." />} + <SnackbarProvider + preventDuplicate + maxSnack={isMobile ? 1 : 3} + anchorOrigin={{ + vertical: 'top', + horizontal: 'right' + }} > - <SnackbarProvider - preventDuplicate - maxSnack={isMobile ? 1 : 3} - anchorOrigin={{ - vertical: 'top', - horizontal: 'right' - }} - > - <div className={classes.root}> + <div className={classes.root}> + <ErrorBoundary FallbackComponent={ErrorFallback}> <Suspense fallback={<Loading />}> <DynoWaiter> <Router /> </DynoWaiter> </Suspense> - </div> - </SnackbarProvider> - </ErrorBoundary> + </ErrorBoundary> + </div> + </SnackbarProvider> ); }; |