import React, { useEffect, useState } from 'react'; import { View, FlatList, Image, Text, TouchableOpacity } from 'react-native'; import { useNavigation } from '@react-navigation/native'; import * as Progress from 'react-native-progress'; import * as ImagePicker from 'expo-image-picker'; import { Header, Input, Modal, PageWrapper, FlatList as List } from 'src/components'; import { API_HOST } from 'src/constants'; import { CustomButton } from '../Components'; import RangeCalendar from 'src/components/Calendars/RangeCalendar'; import { postSetUploadTemp, usePostRemoveTempMutation, usePostSaveTempMutation } from '@api/photos'; import { StoreType, storage } from 'src/storage'; import { AllRegions, ImageStatus, TempData } from '../utils/types'; import { itemWidth } from '../utils'; import { styles } from './styles'; import { Colors } from 'src/theme'; import AddImgSvg from '../../../../../assets/icons/travels-screens/add-img.svg'; import ChooseSvg from '../../../../../assets/icons/travels-screens/choose.svg'; import SaveSvg from '../../../../../assets/icons/travels-screens/save.svg'; import XCircleSvg from '../../../../../assets/icons/travels-screens/x-circle.svg'; import ChevronIcon from '../../../../../assets/icons/travels-screens/chevron-bottom.svg'; import CalendarSvg from '../../../../../assets/icons/calendar.svg'; const AddPhotoScreen = ({ route }: { route: any }) => { const navigation: any = useNavigation(); const { data, images, allRegions, tempData } = route.params; const token = storage.get('token', StoreType.STRING) as string; const [isModalVisible, setIsModalVisible] = useState(false); const [selectedRegion, setSelectedRegion] = useState( data && data.country ? ({ id: data.id, country: data.country } as AllRegions) : null ); const [description, setDescription] = useState(''); const [selectedDate, setSelectedDate] = useState( data && data.date ? data.date : new Date().toISOString().slice(0, 10) ); const { mutate: removeTemp } = usePostRemoveTempMutation(); const { mutate: saveTemp, data: saveResponse } = usePostSaveTempMutation(); const [imagesStatus, setImagesStatus] = useState( images?.map((image: ImagePicker.ImagePickerAsset) => ({ uri: image.uri, assetId: image.assetId, loaded: false, progress: 0, uploadResponse: null, dateTime: image.exif?.DateTimeOriginal?.split(' ')[0].replaceAll(':', '-') ?? null })) ); const [calendarVisible, setCalendarVisible] = useState(false); useEffect(() => { if (tempData) { setImagesStatus( tempData.map((temp: TempData) => { return { assetId: temp.guid, loaded: true, uploadResponse: temp }; }) ); return; } else { images.forEach((image: ImagePicker.ImagePickerAsset) => uploadTempImage(image)); } const date = images[images.length - 1]?.exif?.DateTimeOriginal?.split(' ')[0].replaceAll( ':', '-' ); date && setSelectedDate(date); }, [images]); const uploadTempImage = async (image: ImagePicker.ImagePickerAsset) => { const uriParts = image.uri.split('.'); const fileType = uriParts[uriParts.length - 1]; const imgData = { token, file: { uri: image.uri, name: image.uri.split('/').pop()!, type: `image/${fileType}` } }; image.assetId && simulateUploadProgress(image.assetId); postSetUploadTemp(imgData) .then((response) => { if (response && response.result === 'OK') { setImagesStatus((currentStatus) => currentStatus.map((item) => { if (item.assetId === image.assetId) { return { ...item, loaded: true, progress: 1, uploadResponse: { guid: response.guid, link: response.link } }; } return item; }) ); } }) .catch((error) => { console.error('Error', error); }); }; const simulateUploadProgress = (assetId: string) => { let progress = 0; const intervalId = setInterval(() => { progress += 0.05 + Math.random() * 0.25; if (progress >= 1) { clearInterval(intervalId); progress = 1; } setImagesStatus((currentStatus) => currentStatus.map((item) => { if (item.assetId === assetId) { return { ...item, progress }; } return item; }) ); }, 300); }; const deleteTemp = (item: ImageStatus) => { removeTemp( { token, guid: item.uploadResponse?.guid as string }, { onSuccess: (res) => { if (res.result === 'OK') { setImagesStatus( imagesStatus.filter( (img: ImageStatus) => img.uploadResponse?.guid !== item.uploadResponse?.guid ) ); } } } ); }; const handleSelectPhoto = async () => { await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, quality: 1, allowsMultipleSelection: true, exif: true }).then((result) => { if (!result.canceled) { addPhoto(result.assets); } }); }; const addPhoto = (newImages: ImagePicker.ImagePickerAsset[]) => { const date = newImages[newImages.length - 1]?.exif?.DateTimeOriginal?.split(' ')[0].replaceAll( ':', '-' ); date && setSelectedDate(date); setImagesStatus([ ...imagesStatus, ...newImages.map((image: any) => ({ uri: image.uri, assetId: image.assetId, loaded: false, progress: 0, uploadResponse: null, dateTime: image.exif?.DateTimeOriginal?.split(' ')[0].replaceAll(':', '-') ?? null })) ]); newImages.forEach((image: ImagePicker.ImagePickerAsset) => uploadTempImage(image)); }; const saveTempData = () => { const tempData = { token, guids: imagesStatus.map((img) => img.uploadResponse?.guid!), date: selectedDate, region: selectedRegion?.id!, description }; saveTemp(tempData, { onSuccess: () => { data && allRegions?.length ? navigation.pop(2) : navigation.goBack(); } }); }; const renderItem = ({ item }: { item: ImageStatus }) => ( {!item.loaded ? ( ) : ( )} {item.loaded && ( deleteTemp(item)}> )} ); const getHeaderLabel = () => { if (data?.country) return data.country; if (data?.date) return data.date; return 'Add photo'; }; return (
{data?.name && {data.name}} } disabled={!selectedRegion || imagesStatus.length === 0} /> } onPress={handleSelectPhoto} /> setDescription(text)} value={description} /> {!data?.country && ( setIsModalVisible(true)} > {selectedRegion?.country ?? 'Choose a region'} )} {!data?.date && ( setCalendarVisible(true)}> {selectedDate ?? 'Add date'} )} index.toString()} numColumns={2} columnWrapperStyle={styles.columnWrapper} showsVerticalScrollIndicator={false} /> setIsModalVisible(false)} headerTitle={'Select Region'} visible={isModalVisible} > { setSelectedRegion(object); setIsModalVisible(false); }} initialData={allRegions} /> { startDate && setSelectedDate(startDate.toString()); setCalendarVisible(false); }} allowRangeSelection={false} disableFutureDates={true} /> ); }; export default AddPhotoScreen;