aretherecookies-mobile/js/components/FoodItemList.js

59 lines
1.6 KiB
JavaScript

// @flow
import React, { Component } from 'react';
import { View } from 'react-native';
import { type SetSeq } from 'immutable';
import FoodItemRecord from '../records/FoodItemRecord';
import { pure } from 'recompose';
import R from 'ramda';
const matchString = R.memoize((match = '', str = '') =>
str.toLowerCase().includes(match.toLowerCase())
);
const filterBy = (filter?: string = '') => (foodItemsSeq: SetSeq<FoodItemRecord>) => {
if (!filter) {
return foodItemsSeq;
}
return foodItemsSeq.filter(foodItem => matchString(filter, foodItem.name));
};
const limitBy = (limit?: number) => (foodItemsSeq: SetSeq<FoodItemRecord>) => {
if (!limit) {
return foodItemsSeq;
}
return foodItemsSeq.take(limit);
};
const sortByDistance = (foodItemsSeq: SetSeq<FoodItemRecord>) => {
return foodItemsSeq.sort((left, right) => left.distance - right.distance);
};
const intoArray = (foodItemsSeq: SetSeq<FoodItemRecord>) =>
foodItemsSeq ? foodItemsSeq.toArray() : [];
class FoodItemList extends Component {
static displayName = 'FoodItemList';
props: {
filter: string,
limit?: number,
foodItemsSeq: SetSeq<FoodItemRecord>,
renderFoodItem: (foodItem: typeof FoodItemRecord) => Component<*, *, *>,
foodItemsLoading: boolean,
};
render() {
const { filter, foodItemsSeq, renderFoodItem, limit } = this.props;
if (!foodItemsSeq) {
return null;
}
const getItems = R.compose(intoArray, limitBy(limit), sortByDistance, filterBy(filter));
const items = getItems(foodItemsSeq);
return <View style={{ flexShrink: 2 }}>{items.map(renderFoodItem)}</View>;
}
}
export default pure(FoodItemList);