# All files / atlas-mobile-ts/src/components PhotoPicker.tsx

0% Statements 0/54
0% Branches 0/16
0% Functions 0/11
0% Lines 0/53

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126

     ﻿/* Copyright (C) Click & Push Accessibility, Inc - All Rights Reserved
     * Unauthorized copying of this file, via any medium is strictly prohibited
     * Proprietary and confidential
     * Written and maintained by the Click & Push Development team
     * <dev@clicknpush.ca>, January 2022
     */

    import * as ImagePicker from "expo-image-picker"
    import { ImageInfo } from "expo-image-picker/build/ImagePicker.types"
    import React, { useEffect, useState } from "react"
    import {Alert, AlertButton, Linking, Platform, Text} from 'react-native'
    import { Menu, MenuOption, MenuOptions, MenuTrigger, renderers } from "react-native-popup-menu"
    import { colors, getMediaPermissions } from "../utils/GlobalUtils"
    const {SlideInMenu} = renderers

    export const PhotoPicker: React.FC<{photoSourceMenuOpened: boolean, cancel: () => void, onBeforeLaunchPicker?: () => void, onReceivedPhotoResult?: (result: ImageInfo) => void, menuType: 'slideup' | 'alert', multiple: boolean}> = ({photoSourceMenuOpened, cancel, onBeforeLaunchPicker, onReceivedPhotoResult, menuType, multiple}) => {

        useEffect(() => {
            Iif (photoSourceMenuOpened && menuType ==  'alert') {
                console.log("[PhotoPicker]: PhotoPicker is launching with menutype = " + menuType + " and multiple = " + multiple)
                showAlert()
            }
        }, [photoSourceMenuOpened])

        const showAlert = () => {
            if (Platform.OS == 'android') {
                Alert.alert(
                    "Pick photo source",
                    "Where would like to get the photo from?",
                    [
                        {text: 'Cancel', onPress: cancel, style: 'cancel'},
                        {text: 'Camera', onPress: () => selectNewPhoto('camera')},
                        {text: 'Library', onPress: () => selectNewPhoto('library')},
                    ],
                    {onDismiss: cancel, cancelable: true})
            }
            else Iif (Platform.OS == 'ios') {
                Alert.alert(
                    "Pick photo source",
                    "Where would like to get the photo from?",
                    [
                        {text: 'Camera', onPress: () => selectNewPhoto('camera')},
                        {text: 'Library', onPress: () => selectNewPhoto('library')},
                        {text: 'Cancel', onPress: cancel, style: 'cancel'},
                    ],
                    {onDismiss: cancel, cancelable: true})
            }

        }

        const selectNewPhoto = async (imageSource: 'camera' | 'library') => {
            Iif (onBeforeLaunchPicker) {
                onBeforeLaunchPicker()
            }

            console.log("[Permissions]: Checking photo permissions...")
            const granted = await getMediaPermissions();

            if (granted) {
                console.log("[Permissions]: Photo permissions are granted")
                const imageOptions: ImagePicker.ImagePickerOptions = {
                    mediaTypes: ImagePicker.MediaTypeOptions.Images,
                    base64: true,
                    allowsEditing: true,
                    quality: .5,
                    allowsMultipleSelection: multiple
                }

                let result: ImagePicker.ImagePickerResult = {cancelled: true}

                try {
                    Iif (imageSource === 'camera') {
                        console.log("[PhotoPicker]: Camera was selected as photo source, launching camera...")
                        result = await ImagePicker.launchCameraAsync(imageOptions)
                    }

                    Iif (imageSource === 'library') {
                        console.log("[PhotoPicker]: Image Library was selected as photo source, launching library...")
                        result = await ImagePicker.launchImageLibraryAsync(imageOptions)
                    }
                    if (!result.cancelled) {
                        console.log("[PhotoPicker]: User selected image")
                        onReceivedPhotoResult(result as ImageInfo)
                    }
                    else {
                        console.log("[PhotoPicker]: User canceled image selection")
                        cancel()
                    }
                } catch (error) {
                    console.log("[PhotoPicker]: An error occurred during image selection: " + error)
                    Alert.alert("Something went wrong when loading the selected image. Please try another image.")
                    cancel()
                }
            }
            else {
                const permissionsButtons: AlertButton[] = [{text: 'Cancel', style: "cancel", onPress: cancel}]
                Iif (Platform.OS == 'ios')
                    permissionsButtons.push({text: 'Go to settings', onPress: () => {
                        Linking.openURL('app-settings:')
                        cancel()
                    }})
                Alert.alert(
                    "Permissions needed",
                    "You need to grant camera/storage permissions to upload an image.",
                    permissionsButtons,
                    {onDismiss: cancel, cancelable: true})
            }
        }

        return (
            <>
            {menuType == 'slideup' ?
            <Menu renderer={SlideInMenu} style={{zIndex: 10}} opened={photoSourceMenuOpened} onBackdropPress={cancel} >
                <MenuTrigger />
                <MenuOptions optionsContainerStyle={{backgroundColor: colors.red}}>
                    <MenuOption onSelect={async () => await selectNewPhoto('camera')} style={{padding: 20, alignItems: 'center', borderBottomWidth: 1, borderColor: 'white', marginHorizontal: 10}} >
                        <Text style={{fontSize: 20, color: 'white'}}>Select from camera</Text>
                    </MenuOption>
                    <MenuOption onSelect={async () => await selectNewPhoto('library')} style={{padding: 20, alignItems: 'center'}} >
                        <Text style={{fontSize: 20, color: 'white'}}>Select from library</Text>
                    </MenuOption>
                </MenuOptions>
            </Menu> : null}
            </>
        )
    }