Skip to content

Instantly share code, notes, and snippets.

@fakenickels
Created January 6, 2020 12:56
Show Gist options
  • Save fakenickels/152a06a0d4969c92d5a19459e5b7d764 to your computer and use it in GitHub Desktop.
Save fakenickels/152a06a0d4969c92d5a19459e5b7d764 to your computer and use it in GitHub Desktop.
type file = {
.
"path": string,
"data": string,
"mime": string,
"size": int,
};
type currentImage = {
.
"name": string,
"fileType": string,
"path": string,
};
type handleImagePicker = unit => Js.Promise.t(array(file));
type removeCurrentImage = int => unit;
type removeImage = int => unit;
type children =
(
~images: Js.nullable(array(file)),
~currentImages: array(currentImage),
~handleImagePicker: handleImagePicker,
~removeCurrentImage: removeCurrentImage,
~removeImage: removeImage
) =>
React.element;
type generalizedComponent('a) = React.component('a);
[@bs.module "./withImagePicker.js"]
external withUploader:
generalizedComponent('a) =>
React.component({
.
"currentImages": 'c,
"children": 'd,
}) =
"default";
module Enhanced = {
[@react.component]
let make' =
(
~images,
~currentImages,
~handleImagePicker,
~removeCurrentImage,
~removeImage,
~children: children,
) =>
children(
~images,
~currentImages,
~handleImagePicker=
() =>
handleImagePicker({
"width": 400,
"height": 400,
"cropping": true,
"multiple": true,
}),
~removeCurrentImage,
~removeImage,
);
/* We need to do this because our HOC uses context and this ensures Reason is going to wrap the call with React.createElement */
[@bs.obj]
external makeProps:
(
~currentImages: 'currentImages,
~children: 'children,
~key: string=?,
unit
) =>
{
.
"currentImages": 'currentImages,
"children": 'children,
} =
"";
let make = withUploader(make');
};
[@react.component]
let make = (~currentImages: array(currentImage), ~children: children) =>
<Enhanced currentImages> children </Enhanced>;
import { compose, withStateHandlers, withHandlers } from 'recompose'
import isArray from 'lodash/fp'
import ImagePicker from 'react-native-image-crop-picker'
import { connectActionSheet } from '@expo/react-native-action-sheet'
const enhancer = compose(
connectActionSheet,
withStateHandlers(
({ currentImages = [] }) => ({
images: [],
currentImages,
}),
{
setImages: state => images => ({ ...state, images }),
removeImage: state => removedIndex => ({
...state,
images: state.images.filter((_, index) => index !== removedIndex),
}),
removeCurrentImage: state => removedIndex => ({
...state,
currentImages: state.currentImages.filter(
(_, index) => index !== removedIndex,
),
}),
},
),
withHandlers({
handleImagePicker: ({ setImages, showActionSheetWithOptions }) => ({
width = 400,
height = 400,
cropping = true,
multiple,
} = {}) => {
return new Promise((resolve, reject) => {
const modes = {
album: 'Álbum',
camera: 'Câmera',
cancel: 'Cancelar',
}
const options = Object.keys(modes).map(mode => modes[mode])
const pickImage = async pick => {
try {
const image = await pick
return (isArray(image) ? image : [image]) || []
} catch (exception) {
return null
}
}
const switchImageMode = async mode => {
switch (mode) {
case modes.album:
return pickImage(
ImagePicker.openPicker({
width,
height,
cropping,
includeBase64: true,
multiple,
}),
)
case modes.camera:
return pickImage(
ImagePicker.openCamera({
width,
height,
includeBase64: true,
cropping,
}).then(image => [image]),
)
default:
return null
}
}
showActionSheetWithOptions(
{
options,
cancelButtonIndex: options.indexOf(modes.cancel),
},
async index => {
const images = await switchImageMode(options[index])
if (images) setImages(images)
resolve(images)
},
)
})
},
}),
)
export default enhancer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment