Explorar o código

fixed bugs and changed calendar

Viktoriia hai 1 ano
pai
achega
bb36885bc0

+ 1 - 0
package.json

@@ -41,6 +41,7 @@
     "react": "18.2.0",
     "react-native": "0.72.6",
     "react-native-calendar-picker": "^7.1.4",
+    "react-native-calendars": "^1.1304.1",
     "react-native-device-detection": "^0.2.1",
     "react-native-gesture-handler": "~2.12.0",
     "react-native-image-viewing": "^0.2.2",

+ 93 - 0
patches/react-native-calendars+1.1304.1.patch

@@ -0,0 +1,93 @@
+diff --git a/node_modules/react-native-calendars/src/calendar/day/period/index.js b/node_modules/react-native-calendars/src/calendar/day/period/index.js
+index f27db0e..434f414 100644
+--- a/node_modules/react-native-calendars/src/calendar/day/period/index.js
++++ b/node_modules/react-native-calendars/src/calendar/day/period/index.js
+@@ -87,21 +87,19 @@ const PeriodDay = (props) => {
+         return textStyle;
+     }, [marking, state]);
+     const fillerStyles = useMemo(() => {
+-        const leftFillerStyle = { backgroundColor: undefined };
+-        const rightFillerStyle = { backgroundColor: undefined };
++        const leftFillerStyle = { backgroundColor: marking?.disabled ? 'transparent' : 'rgb(250, 223, 194)' };
++        const rightFillerStyle = { backgroundColor: marking?.disabled ? 'transparent' : 'rgb(250, 223, 194)' };
+         let fillerStyle = {};
+         const start = markingStyle.startingDay;
+         const end = markingStyle.endingDay;
+-        if (start && !end) {
+-            rightFillerStyle.backgroundColor = markingStyle.startingDay?.backgroundColor;
++        if (start) {
++          leftFillerStyle.backgroundColor = markingStyle.day?.backgroundColor;
+         }
+-        else if (end && !start) {
+-            leftFillerStyle.backgroundColor = markingStyle.endingDay?.backgroundColor;
++        if (end) {
++          rightFillerStyle.backgroundColor = markingStyle.day?.backgroundColor;
+         }
+-        else if (markingStyle.day) {
+-            leftFillerStyle.backgroundColor = markingStyle.day?.backgroundColor;
+-            rightFillerStyle.backgroundColor = markingStyle.day?.backgroundColor;
+-            fillerStyle = { backgroundColor: markingStyle.day?.backgroundColor };
++        if (!start && !end && markingStyle.day) {
++          fillerStyle = { backgroundColor: markingStyle.day?.backgroundColor };
+         }
+         return { leftFillerStyle, rightFillerStyle, fillerStyle };
+     }, [marking]);
+diff --git a/node_modules/react-native-calendars/src/calendar/day/period/style.js b/node_modules/react-native-calendars/src/calendar/day/period/style.js
+index 51e2082..d82f5eb 100644
+--- a/node_modules/react-native-calendars/src/calendar/day/period/style.js
++++ b/node_modules/react-native-calendars/src/calendar/day/period/style.js
+@@ -10,7 +10,7 @@ export default function styleConstructor(theme = {}) {
+             marginLeft: -1
+         },
+         base: {
+-            width: 38,
++            width: FILLER_HEIGHT,
+             height: FILLER_HEIGHT,
+             alignItems: 'center',
+             justifyContent: 'center'
+@@ -44,7 +44,10 @@ export default function styleConstructor(theme = {}) {
+             bottom: 3
+         },
+         today: {
+-            backgroundColor: appStyle.todayBackgroundColor
++            backgroundColor: appStyle.todayBackgroundColor,
++            borderColor: '#ED9334',
++            borderWidth: 1,
++            borderRadius: 17
+         },
+         todayText: {
+             fontWeight: '500',
+diff --git a/node_modules/react-native-calendars/src/calendar/index.js b/node_modules/react-native-calendars/src/calendar/index.js
+index 6f46e8a..de8ce86 100644
+--- a/node_modules/react-native-calendars/src/calendar/index.js
++++ b/node_modules/react-native-calendars/src/calendar/index.js
+@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
+ import XDate from 'xdate';
+ import isEmpty from 'lodash/isEmpty';
+ import React, { useRef, useState, useEffect, useCallback, useMemo } from 'react';
+-import { View } from 'react-native';
++import { View, PanResponder } from 'react-native';
+ // @ts-expect-error
+ import GestureRecognizer, { swipeDirections } from 'react-native-swipe-gestures';
+ import constants from '../commons/constants';
+@@ -137,6 +137,11 @@ const Calendar = (props) => {
+         }
+         return false;
+     }, [currentMonth, displayLoadingIndicator, markedDates]);
++    const panResponder = useRef(
++      PanResponder.create({
++        onStartShouldSetPanResponder: () => true,
++      })
++    ).current;
+     const renderHeader = () => {
+         const headerProps = extractHeaderProps(props);
+         const ref = customHeader ? undefined : header;
+@@ -150,7 +155,7 @@ const Calendar = (props) => {
+     };
+     const gestureProps = enableSwipeMonths ? swipeProps : undefined;
+     return (<GestureComponent {...gestureProps}>
+-      <View style={[style.current.container, propsStyle]} testID={testID} accessibilityElementsHidden={accessibilityElementsHidden} // iOS
++      <View {...panResponder.panHandlers} style={[style.current.container, propsStyle]} testID={testID} accessibilityElementsHidden={accessibilityElementsHidden} // iOS
+      importantForAccessibility={importantForAccessibility} // Android
+     >
+         {renderHeader()}

+ 86 - 71
src/components/Calendars/RangeCalendar/index.tsx

@@ -1,78 +1,109 @@
-import React, { useMemo, useState } from 'react';
+import React, { useState } from 'react';
 import { View } from 'react-native';
-import CalendarPicker, {
-  CustomDatesStylesFunc,
-  CustomDayHeaderStylesFunc
-} from 'react-native-calendar-picker';
 import moment from 'moment';
 import { Modal } from '../../Modal';
-import Navigation from './Navigation';
 
 import { styles } from './style';
 import { Colors } from '../../../theme';
+import { Calendar } from 'react-native-calendars';
 
 export default function RangeCalendar({
   isModalVisible,
   closeModal,
-  allowRangeSelection = true
+  allowRangeSelection = true,
+  disableFutureDates = false,
 }: {
   isModalVisible: boolean;
-  closeModal: (selectedDate: Date | null) => void;
+  closeModal: (startDate: Date | null, endDate: Date | null) => void;
   allowRangeSelection?: boolean;
+  disableFutureDates?: boolean;
 }) {
   const [selectedStartDate, setSelectedStartDate] = useState<Date | null>(null);
   const [selectedEndDate, setSelectedEndDate] = useState<Date | null>(null);
 
-  const handleOnDateChange = (date: Date, type: string) => {
-    if (type === 'END_DATE') {
-      setSelectedEndDate(date);
-    } else {
-      setSelectedStartDate(date);
-      setSelectedEndDate(null);
-    }
+  const customThemeStyles = {
+    textSectionTitleColor: Colors.ORANGE,
+    todayTextColor: Colors.DARK_BLUE,
+    dayTextColor: Colors.DARK_BLUE,
+    textDisabledColor: Colors.LIGHT_GRAY,
+    dotColor: Colors.DARK_BLUE,
+    arrowColor: Colors.DARK_BLUE,
+    monthTextColor: Colors.DARK_BLUE,
+    indicatorColor: Colors.DARK_BLUE,
+    textDayFontWeight: 'normal',
+    textMonthFontWeight: 'bold',
+    textDayHeaderFontWeight: 'bold',
+    textDayFontSize: 14,
+    textMonthFontSize: 14,
+    textDayHeaderFontSize: 12,
+    selectedDayBackgroundColor: Colors.ORANGE,
+    'stylesheet.calendar.header': {
+      header: styles.calendarHeader
+    },
   };
 
-  const customDayHeaderStyles: CustomDayHeaderStylesFunc = () => {
-    return {
-      textStyle: styles.dayHeader
-    };
+  const onDayPress = (day: any) => {
+    if (!allowRangeSelection) {
+      setSelectedStartDate(day.dateString);
+      return;
+    } 
+    if (!selectedStartDate || (selectedStartDate && selectedEndDate)) {
+      setSelectedStartDate(day.dateString);
+      setSelectedEndDate(null);
+    } else if (!selectedEndDate) {
+      if (day.dateString < selectedStartDate) {
+        setSelectedEndDate(selectedStartDate);
+        setSelectedStartDate(day.dateString);
+      } else {
+        setSelectedEndDate(day.dateString);
+      }
+    }
   };
 
-  const customSelectedDatesStyles: CustomDatesStylesFunc = useMemo(() => {
-    return (date: moment.Moment) => {
-      if (date.isSame(moment(), 'day')) {
-        return {
-          containerStyle: {},
-          textStyle: {
-            borderWidth: 1,
-            borderColor: Colors.DARK_BLUE,
-            borderRadius: 17,
-            height: 34,
-            width: 34,
-            textAlign: 'center',
-            verticalAlign: 'middle'
-          },
-          style: {
-            backgroundColor: Colors.WHITE
-          }
-        };
+  const markedDates = (() => {
+    const marked: { [key: string]: any } = {};
+    let start = selectedStartDate as unknown as string;
+    let end = selectedEndDate as unknown as string;
+    if (disableFutureDates) {
+      const today = moment().add(1, 'day');
+      const lastDay = moment().add(2, 'years');
+      while (today.isBefore(lastDay, 'day')) {
+        const dateString = today.format('YYYY-MM-DD');
+        if (!marked[dateString]) {
+          marked[dateString] = {  disableTouchEvent: true, disabled: true };
+        }
+        today.add(1, 'day');
       }
-      return {
-        containerStyle: {},
-        textStyle: {}
+    }
+    if (start && end) {
+      marked[start] = { startingDay: true, color: Colors.ORANGE, textColor: 'white' };
+      let day = start;
+      while (day < end) {
+        day = moment(day).add(1, 'days').format('YYYY-MM-DD');
+        if (day === end) {
+          marked[day] = { endingDay: true, color: Colors.ORANGE, textColor: 'white' };
+        } else {
+          marked[day] = { color: 'transparent', textColor: Colors.DARK_BLUE };
+        }
+      }
+    } else if (start) {
+      marked[start] = {
+        selected: true,
+        startingDay: true,
+        endingDay: true,
+        color: Colors.ORANGE,
+        textColor: 'white',
       };
-    };
-  }, []);
+    }
+    return marked;
+  })();
 
   const resetSelections = () => {
-    closeModal(selectedStartDate);
+    closeModal(selectedStartDate, selectedEndDate);
     setSelectedStartDate(null);
     setSelectedEndDate(null);
   };
 
-  const prevNavigationComponent = useMemo(() => <Navigation direction="prev" />, []);
-  const nextNavigationComponent = useMemo(() => <Navigation direction="next" />, []);
-
   return (
     <Modal
       visibleInPercent={'auto'}
@@ -81,31 +112,15 @@ export default function RangeCalendar({
       headerTitle="Select Date"
     >
       <View style={styles.modalContent}>
-        <CalendarPicker
-          scaleFactor={400}
-          allowRangeSelection={allowRangeSelection}
-          allowBackwardRangeSelect
-          onDateChange={handleOnDateChange as any}
-          selectedStartDate={selectedStartDate as Date}
-          selectedEndDate={selectedEndDate as Date}
-          scrollable
-          showDayStragglers
-          previousComponent={prevNavigationComponent}
-          nextComponent={nextNavigationComponent}
-          dayLabelsWrapper={styles.labelsWrapper}
-          selectedRangeStyle={styles.rangeStyle}
-          selectedRangeEndTextStyle={styles.rangeStartEndTextStyle}
-          selectedRangeStartTextStyle={styles.rangeStartEndTextStyle}
-          selectedRangeEndStyle={[styles.rangeStartEndStyle, styles.rangeEndStyle]}
-          selectedRangeStartStyle={[styles.rangeStartEndStyle, styles.rangeStartStyle]}
-          selectedDayTextColor={Colors.WHITE}
-          customDayHeaderStyles={customDayHeaderStyles}
-          customDatesStyles={customSelectedDatesStyles}
-          disabledDatesTextStyle={styles.disabledDates}
-          textStyle={styles.textStyle}
-          monthTitleStyle={styles.dateTitle}
-          yearTitleStyle={styles.dateTitle}
-          headerWrapperStyle={styles.headerWrapper}
+        <Calendar
+          onDayPress={onDayPress}
+          markingType={'period'}
+          markedDates={markedDates}
+          enableSwipeMonths={true}
+          firstDay={1}
+          theme={{
+            ...customThemeStyles,
+          }}
         />
       </View>
     </Modal>

+ 6 - 52
src/components/Calendars/RangeCalendar/style.ts

@@ -6,58 +6,12 @@ export const styles = StyleSheet.create({
     backgroundColor: Colors.WHITE,
     paddingTop: 22,
     paddingBottom: 52,
-    justifyContent: 'center',
-    alignItems: 'center'
+    height: '50%',
   },
-  rangeStartEndTextStyle: {
-    color: Colors.WHITE
+  calendarHeader: {
+    flexDirection: 'row',
+    justifyContent: 'space-between',
+    marginBottom: 16,
+    alignItems: 'center',
   },
-  rangeStartEndStyle: {
-    width: 40
-  },
-  rangeEndStyle: {
-    alignSelf: 'flex-start',
-    justifyContent: 'flex-start',
-    borderTopRightRadius: 20,
-    borderBottomRightRadius: 20
-  },
-  rangeStartStyle: {
-    alignSelf: 'flex-end',
-    justifyContent: 'flex-end',
-    borderTopLeftRadius: 20,
-    borderBottomLeftRadius: 20
-  },
-  rangeStyle: {
-    backgroundColor: Colors.DARK_LIGHT,
-    height: 34
-  },
-  labelsWrapper: {
-    borderTopWidth: 0,
-    borderBottomWidth: 0,
-    marginBottom: 5
-  },
-  disabledDates: {
-    backgroundColor: Colors.WHITE,
-    textAlign: 'center',
-    textAlignVertical: 'center'
-  },
-  dateTitle: {
-    color: Colors.DARK_BLUE,
-    fontSize: 16,
-    fontWeight: '700'
-  },
-  headerWrapper: {
-    marginBottom: 15
-  },
-  textStyle: {
-    color: Colors.DARK_BLUE,
-    fontSize: 14,
-    lineHeight: 32
-  },
-  dayHeader: {
-    color: Colors.ORANGE,
-    fontSize: 12,
-    letterSpacing: 1,
-    fontWeight: '700'
-  }
 });

+ 10 - 17
src/screens/InAppScreens/TravelsScreen/AddPhotoScreen/index.tsx

@@ -38,7 +38,7 @@ const AddPhotoScreen = ({ route }: { route: any }) => {
   );
   const [description, setDescription] = useState('');
   const [selectedDate, setSelectedDate] = useState<string | null>(
-    data && data.date ? data.date : null
+    data && data.date ? data.date : new Date().toISOString().slice(0, 10)
   );
   const { mutate: removeTemp } = usePostRemoveTempMutation();
   const { mutate: saveTemp, data: saveResponse } = usePostSaveTempMutation();
@@ -88,7 +88,7 @@ const AddPhotoScreen = ({ route }: { route: any }) => {
 
     image.assetId && simulateUploadProgress(image.assetId);
 
-    await postSetUploadTemp(imgData)
+    postSetUploadTemp(imgData)
       .then((response) => {
         if (response && response.result === 'OK') {
           setImagesStatus((currentStatus) =>
@@ -162,9 +162,11 @@ const AddPhotoScreen = ({ route }: { route: any }) => {
   };
 
   const addPhoto = (newImages: ImagePicker.ImagePickerAsset[]) => {
-    setSelectedDate(
-      newImages[newImages.length - 1]?.exif?.DateTimeOriginal?.split(' ')[0].replaceAll(':', '-')
+    const date = newImages[newImages.length - 1]?.exif?.DateTimeOriginal?.split(' ')[0].replaceAll(
+      ':',
+      '-'
     );
+    date && setSelectedDate(date);
     setImagesStatus([
       ...imagesStatus,
       ...newImages.map((image: any) => ({
@@ -213,10 +215,7 @@ const AddPhotoScreen = ({ route }: { route: any }) => {
           />
         )}
         {item.loaded && (
-          <TouchableOpacity
-            style={styles.deleteTemp}
-            onPress={() => deleteTemp(item)}
-          >
+          <TouchableOpacity style={styles.deleteTemp} onPress={() => deleteTemp(item)}>
             <XCircleSvg />
           </TouchableOpacity>
         )}
@@ -242,13 +241,6 @@ const AddPhotoScreen = ({ route }: { route: any }) => {
             icon={<SaveSvg fill={Colors.DARK_BLUE} />}
             disabled={!selectedRegion || imagesStatus.length === 0}
           />
-
-          <CustomButton
-            title="Choose"
-            icon={<ChooseSvg fill={Colors.DARK_BLUE} />}
-            onPress={() => {}}
-            disabled={true}
-          />
           <CustomButton
             title="Add photo"
             icon={<AddImgSvg fill={Colors.DARK_BLUE} />}
@@ -305,11 +297,12 @@ const AddPhotoScreen = ({ route }: { route: any }) => {
 
       <RangeCalendar
         isModalVisible={calendarVisible}
-        closeModal={(date: Date | null) => {
-          date && setSelectedDate(date.toISOString().split('T')[0]);
+        closeModal={(startDate: Date | null, endDate: Date | null) => {
+          startDate && setSelectedDate(startDate.toString());
           setCalendarVisible(false);
         }}
         allowRangeSelection={false}
+        disableFutureDates={true}
       />
     </PageWrapper>
   );

+ 2 - 1
src/screens/InAppScreens/TravelsScreen/AddPhotoScreen/styles.tsx

@@ -34,6 +34,7 @@ export const styles = StyleSheet.create({
     flexDirection: 'row',
     justifyContent: 'space-between',
     alignItems: 'center',
-    gap: 5
+    gap: 15,
+    width: '85%'
   }
 });

+ 62 - 20
src/screens/InAppScreens/TravelsScreen/Components/PhotoItem.tsx

@@ -1,4 +1,4 @@
-import React, { useCallback, useMemo } from 'react';
+import React, { useCallback, useEffect, useMemo, useState } from 'react';
 import { View, Image, Text, TouchableOpacity } from 'react-native';
 import { useNavigation } from '@react-navigation/native';
 
@@ -8,10 +8,29 @@ import { NAVIGATION_PAGES } from 'src/types';
 import { styles } from './styles';
 
 import ChevronRightIcon from '../../../../../assets/icons/travels-screens/chevron-right.svg';
+import { API_HOST } from 'src/constants';
+import ImageView from 'react-native-image-viewing';
 
 export const PhotoItem = React.memo(
   ({ item, allRegions }: { item: any; allRegions: AllRegions[] }) => {
     const navigation = useNavigation();
+    const [currentImageIndex, setCurrentImageIndex] = useState(0);
+    const [isViewerVisible, setIsViewerVisible] = useState(false);
+    const [fullImages, setFullImages] = useState<PhotosData[]>([]);
+
+    const openImageViewer = (index: number) => {
+      setCurrentImageIndex(index);
+      setIsViewerVisible(true);
+    };
+
+    useEffect(() => {
+      setFullImages(
+        item.photos.map((photo: PhotosData) => ({
+          ...photo,
+          uri: API_HOST + photo.url_mid
+        }))
+      );
+    }, [item]);
 
     const renderPhotos = () => {
       const photos = item.photos.slice(0, 3);
@@ -19,41 +38,55 @@ export const PhotoItem = React.memo(
 
       if (photos.length === 1) {
         return (
-          <Image source={{ uri: getImageUri(photos[0].url_small) }} style={photoStyles.onePhoto} />
+          <TouchableOpacity onPress={() => openImageViewer(0)}>
+            <Image
+              source={{ uri: getImageUri(photos[0].url_small) }}
+              style={photoStyles.onePhoto}
+            />
+          </TouchableOpacity>
         );
       } else if (photos.length === 2) {
         return photos.map((photo: PhotosData, index: number) => (
-          <Image
-            key={photo.id}
-            source={{ uri: getImageUri(photo.url_small) }}
-            style={[photoStyles.twoPhotos, index === 0 && { marginRight: 8 }]}
-          />
+          <TouchableOpacity key={photo.id} onPress={() => openImageViewer(index)}>
+            <Image
+              source={{ uri: getImageUri(photo.url_small) }}
+              style={[photoStyles.twoPhotos, index === 0 && { marginRight: 8 }]}
+            />
+          </TouchableOpacity>
         ));
       } else {
         return (
           <View style={{ flexDirection: 'row' }}>
-            <Image
-              source={{ uri: getImageUri(photos[0].url_small) }}
-              style={photoStyles.bigPhoto}
-            />
-            <View style={styles.smallPhotoContainer}>
+            <TouchableOpacity onPress={() => openImageViewer(0)}>
               <Image
-                source={{ uri: getImageUri(photos[1].url_small) }}
-                style={photoStyles.smallPhoto}
-              />
-              <Image
-                source={{ uri: getImageUri(photos[2].url_small) }}
-                style={[photoStyles.smallPhoto, { position: 'relative' }]}
+                source={{ uri: getImageUri(photos[0].url_small) }}
+                style={photoStyles.bigPhoto}
               />
+            </TouchableOpacity>
+
+            <View style={styles.smallPhotoContainer}>
+              <TouchableOpacity onPress={() => openImageViewer(1)}>
+                <Image
+                  source={{ uri: getImageUri(photos[1].url_small) }}
+                  style={photoStyles.smallPhoto}
+                />
+              </TouchableOpacity>
+              <TouchableOpacity onPress={() => openImageViewer(2)}>
+                <Image
+                  source={{ uri: getImageUri(photos[2].url_small) }}
+                  style={[photoStyles.smallPhoto, { position: 'relative' }]}
+                />
+              </TouchableOpacity>
               {morePhotosCount > 0 && (
-                <View
+                <TouchableOpacity
+                  onPress={() => openImageViewer(2)}
                   style={[
                     styles.morePhotosOverlay,
                     { width: smallPhotoWidth, height: smallPhotoHeight }
                   ]}
                 >
                   <Text style={styles.morePhotosText}>+{morePhotosCount}</Text>
-                </View>
+                </TouchableOpacity>
               )}
             </View>
           </View>
@@ -97,6 +130,15 @@ export const PhotoItem = React.memo(
           </TouchableOpacity>
         </View>
         <View style={styles.photoContainer}>{photoViews}</View>
+        <ImageView
+          images={fullImages}
+          keyExtractor={(imageSrc, index) => index.toString()}
+          imageIndex={currentImageIndex}
+          visible={isViewerVisible}
+          onRequestClose={() => setIsViewerVisible(false)}
+          swipeToCloseEnabled={false}
+          backgroundColor="transparent"
+        />
       </View>
     );
   }