Merge branch '99-ios-top-bar' into 'master'

Resolve "iOS top bar"

Closes #99

See merge request aretherecookies/ui-mobile!18
This commit is contained in:
Bart Akeley 2019-06-29 17:04:22 +00:00
commit 92ada00274
7 changed files with 61 additions and 145 deletions

View file

@ -1,98 +0,0 @@
// @flow
import React from 'react';
import { ActionButton } from 'react-native-material-ui';
import { compose, pure, withHandlers } from 'recompose';
import { withRouterContext, withViewMode, withPushRoute } from '../enhancers/routeEnhancers';
import queryString from 'query-string';
import { routeWithQuery } from '../helpers/RouteHelpers';
import { prop, head, length, map } from 'ramda';
type Props = {
actions: Array<'add-food' | 'filter-modal' | 'view-mode'>,
viewMode: string,
actionPressed: Function,
toggleFilterModal: ?Function,
pushRoute: Function,
router: Object,
addFoodItem: Function,
setViewMode: (mode: string) => void,
placeId?: string,
};
const actionDefs = {
'add-food': () => ({ icon: 'add', label: 'Add New', name: 'add-food' }),
'filter-modal': () => ({ icon: 'filter-list', label: 'Filter', name: 'filter-modal' }),
'view-mode': props =>
props.viewMode === 'map'
? { icon: 'list', label: 'View list', name: 'list-view' }
: { icon: 'map', label: 'View map', name: 'map-view' },
};
const ActionsButton = (props: Props) => {
const actions = map(action => actionDefs[action](props), props.actions || []);
const transition = length(actions) > 1 ? 'speedDial' : null;
const icon = length(actions) > 1 ? 'add' : prop('icon', head(actions));
return (
<ActionButton
actions={actions}
icon={icon}
transition={transition}
onPress={props.actionPressed}
onLongPress={props.actionPressed}
/>
);
};
export default compose(
pure,
withRouterContext,
withViewMode,
withPushRoute,
withHandlers({
addFoodItem: ({ pushRoute, placeId }: Props) => () => {
pushRoute(
routeWithQuery('/createFoodItem', {
routeTitle: 'Add a Food Item',
placeId,
})
);
},
setViewMode: ({ router }: Props) => (viewMode: string) => {
const history = router.history;
const search = router.route.location.search;
history.replace({
search: queryString.stringify({
search,
viewMode,
}),
});
},
}),
withHandlers({
actionPressed: (props: Props) =>
function handleActionPressed(action: ?String) {
switch (action) {
case 'add-food':
props.addFoodItem();
break;
case 'filter-modal':
props.toggleFilterModal && props.toggleFilterModal();
break;
case 'map-view':
case 'list-view':
case 'view-mode':
props.setViewMode(props.viewMode === 'map' ? 'list' : 'map');
break;
case 'main-button':
if (length(props.actions) === 1) {
handleActionPressed(head(props.actions));
}
break;
default:
break;
}
},
})
)(ActionsButton);

View file

