diff --git a/js/components/ImagePicker.js b/js/components/ImagePicker.js
index 9bbfe1e..fc5f3af 100644
--- a/js/components/ImagePicker.js
+++ b/js/components/ImagePicker.js
@@ -4,6 +4,7 @@ import { Text, View, TouchableOpacity, Image } from 'react-native';
import { Icon } from 'react-native-material-ui';
import uiTheme from '../ui-theme.js';
import ReactNativeImagePicker from 'react-native-image-picker';
+import { type List } from 'immutable';
const { palette: { accentColor } } = uiTheme;
@@ -19,12 +20,12 @@ export const ImageThumb = ({ uri, onPress }: { uri?: string, onPress: () => void
;
-export const ImagePicker = ({ children, onCreateNew }: { children?: any, onCreateNew: Function }) =>
+export const ImagePicker = ({ children, onCreateNew }: { children?: List, onCreateNew: Function }) =>
- {(!children || !children.length) &&
+ {(!children || !children.size) &&
Add Images
}
diff --git a/js/modals/ImagePreviewModal.js b/js/modals/ImagePreviewModal.js
new file mode 100644
index 0000000..2e234db
--- /dev/null
+++ b/js/modals/ImagePreviewModal.js
@@ -0,0 +1,38 @@
+// @flow
+import React from 'react';
+import { TouchableOpacity, Image } from 'react-native';
+import { ActionButton } from 'react-native-material-ui';
+
+const backdropStyle = {
+ position: 'absolute',
+ top: 0,
+ bottom: 0,
+ left: 0,
+ right: 0,
+ backgroundColor: 'black',
+ flexDirection: 'column',
+ justifyContent: 'center',
+};
+
+const imageStyle = {
+ flex: 2,
+ resizeMode: 'contain',
+};
+
+type Props = {
+ onClose: () => void,
+ onDelete: () => void,
+ imageSrc: string,
+};
+
+const ImagePreviewModal = ({ onClose, onDelete, imageSrc }: Props) => {
+ return (
+
+
+
+
+ );
+};
+ImagePreviewModal.displayName = 'ImagePreviewModal';
+
+export default ImagePreviewModal;
diff --git a/js/pages/CreateFoodItem.js b/js/pages/CreateFoodItem.js
index ccbfe45..5bc269b 100644
--- a/js/pages/CreateFoodItem.js
+++ b/js/pages/CreateFoodItem.js
@@ -6,6 +6,7 @@ import { Divider } from 'react-native-material-ui';
import FoodItemRecord from '../records/FoodItemRecord';
import PlaceRecord from '../records/PlaceRecord';
import NameModal from '../modals/FoodItemNameModal';
+import ImagePreviewModal from '../modals/ImagePreviewModal';
import QuantityPicker from '../components/QuantityPicker';
import { compose, branch, withState, withHandlers, renderComponent, mapProps } from 'recompose';
import RNGooglePlaces from 'react-native-google-places';
@@ -52,12 +53,12 @@ type Props = {
setModalsVisible: Function,
place: typeof PlaceRecord,
setPlace: (place: typeof PlaceRecord) => void,
- removeImageAtIndex: (i: number) => () => void,
updatePlace: (place: GooglePlaceObject) => void,
addImage: (uri: string) => void,
+ setImagePreview: (index?: number) => void,
};
const CreateFoodItem = (props: Props) => {
- const { foodItem, toggleNameModal, setPropOfFoodItem, place, updatePlace, removeImageAtIndex, addImage } = props;
+ const { foodItem, toggleNameModal, setPropOfFoodItem, place, updatePlace, addImage, setImagePreview } = props;
return (
@@ -77,14 +78,14 @@ const CreateFoodItem = (props: Props) => {
{foodItem.images.map((image, index) =>
-
+ setImagePreview(index)} />
)}
);
};
-const enhanceNameModal = compose(
+const NameModalComp = compose(
renderComponent,
mapProps(({ toggleNameModal, setPropOfFoodItem }: Props) => {
return {
@@ -92,57 +93,73 @@ const enhanceNameModal = compose(
onUpdate: setPropOfFoodItem('name'),
};
})
-);
+)(NameModal);
+
+const ImagePreviewComp = compose(
+ renderComponent,
+ mapProps(({ foodItem, setFoodItem, setImagePreview, imagePreview }) => {
+ return {
+ onClose: () => setImagePreview(-1),
+ onDelete: () => {
+ setFoodItem(foodItem.deleteIn(['images', imagePreview]));
+ setImagePreview(-1);
+ },
+ imageSrc: foodItem.images.get(imagePreview),
+ };
+ })
+)(ImagePreviewModal);
+
+const setPropOfFoodItem = ({ foodItem, setFoodItem }: Props) => (prop: string) => (value: any) => {
+ setFoodItem(foodItem.set(prop, value));
+};
+
+const addImage = ({ foodItem, setFoodItem }: Props) => (uri: string) => {
+ setFoodItem(foodItem.update('images', images => images.push(uri)));
+};
+
+const updatePlace = ({ setPlace, foodItem, setFoodItem }: Props) => ({
+ placeID,
+ latitude,
+ longitude,
+ name,
+ address,
+ phoneNumber,
+ website,
+}) => {
+ setPlace(
+ new PlaceRecord({
+ id: placeID,
+ name,
+ address,
+ latitude,
+ longitude,
+ phoneNumber,
+ website,
+ })
+ );
+
+ setFoodItem(
+ foodItem.merge({
+ placeId: placeID,
+ latitude,
+ longitude,
+ })
+ );
+};
+
+const toggleNameModal = ({ nameModalOpen, setNameModalOpen }) => () => setNameModalOpen(!nameModalOpen);
export default compose(
withState('foodItem', 'setFoodItem', new FoodItemRecord()),
withState('place', 'setPlace', new PlaceRecord()),
withState('nameModalOpen', 'setNameModalOpen', false),
+ withState('imagePreview', 'setImagePreview', -1),
withHandlers({
- setPropOfFoodItem: ({ foodItem, setFoodItem }: Props) => (prop: string) => (value: any) => {
- setFoodItem(foodItem.set(prop, value));
- },
- addImage: ({ foodItem, setFoodItem }: Props) => (uri: string) => {
- setFoodItem(foodItem.update('images', images => [uri].concat(images)));
- },
- removeImageAtIndex: ({ foodItem, setFoodItem }: Props) => (index: number) => () => {
- setFoodItem(
- foodItem.update('images', (images: Array) => {
- images.splice(index, 1);
- return images;
- })
- );
- },
- updatePlace: ({ setPlace, foodItem, setFoodItem }: Props) => ({
- placeID,
- latitude,
- longitude,
- name,
- address,
- phoneNumber,
- website,
- }) => {
- setPlace(
- new PlaceRecord({
- id: placeID,
- name,
- address,
- latitude,
- longitude,
- phoneNumber,
- website,
- })
- );
-
- setFoodItem(
- foodItem.merge({
- placeId: placeID,
- latitude,
- longitude,
- })
- );
- },
- toggleNameModal: ({ nameModalOpen, setNameModalOpen }) => () => setNameModalOpen(!nameModalOpen),
+ setPropOfFoodItem,
+ addImage,
+ updatePlace,
+ toggleNameModal,
}),
- branch(({ nameModalOpen }) => !!nameModalOpen, enhanceNameModal(NameModal))
+ branch(({ nameModalOpen }) => !!nameModalOpen, NameModalComp),
+ branch(({ imagePreview }) => imagePreview > -1, ImagePreviewComp)
)(CreateFoodItem);
diff --git a/js/pages/FoodItemDetail.js b/js/pages/FoodItemDetail.js
index c2f0c46..95fbd77 100644
--- a/js/pages/FoodItemDetail.js
+++ b/js/pages/FoodItemDetail.js
@@ -68,15 +68,15 @@ export class FoodItemDetail extends Component {
return (
- {viewableImages.length === 1 &&
- }
- {viewableImages.length > 1 &&
+ {viewableImages.size === 1 &&
+ }
+ {viewableImages.size > 1 &&
{viewableImages.map(uri =>
)}
}
-
+
diff --git a/js/records/FoodItemRecord.js b/js/records/FoodItemRecord.js
index 039d5c4..11b6d5c 100644
--- a/js/records/FoodItemRecord.js
+++ b/js/records/FoodItemRecord.js
@@ -1,5 +1,5 @@
//@flow
-import { Record } from 'immutable';
+import { fromJS, List, Record } from 'immutable';
export const QUANTITY_NONE: 'none' = 'none';
export const QUANTITY_FEW: 'few' = 'few';
@@ -28,7 +28,7 @@ export type FoodItem = {
distance: number,
quantity: Quantity,
category: Category,
- images: Array,
+ images: List,
thumbImage: ?string,
titleImage: ?string,
};
@@ -42,9 +42,18 @@ const FoodRecordDefaults: FoodItem = {
distance: 999,
quantity: QUANTITY_MANY,
category: CATEGORY_DESSERTS,
- images: [],
+ images: new List(),
thumbImage: '',
titleImage: '',
};
-export default Record(FoodRecordDefaults, 'FoodItemRecord');
+const FoodItemRecord = Record(FoodRecordDefaults, 'FoodItemRecord');
+
+export const createFoodItem = (foodItemRaw: Object) => {
+ return new FoodItemRecord({
+ ...foodItemRaw,
+ images: fromJS(foodItemRaw.images),
+ });
+};
+
+export default FoodItemRecord;
diff --git a/js/streams/FoodItemsStream.js b/js/streams/FoodItemsStream.js
index 691a75c..4f927df 100644
--- a/js/streams/FoodItemsStream.js
+++ b/js/streams/FoodItemsStream.js
@@ -1,5 +1,5 @@
//@flow
-import FoodItemRecord from '../records/FoodItemRecord';
+import { createFoodItem } from '../records/FoodItemRecord';
import { Observable } from 'rxjs';
import { setById } from '../helpers/ImmutableHelpers';
import { Map } from 'immutable';
@@ -110,4 +110,4 @@ const DUMMY_DATA = [
export const foodItemsRaw$ = Observable.from(DUMMY_DATA);
-export default foodItemsRaw$.map(FoodItemRecord).scan(setById, Map());
+export default foodItemsRaw$.map(createFoodItem).scan(setById, Map());