// tslint:disable:jsx-no-lambda import React from 'react' import { Grayscale, cleanExtractedImagesCache } from 'react-native-image-filter-kit' import { Image, View, Button, ViewStyle, ImageStyle, StyleSheet, Alert, ActivityIndicator } from 'react-native' import { ImagePickerResponse, launchCamera } from 'react-native-image-picker' import useElmish, { Effects, Reducer, Effect } from 'react-use-elmish' import { unreachableCase } from 'ts-assert-unreachable' import CameraRoll from '@react-native-community/cameraroll' type State = ['ready'] | ['in-progress'] | ['photo-taken', string] type Action = | ['take-photo'] | ['set-uri', string | undefined] | ['save-photo', string] | ['show-error', Error] const init = (): [State, Effect] => [['ready'], Effects.none()] const update: Reducer = (_, action) => { switch (action[0]) { case 'take-photo': { const effect = Effects.fromPromise( takePhoto, (uri) => ['set-uri', uri], (error) => ['show-error', error] ) return [['in-progress'], effect] } case 'set-uri': { const [, uri] = action return uri === undefined ? [ ['ready'], Effects.attemptFunction(cleanExtractedImagesCache, (error) => ['show-error', error]) ] : [['photo-taken', uri], Effects.none()] } case 'save-photo': { const effect = Effects.fromPromise( () => saveImage(action[1]).then(() => showMessage('Success', 'Filtered image was saved to camera roll') ), () => ['set-uri', undefined], (error) => ['show-error', error] ) return [['in-progress'], effect] } case 'show-error': { const effect = Effects.fromPromise( () => showMessage('Error', action[1].message), () => ['set-uri', undefined], (error) => ['show-error', error] ) return [['in-progress'], effect] } default: return unreachableCase(action) } } const showMessage = (title: string, message: string) => new Promise((resolve) => { Alert.alert(title, message, [{ onPress: resolve, text: 'OK' }], { onDismiss: () => resolve(undefined) }) }) const takePhoto = () => new Promise((resolve, reject: (reason: Error) => void) => { launchCamera( { mediaType: 'photo' }, ({ didCancel, errorMessage, uri }: ImagePickerResponse) => { if (didCancel) { reject(new Error('cancelled')) } else if (errorMessage || uri === undefined) { reject(new Error(errorMessage ?? 'no uri')) } else { resolve(uri) } } ) }) const saveImage = (uri: string) => CameraRoll.save(uri, { type: 'photo' }) const Extractor = () => { const [state, dispatch] = useElmish(update, init) switch (state[0]) { case 'ready': { return (