@ -4,7 +4,7 @@ import { View, TextInput, TouchableOpacity, SafeAreaView } from 'react-native';
import { Toolbar, Icon } from 'react-native-material-ui';
import { path, pipe, not, cond, isNil, compose, always } from 'ramda';
import queryString from 'query-string';
import { getSearch } from '../helpers/RouteHelpers';
import { getSearch, getViewMode } from '../helpers/RouteHelpers';
import FoodItemSaveBtn from '../components/FoodItemSaveBtn';
import { withFilter } from '../enhancers/filterEnhancers';
import FilterRecord from '../records/FilterRecord';
@ -46,16 +46,15 @@ class TopToolbar extends Component {
goBackTo(router);
};
onRightPress = ({ action }: { action: string }) => {
const {
router: { history },
} = this.props;
toggleMapList = () => {
const history = path(['router', 'history'], this.props);
const search = getSearch(this.props);
const viewMode = getViewMode(this.props);
history.replace({
search: queryString.stringify({
...search,
viewMode: action,
viewMode: viewMode === 'list' ? 'map' : 'list',
}),
});
};
@ -83,6 +82,7 @@ class TopToolbar extends Component {
const route = path(['router', 'route', 'location', 'pathname'], this.props);
const routeSearch = getSearch(this.props);
const title = routeSearch.routeTitle || this.props.title;
const viewMode = getViewMode(this.props);
const showSearch = /^\/list/.test(route);
const showSearchClear = filter.search.length > 0;
@ -97,45 +97,60 @@ class TopToolbar extends Component {
onLeftElementPress={this.onBackPress}
centerElement={title}
rightElement={this.getRightElement()}
onRightElementPress={this.onRightPress}
/>
)}
{showSearch && (
<View
style={{
flexDirection: 'row',
alignItems: 'center',
margin: 10,
backgroundColor: 'white',
borderRadius: 10,
}}>
<Icon name="search" style={{ margin: 10 }} />
<TextInput
value={filter.search}
onChangeText={this.onChangeText}
placeholder={searchPlaceholder}
underlineColorAndroid="transparent"
<View style={{ flexDirection: 'row', padding: 10 }}>
<View
style={{
flex: 1,
fontSize: 18,
}}
/>
{showSearchClear ? (
<TouchableOpacity onPress={this.onSearchCleared}>
<Icon name="close" style={{ margin: 10 }} />
</TouchableOpacity>
) : (
<TouchableOpacity
onPress={onFilterPress}
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'white',
borderRadius: 10,
}}>
<Icon name="search" style={{ marginHorizontal: 10 }} />
<TextInput
value={filter.search}
onChangeText={this.onChangeText}
placeholder={searchPlaceholder}
underlineColorAndroid="transparent"
style={{
backgroundColor: '#E5E5E5',
borderRadius: 3,
marginHorizontal: 10,
padding: 7,
}}>
<FAIcon name="filter" style={{ fontSize: 22 }} />
</TouchableOpacity>
)}
flex: 1,
fontSize: 18,
padding: 5,
}}
/>
{showSearchClear ? (
<TouchableOpacity onPress={this.onSearchCleared}>
<Icon name="close" style={{ margin: 10 }} />
</TouchableOpacity>
) : (
<TouchableOpacity
onPress={onFilterPress}
style={{
backgroundColor: '#E5E5E5',
borderRadius: 3,
marginHorizontal: 10,
paddingVertical: 5,
paddingHorizontal: 8,
}}>
<FAIcon name="filter" style={{ fontSize: 22 }} />
</TouchableOpacity>
)}
</View>
<TouchableOpacity
onPress={this.toggleMapList}
style={{
padding: 8,
borderRadius: 10,
backgroundColor: 'rgba(255,255,255,0.2)',
marginLeft: 10,
alignItems: 'center',
justifyContent: 'center',
}}>
<Icon name={viewMode === 'map' ? 'view-list' : 'map'} size={22} color="white" />
</TouchableOpacity>
</View>
)}
</SafeAreaView>

View file

@ -2,7 +2,7 @@
import { getContext, withProps, compose } from 'recompose';
import { shape, func, string } from 'prop-types';
import { path } from 'ramda';
import { getSearch } from '../helpers/RouteHelpers';
import { getViewMode } from '../helpers/RouteHelpers';
export type routeMatch = {
isExact: boolean,
@ -48,7 +48,7 @@ export const withRouterContext = getContext({
export const withViewMode = withProps((props: Object) => {
return {
viewMode: getSearch(props).viewMode || 'list',
viewMode: getViewMode(props),
};
});

View file

@ -26,3 +26,8 @@ export const getSearch = pipe(
pathOr('', ['router', 'route', 'location', 'search']),
queryString.parse
);
export const getViewMode = pipe(
getSearch,
pathOr('list', ['viewMode'])
);

View file

@ -4,7 +4,6 @@ import { View, Text, TextInput, Button, TouchableOpacity } from 'react-native';
import { withHandlers, compose, withState, lifecycle } from 'recompose';
import { withRouterContext } from '../enhancers/routeEnhancers';
import AuthManager from '../AuthManager';
import queryString from 'query-string';
import theme from '../ui-theme';
import { Divider, Icon } from 'react-native-material-ui';

View file

@ -17,7 +17,6 @@ import { type List } from 'immutable';
import typeof FoodItemRecord from '../records/FoodItemRecord';
import FoodItemTile from '../components/FoodItemTile';
import { openUrl } from '../helpers/linkHelpers';
import ActionsButton from '../components/ActionsButton';
import { routeWithQuery } from '../helpers/RouteHelpers';
import { Link } from 'react-router-native';
@ -115,7 +114,6 @@ const PlaceDetail = (props: Props) => {
))}
</View>
</ScrollView>
<ActionsButton actions={['add-food']} placeId={place.id} />
</View>
);
};

View file

@ -11,7 +11,6 @@ import PlaceTile from '../components/PlaceTile';
import { withFoodItemsGroupedByPlace } from '../enhancers/foodItemEnhancers';
import { withRegionState } from '../enhancers/mapViewEnhancers';
import typeof PlaceRecord from '../records/PlaceRecord';
import ActionsButton from '../components/ActionsButton';
type Region = {
latitude: number,
@ -29,7 +28,6 @@ type Props = {
pushRoute: () => {},
};
// const PlacesMap = ({ places, region, onRegionChange, pushRoute }: Props) => {
const PlacesMap = ({
places = Map(),
foodItemsByPlace = Map(),
@ -72,7 +70,6 @@ const PlacesMap = ({
})
.toList()}
</MapView>
<ActionsButton actions={['view-mode']} />
</View>
);
};