aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEugene Sokolov <eug-vs@keemail.me>2020-08-16 23:52:59 +0300
committerGitHub <noreply@github.com>2020-08-16 23:52:59 +0300
commita2288ab4786d9886245df6c92b4fbbe5be0e7a5f (patch)
tree180722a3b885ebc0ba5411030a696bc7a0b75464 /src
parent1db77b9cc96ee8f7c014f383ae71da0d225a6d6a (diff)
parente5d067dcc433e7086845946946f632565b2d5e1c (diff)
downloadwhich-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.tsx2
-rw-r--r--src/components/PollsList/PollsList.tsx64
-rw-r--r--src/containers/Page/Page.tsx30
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>
);
};