aretherecookies-mobile/js/enhancers/foodItemEnhancers.js
2018-09-09 12:25:51 -05:00

90 lines
2.4 KiB
JavaScript

// @flow
import withProps from 'recompose/withProps';
import compose from 'recompose/compose';
import mapPropsStream from 'recompose/mapPropsStream';
import FoodItems$ from '../streams/FoodItemsStream';
import typeof FoodItemRecord from '../records/FoodItemRecord';
import { Map, Set } from 'immutable';
import { pipe, path, toLower, equals } from 'ramda';
type FindPredicate<A> = (left: A) => (right: A) => Boolean;
const getName: (f: FoodItemRecord) => String = pipe(
path(['name']),
toLower
);
const matchesName: FindPredicate<FoodItemRecord> = left => right => {
return equals(getName(left), getName(right));
};
const addIfNotExisting = (predicate: FindPredicate<FoodItemRecord>) => (
set: Set<FoodItemRecord>,
item: FoodItemRecord
) => {
return !set.find(predicate(item)) ? set.add(item) : set;
};
const intoSet = reducer => items => {
return items ? items.reduce(reducer, new Set()) : new Set();
};
export const withFoodItems = mapPropsStream(props$ =>
props$.combineLatest(FoodItems$, (props, foodItems) => {
return {
...props,
foodItemsMap: foodItems && foodItems,
};
})
);
export const withFoodItemsAsSeq = mapPropsStream(props$ =>
props$.combineLatest(FoodItems$, (props, foodItems) => {
return {
...props,
foodItemsSeq: foodItems && foodItems.valueSeq(),
};
})
);
export const withFoodItemIdFromRoute = withProps((props: { match: { params: { id: string } } }) => {
const id: string = path(['match', 'params', 'id'], props) || '';
return { foodItemId: id };
});
export const withFoodItem = compose(
withFoodItems,
withFoodItemIdFromRoute,
withProps((props: { foodItemsMap: ?Map<number, FoodItemRecord>, foodItemId: number }) => {
const { foodItemsMap, foodItemId } = props;
return { foodItem: foodItemsMap && foodItemsMap.get(foodItemId) };
})
);
export const withFoodItemPlaceId = withProps((props: { foodItem: FoodItemRecord }) => {
const { foodItem } = props;
return {
placeId: foodItem && foodItem.placeId,
};
});
export const withFoodItemsGroupedByPlace = compose(
withFoodItems,
withProps((props: { foodItemsMap: ?Map<number, FoodItemRecord> }) => {
if (!props.foodItemsMap) {
return {};
}
return {
foodItemsByPlace: props.foodItemsMap.groupBy(foodItem => foodItem.placeId),
};
})
);
export const withUniqueFoodItems = compose(
withFoodItemsAsSeq,
withProps(({ foodItemsSeq }) => {
return {
foodItemsSeq: intoSet(addIfNotExisting(matchesName))(foodItemsSeq),
};
})
);