All files / atlas-mobile-ts/src/components/Map/Panels/LandmarkDetailsPanel LandmarkPhotos.tsx

0% Statements 0/29
0% Branches 0/38
0% Functions 0/12
0% Lines 0/27

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                                                                                                                                                                                                                         
import { FontAwesome } from "@expo/vector-icons"
import { ImageInfo } from "expo-image-picker/build/ImagePicker.types"
import React, { useEffect, useState } from "react"
import { View, Text, ActivityIndicator, ScrollView, TouchableOpacity, Image } from "react-native"
import { QueryStatus } from "react-query"
import { Landmark, LMPhoto, useLandmarks } from "../../../../hooks/useLandmarks"
import { IconButton, PrimaryButton } from "../../../Buttons"
import { PhotoPicker } from "../../../PhotoPicker"
 
interface LandmarkPhotosProps {
    deletePhotoStatus: QueryStatus 
    addPhoto: (photo: LMPhoto) => void
    addPhotoStatus: QueryStatus
    toggleLmDetails: (state: boolean) => void
    landmark?: Landmark
    editingEnabled: boolean
    setUpdatedLandmark: (state: Landmark) => void
    updatedLandmark?: Landmark
    setSelectedImage: (index: number) => void
    tryDeletePhoto: (photoId: string) => void
    processingPhoto: boolean
    setProcessingPhoto: (state: boolean) => void
    profileId: string
}
 
export const LandmarkPhotos: React.FC<LandmarkPhotosProps> = (props) => {
    /**
     * Flag that toggles the photo source menu being displayed
    */
    const photoSourceMenuOpenedState = false
    const [photoSourceMenuOpened, togglePhotoSourceMenu] = useState<boolean>(photoSourceMenuOpenedState) 
 
    /**
     * Handles selection of a selected photo. Adds the photo data to the database.
    */
     const _onPhotoSelected = async (result: ImageInfo) => {
        togglePhotoSourceMenu(false)
        const photo: LMPhoto = {id: '', image_b64: 'data:image/png;base64,' + result.base64, height: result.height, width: result.width, landmark: props.landmark?.id}
        props.setProcessingPhoto(false)
        await props.addPhoto(photo)
    }
 
    /**
     * Sets given image as selected photo to be maximized on the screen
     * @param 
     */
    const maximizePhoto = (i: number): void => {
        if (!props.editingEnabled) {
            props.setSelectedImage(i)
        }
        else {
            console.warn('[LandmarkDetails]: Editing is enabled, can\'t maximize image')
        }
    }
 
    return (
        <>
            {
            props.deletePhotoStatus == 'loading' || 
            props.deletePhotoStatus == 'error' || 
            props.addPhotoStatus == "loading" || 
            props.addPhotoStatus == "error" ||
            props.processingPhoto ?
            <View style={{justifyContent: "space-evenly", alignItems: "center"}}>
                <Text style={{color: 'white', fontSize: 20, marginBottom: 40}}>{
                    props.deletePhotoStatus == "loading" || props.addPhotoStatus == "loading" ? "Loading photos" :
                    props.deletePhotoStatus == "error" || props.addPhotoStatus == "error" ? "There was an error loading photos" : 
                    props.processingPhoto ? "Processing photo" : null
                }</Text>
                {
                    props.deletePhotoStatus == 'loading' || props.addPhotoStatus == "loading" || props.processingPhoto ? <ActivityIndicator color='white' size="large"/> :
                    props.deletePhotoStatus == 'error' || props.addPhotoStatus == "error" ? <PrimaryButton text="Okay" style={{borderColor: 'white', borderWidth: 1}} onPress={() => props.toggleLmDetails(false)} /> : null
                }
            </View> : 
            <>
                <PhotoPicker 
                    multiple={true} 
                    menuType="alert" 
                    onReceivedPhotoResult={async result => await _onPhotoSelected(result)} 
                    photoSourceMenuOpened={photoSourceMenuOpened} 
                    onBeforeLaunchPicker={() => props.setProcessingPhoto(true)} 
                    cancel={() => {props.setProcessingPhoto(false) ; togglePhotoSourceMenu(false)}}/> 
                {props.landmark?.photos?.length > 0 ? 
                <>
                    <ScrollView nestedScrollEnabled={true} contentContainerStyle={{alignItems: 'center'}} style={{flexDirection: 'row', marginBottom: 5, alignSelf: 'center'}} horizontal={true}>
                        {props.landmark?.photos?.length < 5 && props.profileId == props.landmark?.user ? <IconButton style={{alignSelf: 'center', padding: 10, opacity: .5, marginLeft: 10}} color='white' size={30} icon="plus" onPress={() => togglePhotoSourceMenu(true)} />: null}
                        {props.landmark?.photos?.map((photo, i) => {    
                            
                            return (
                                <TouchableOpacity activeOpacity={1} key={i} style={{marginHorizontal: 1, padding: 14, zIndex: 11}} onPress={() => maximizePhoto(i)}>
                                    <Image style={{alignSelf: 'center', height: 300, width: 200}} source={{uri: 'data:image/png;base64,' + photo.image_b64}}/> 
                                    {props.landmark?.user == props.profileId ? <IconButton icon="times-circle" color="lightgray" style={{position: 'absolute', top: -2, right: 0}} size={25} onPress={() => props.tryDeletePhoto(photo.id)} /> : null}
                                </TouchableOpacity>
                            )
                        })}
                    </ScrollView>
                    
                </> : 
                <>
                {props.landmark?.user == props.profileId ?
                <TouchableOpacity style={{marginTop: 30, justifyContent: 'center', alignItems: 'center', opacity: .7}} onPress={() => {togglePhotoSourceMenu(true)}}>
                    <Text style={{fontSize: 20, marginBottom: 10, color: 'white'}}>Add photo</Text>
                    <FontAwesome name="plus" size={30} color='white' />
                </TouchableOpacity> : null}
                </>}
            </> }
        </>
    )
}