index.tsx 4.59 KB
import { StackActions, useNavigation } from '@react-navigation/native';
import { get, isEmpty } from 'lodash/fp';
import { Spinner as NativeSpinner, View } from 'native-base';
import React, { useCallback, useEffect, useState } from 'react';
import {
  DataProvider,
  LayoutProvider,
  RecyclerListView
} from 'recyclerlistview';
import { TabNavigation } from '../../../types/navigation';
import ListGrid, { HeaderRow } from '../../ListGrid';
import HeaderColumn from '../../ListGrid/HeaderColumn';
import { CardHeight } from '../../player-card/constants';
import { COLUMNS, DEFAULT_SORT } from '../constants';
import Item from './Item';

interface Props {
  players: PlayerEdge[];
  franchisePlayers: Dictionary<FranchisePlayer>;
  onSort: (field: string, order: string) => void;
  onFetchMore: VoidFunction;
  isFetching: boolean;
}

const layoutProvider = new LayoutProvider(
  () => 'MARKET_LIST',
  (_, dim) => {
    // eslint-disable-next-line no-param-reassign
    dim.width = 500;
    // eslint-disable-next-line no-param-reassign
    dim.height = CardHeight + 1;
  }
);

const MainList: React.FC<Props> = ({
  isFetching,
  onFetchMore,
  franchisePlayers,
  onSort,
  players
}: Props) => {
  const navigation = useNavigation<TabNavigation>();
  const [sortBy, setSortBy] = useState<string>(DEFAULT_SORT.COLUMN);
  const [sortDirection, setSortDirection] = useState<SortType>(
    DEFAULT_SORT.DIRECTION
  );
  const [dataProvider, setDataProvider] = useState<DataProvider>(
    new DataProvider((r1, r2) => r1 !== r2)
  );

  useEffect(() => {
    if (sortBy && sortDirection) {
      onSort(sortBy, sortDirection);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [sortBy, sortDirection]);

  useEffect(() => {
    if (!isEmpty(players)) {
      setDataProvider(dataProvider.cloneWithRows(players));
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [players]);

  const handleOnSort = (colName: string) => () => {
    if (colName === sortBy) {
      setSortDirection(sortDirection === 'ASC' ? 'DESC' : 'ASC');
    } else {
      setSortBy(colName);
      setSortDirection('ASC');
    }
  };

  const getColumnSortDirection = (colName: string) =>
    colName === sortBy ? sortDirection : '';

  const renderFooter = useCallback(
    () => (isFetching ? <NativeSpinner /> : <View />),
    [isFetching]
  );

  const navigateToProfile = (selectedIndex: number) => () => {
    navigation.dispatch(
      StackActions.push('PlayerView', {
        players,
        selectedIndex,
        franchisePlayers
      })
    );
  };

  const renderRow = useCallback(
    (_, data: PlayerEdge, index: number) => {
      return (
        <Item
          data={data}
          activeSort={sortBy}
          isOwned={!isEmpty(get(data.node.id, franchisePlayers))}
          onPress={navigateToProfile(index)}
        />
      );
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [dataProvider]
  );

  const hasPlayerData = dataProvider.getSize() > 0;
  return (
    <ListGrid style={{ marginHorizontal: 6 }}>
      <HeaderRow style={{ height: 45, marginBottom: 20 }}>
        <HeaderColumn align="center" size={4} fontSize="sm" label="PLAYER" />
        <HeaderColumn
          sortable
          size={2}
          fontSize="sm"
          label="Rank"
          onSort={handleOnSort(COLUMNS.RANK)}
          sortDirection={getColumnSortDirection(COLUMNS.RANK)}
        />
        <HeaderColumn
          sortable
          size={2.5}
          fontSize="sm"
          label="FP"
          helpText="FANTASY PTS"
          onSort={handleOnSort(COLUMNS.FP)}
          sortDirection={getColumnSortDirection(COLUMNS.FP)}
        />
        <HeaderColumn
          sortable
          size={2.5}
          fontSize="sm"
          label="FPPG"
          helpText={'FANTASY PTS\n(per game)'}
          onSort={handleOnSort(COLUMNS.FPPG)}
          sortDirection={getColumnSortDirection(COLUMNS.FPPG)}
        />
        <HeaderColumn
          sortable
          size={2.3}
          fontSize="sm"
          label="Price"
          helpText={'TREND\n(24hrs)'}
          onSort={handleOnSort(COLUMNS.PRICE)}
          sortDirection={getColumnSortDirection(COLUMNS.PRICE)}
        />
      </HeaderRow>
      {hasPlayerData && (
        <RecyclerListView
          style={{ flex: 1 }}
          dataProvider={dataProvider}
          layoutProvider={layoutProvider}
          rowRenderer={renderRow}
          initialRenderIndex={0}
          renderAheadOffset={1500}
          renderFooter={renderFooter}
          onEndReached={onFetchMore}
          onEndReachedThreshold={2000}
        />
      )}
    </ListGrid>
  );
};

export default MainList;