aboutsummaryrefslogtreecommitdiff
path: root/src/components/PollsList/PollsList.tsx
blob: 039639dec2ea909cfdd3443847560a70f64d0686 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import React, { useCallback, useState, useMemo } from 'react';
import {
  WindowScroller,
  AutoSizer,
  List,
  InfiniteLoader
} from 'react-virtualized';
import _ from 'lodash';
import { Poll } from 'which-types';

import RenderItem from './RenderItem';

interface PropTypes {
  polls: Poll[];
  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}
      mutate={mutate}
      index={index}
      style={style}
      key={key}
      _key={key}
    />
  ), [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>
      {({
        height,
        isScrolling,
        registerChild,
        onChildScroll,
        scrollTop
      }) => (
        <AutoSizer disableHeight>
          {({ width }) => (
            <div ref={registerChild}>
              <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>
      )}
    </WindowScroller>
  );
};

export default PollsList;