map view for food items

This commit is contained in:
Bart Akeley 2017-09-03 19:41:52 -05:00
parent 8c7c3e7344
commit 1753f4df6c
4 changed files with 124 additions and 60 deletions

View file

@ -0,0 +1,12 @@
// @flow
import mapPropsStream from 'recompose/mapPropsStream';
import location$ from '../streams/LocationStream';
export const withLocation = mapPropsStream(props$ =>
props$.combineLatest(location$, (props, location) => {
return {
...props,
location,
};
})
);

View file

@ -1,64 +1,9 @@
// @flow // @flow
import React, { Component, PropTypes } from 'react'; import { shape, func, string } from 'prop-types';
import { View, ScrollView, Text } from 'react-native'; import { compose, branch, getContext, mapProps } from 'recompose';
import theme from '../ui-theme';
import FoodItemTile from '../components/FoodItemTile';
import { ActionButton } from 'react-native-material-ui';
import { routeWithTitle } from '../helpers/RouteHelpers';
import FoodItemList from '../components/FoodItemList';
import typeof FoodItemRecord from '../records/FoodItemRecord';
import { withPlaceForFoodItem } from '../enhancers/placeEnhancers';
import { withFoodItems } from '../enhancers/foodItemEnhancers';
import { compose, branch, getContext, mapProps, renderComponent } from 'recompose';
import { path } from 'ramda'; import { path } from 'ramda';
import { type Map } from 'immutable'; import FoodList from './FoodList';
import FoodMap from './FoodMap';
const { shape, func, string } = PropTypes;
const FoodItemWithPlace = withPlaceForFoodItem(FoodItemTile);
const renderFoodItem = (foodItem: FoodItemRecord) => <FoodItemWithPlace key={foodItem.id} foodItem={foodItem} />;
class FoodList extends Component {
static displayName = 'Food';
props: {
pushRoute: Object => void,
};
addFoodItem = () => {
const newRoute = routeWithTitle('/createFoodItem', 'Add a Food Item');
this.props.pushRoute(newRoute);
};
render() {
return (
<View style={theme.page.container}>
<ScrollView>
<FoodItemList renderFoodItem={renderFoodItem} />
</ScrollView>
<ActionButton icon="add" onPress={this.addFoodItem} />
</View>
);
}
}
const FoodMap = ({ foodItemsMap }: { foodItemsMap: Map<string, FoodItemRecord> }) => {
return (
<View>
<Text>Hey, a map should go here!</Text>
{foodItemsMap
.map((foodItem, id) =>
<Text key={id}>
{foodItem.latitude}, {foodItem.longitude}
</Text>
)
.toList()}
</View>
);
};
const FoodMapComp = compose(renderComponent, withFoodItems)(FoodMap);
export default compose( export default compose(
getContext({ getContext({
@ -83,5 +28,5 @@ export default compose(
}), }),
branch(({ viewMode }) => { branch(({ viewMode }) => {
return viewMode === 'map'; return viewMode === 'map';
}, FoodMapComp) }, FoodMap)
)(FoodList); )(FoodList);

39
js/pages/FoodList.js Normal file
View file

@ -0,0 +1,39 @@
// @flow
import React, { Component } from 'react';
import { View, ScrollView } from 'react-native';
import FoodItemTile from '../components/FoodItemTile';
import { ActionButton } from 'react-native-material-ui';
import { routeWithTitle } from '../helpers/RouteHelpers';
import FoodItemList from '../components/FoodItemList';
import typeof FoodItemRecord from '../records/FoodItemRecord';
import { withPlaceForFoodItem } from '../enhancers/placeEnhancers';
import theme from '../ui-theme';
const FoodItemWithPlace = withPlaceForFoodItem(FoodItemTile);
const renderFoodItem = (foodItem: FoodItemRecord) => <FoodItemWithPlace key={foodItem.id} foodItem={foodItem} />;
export default class FoodList extends Component {
static displayName = 'FoodList';
props: {
pushRoute: Object => void,
};
addFoodItem = () => {
const newRoute = routeWithTitle('/createFoodItem', 'Add a Food Item');
this.props.pushRoute(newRoute);
};
render() {
return (
<View style={theme.page.container}>
<ScrollView>
<FoodItemList renderFoodItem={renderFoodItem} />
</ScrollView>
<ActionButton icon="add" onPress={this.addFoodItem} />
</View>
);
}
}

68
js/pages/FoodMap.js Normal file
View file

@ -0,0 +1,68 @@
// @flow
import React from 'react';
import typeof FoodItemRecord from '../records/FoodItemRecord';
import { withFoodItems } from '../enhancers/foodItemEnhancers';
import { withLocation } from '../enhancers/locationEnhancers';
import { compose, renderComponent, withState } from 'recompose';
import { type Map } from 'immutable';
import MapView from 'react-native-maps';
import { path } from 'ramda';
import { getQuantityText } from '../helpers/QuantityHelpers';
// import theme from '../ui-theme';
type Region = {
latitude: number,
longitude: number,
latitudeDelta: number,
longitudeDelta: number,
};
type Props = {
foodItemsMap: Map<string, FoodItemRecord>,
location: Location,
region: Region,
onRegionChange: Region => void,
};
const FoodMap = ({ foodItemsMap, region, onRegionChange }: Props) => {
return (
<MapView
initialRegion={region}
region={region}
style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }}
onRegionChange={onRegionChange}
>
{foodItemsMap
.map((foodItem, id) => (
<MapView.Marker
key={id}
title={foodItem.name}
coordinate={{
latitude: foodItem.latitude,
longitude: foodItem.longitude,
}}
description={getQuantityText(foodItem.quantity)}
onPress={() => {
// todo - should we navigate the user to place or food item detail screen?
}}
/>
))
.toList()}
</MapView>
);
};
export default compose(
renderComponent,
withFoodItems,
withLocation,
withState('region', 'onRegionChange', ({ location }) => {
return {
latitude: path(['coords', 'latitude'], location),
longitude: path(['coords', 'longitude'], location),
latitudeDelta: 0.07,
longitudeDelta: 0.07,
};
})
)(FoodMap);