mirror of
https://gitlab.com/wheres-the-tp/ui-mobile.git
synced 2026-01-25 07:24:56 -06:00
map view for food items
This commit is contained in:
parent
8c7c3e7344
commit
1753f4df6c
4 changed files with 124 additions and 60 deletions
12
js/enhancers/locationEnhancers.js
Normal file
12
js/enhancers/locationEnhancers.js
Normal 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,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
@ -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
39
js/pages/FoodList.js
Normal 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
68
js/pages/FoodMap.js
Normal 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);
|
||||||
Loading…
Add table
Reference in a new issue