From 9ab3f53d0902d99693d3009241eddf4a82baea5a Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Sun, 27 Oct 2024 20:51:50 +0100 Subject: [PATCH] Fix day circle rendering --- components/pages/calendar/EventCalendar.tsx | 423 +++++++++++--------- ios/cally/Info.plist | 1 + 2 files changed, 234 insertions(+), 190 deletions(-) diff --git a/components/pages/calendar/EventCalendar.tsx b/components/pages/calendar/EventCalendar.tsx index 26eb8e4..e94b056 100644 --- a/components/pages/calendar/EventCalendar.tsx +++ b/components/pages/calendar/EventCalendar.tsx @@ -1,211 +1,254 @@ -import React, { useCallback, useEffect, useMemo, useState } from "react"; -import { Calendar } from "react-native-big-calendar"; -import { ActivityIndicator, StyleSheet, View } from "react-native"; -import { useGetEvents } from "@/hooks/firebase/useGetEvents"; -import { useAtom, useSetAtom } from "jotai"; +import React, {useCallback, useEffect, useMemo, useState} from "react"; +import {Calendar} from "react-native-big-calendar"; +import {ActivityIndicator, StyleSheet, View, ViewStyle} from "react-native"; +import {useGetEvents} from "@/hooks/firebase/useGetEvents"; +import {useAtom, useSetAtom} from "jotai"; import { - editVisibleAtom, - eventForEditAtom, - modeAtom, - selectedDateAtom, - selectedNewEventDateAtom, + editVisibleAtom, + eventForEditAtom, + modeAtom, + selectedDateAtom, + selectedNewEventDateAtom, } from "@/components/pages/calendar/atoms"; -import { useAuthContext } from "@/contexts/AuthContext"; -import { CalendarEvent } from "@/components/pages/calendar/interfaces"; -import { act } from "react-test-renderer"; +import {useAuthContext} from "@/contexts/AuthContext"; +import {CalendarEvent} from "@/components/pages/calendar/interfaces"; +import {Text} from "react-native-ui-lib"; interface EventCalendarProps { - calendarHeight: number; - // WAS USED FOR SCROLLABLE CALENDARS, PERFORMANCE WAS NOT OPTIMAL - calendarWidth: number; + calendarHeight: number; + // WAS USED FOR SCROLLABLE CALENDARS, PERFORMANCE WAS NOT OPTIMAL + calendarWidth: number; } const getTotalMinutes = () => { - const date = new Date(); - return Math.abs(date.getUTCHours() * 60 + date.getUTCMinutes() - 200); + const date = new Date(); + return Math.abs(date.getUTCHours() * 60 + date.getUTCMinutes() - 200); }; export const EventCalendar: React.FC = React.memo( - ({ calendarHeight }) => { - const { data: events, isLoading } = useGetEvents(); - const { profileData } = useAuthContext(); - const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom); - const [activeDate, setActiveDate] = useState(new Date()); - const [mode, setMode] = useAtom(modeAtom); + ({calendarHeight}) => { + const {data: events, isLoading} = useGetEvents(); + const {profileData} = useAuthContext(); + const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom); + const [mode, setMode] = useAtom(modeAtom); - const setEditVisible = useSetAtom(editVisibleAtom); - const setEventForEdit = useSetAtom(eventForEditAtom); - const setSelectedNewEndDate = useSetAtom(selectedNewEventDateAtom); + const setEditVisible = useSetAtom(editVisibleAtom); + const setEventForEdit = useSetAtom(eventForEditAtom); + const setSelectedNewEndDate = useSetAtom(selectedNewEventDateAtom); - const [isRendering, setIsRendering] = useState(true); - const [offsetMinutes, setOffsetMinutes] = useState(getTotalMinutes()); + const [isRendering, setIsRendering] = useState(true); + const [offsetMinutes, setOffsetMinutes] = useState(getTotalMinutes()); - useEffect(() => { - if (events && mode) { - setIsRendering(true); - const timeout = setTimeout(() => { - setIsRendering(false); - }, 300); - return () => clearTimeout(timeout); - } - }, [events, mode]); + const todaysDate = new Date() - const handlePressEvent = useCallback( - (event: CalendarEvent) => { - if (mode === "day" || mode === "week") { - setEditVisible(true); - console.log({ event }); - setEventForEdit(event); - } else { - setMode("day"); - setSelectedDate(event.start); + useEffect(() => { + if (events && mode) { + setIsRendering(true); + const timeout = setTimeout(() => { + setIsRendering(false); + }, 300); + return () => clearTimeout(timeout); + } + }, [events, mode]); + + const handlePressEvent = useCallback( + (event: CalendarEvent) => { + if (mode === "day" || mode === "week") { + setEditVisible(true); + console.log({event}); + setEventForEdit(event); + } else { + setMode("day"); + setSelectedDate(event.start); + } + }, + [setEditVisible, setEventForEdit, mode] + ); + + const handlePressCell = useCallback( + (date: Date) => { + if (mode === "day" || mode === "week") { + setSelectedNewEndDate(date); + } else { + setMode("day"); + setSelectedDate(date); + } + }, + [mode, setSelectedNewEndDate, setSelectedDate] + ); + + const handleSwipeEnd = useCallback( + (date: Date) => { + setSelectedDate(date); + }, + [setSelectedDate] + ); + + const memoizedEventCellStyle = useCallback( + (event: CalendarEvent) => ({backgroundColor: event.eventColor}), + [] + ); + + const memoizedWeekStartsOn = useMemo( + () => (profileData?.firstDayOfWeek === "Mondays" ? 1 : 0), + [profileData] + ); + + const isSameDate = useCallback((date1: Date, date2: Date) => { + return ( + date1.getDate() === date2.getDate() && + date1.getMonth() === date2.getMonth() && + date1.getFullYear() === date2.getFullYear() + ); + }, []); + + const dayHeaderColor = useMemo(() => { + return isSameDate(todaysDate, selectedDate) && mode === "day" ? "white" : "#4d4d4d"; + }, [selectedDate, mode]); + + const dateStyle = useMemo(() => { + return isSameDate(todaysDate, selectedDate) && mode === "day" + ? styles.dayHeader + : styles.otherDayHeader; + }, [selectedDate, mode]); + + const memoizedHeaderContentStyle = useMemo(() => { + if (mode === "day") { + return styles.dayModeHeader; + } else if (mode === "week") { + return styles.weekModeHeader; + } else if (mode === "month") { + return styles.monthModeHeader; + } else { + return {}; + } + }, [mode]); + + const memoizedEvents = useMemo(() => events ?? [], [events]); + + const renderCustomDateForMonth = (date: Date) => { + const circleStyle = useMemo( + () => ({ + position: "absolute", + width: 30, + height: 30, + justifyContent: "center", + alignItems: "center", + borderRadius: 15, + }), + [] + ); + + const defaultStyle = useMemo( + () => ({ + ...circleStyle, + }), + [circleStyle] + ); + + const currentDateStyle = useMemo( + () => ({ + ...circleStyle, + backgroundColor: "#4184f2", + }), + [circleStyle] + ); + + const renderDate = useCallback( + (date: Date) => { + const isCurrentDate = isSameDate(todaysDate, date); + const appliedStyle = isCurrentDate ? currentDateStyle : defaultStyle; + + return ( + + + + {date.getDate()} + + + + ); + }, + [todaysDate, currentDateStyle, defaultStyle] // dependencies + ); + + return renderDate(date); + }; + + useEffect(() => { + setOffsetMinutes(getTotalMinutes()); + }, [events, mode]); + + if (isLoading || isRendering) { + return ( + + + + ); } - }, - [setEditVisible, setEventForEdit, mode] - ); - const handlePressCell = useCallback( - (date: Date) => { - if (mode === "day" || mode === "week") { - setSelectedNewEndDate(date); - } else { - setMode("day"); - setSelectedDate(date); - } - }, - [mode, setSelectedNewEndDate, setSelectedDate] - ); - - const handleSwipeEnd = useCallback( - (date: Date) => { - setSelectedDate(date); - }, - [setSelectedDate] - ); - - const memoizedEventCellStyle = useCallback( - (event: CalendarEvent) => ({ backgroundColor: event.eventColor }), - [] - ); - - const memoizedWeekStartsOn = useMemo( - () => (profileData?.firstDayOfWeek === "Mondays" ? 1 : 0), - [profileData] - ); - - useEffect(() => { - setActiveDate(new Date()); - - const interval = setInterval(() => setActiveDate(new Date()), 60000); - return () => clearInterval(interval); - }, []); - - const dayHeaderColor = useMemo(() => { - const isSameDate = - activeDate.getDate() === selectedDate.getDate() && - activeDate.getMonth() === selectedDate.getMonth() && - activeDate.getFullYear() === selectedDate.getFullYear(); - - return isSameDate && mode === "day" ? "white" : "#4d4d4d"; - }, [selectedDate, mode, activeDate]); - - const dateStyle = useMemo(() => { - const isSameDate = - activeDate.getDate() === selectedDate.getDate() && - activeDate.getMonth() === selectedDate.getMonth() && - activeDate.getFullYear() === selectedDate.getFullYear(); - - return isSameDate && mode === "day" - ? styles.dayHeader - : styles.otherDayHeader; - }, [selectedDate, mode, activeDate]); - - const memoizedHeaderContentStyle = useMemo(() => { - if (mode === "day") { - return styles.dayModeHeader; - } else if (mode === "week") { - return styles.weekModeHeader; - } else if (mode === "month") { - return styles.monthModeHeader; - } else { - return {}; - } - }, [mode]); - - const memoizedEvents = useMemo(() => events ?? [], [events]); - - useEffect(() => { - setOffsetMinutes(getTotalMinutes()); - }, [events, mode]); - - if (isLoading || isRendering) { - return ( - - - - ); + return ( + + ); } - - return ( - - ); - } ); const styles = StyleSheet.create({ - segmentslblStyle: { - fontSize: 12, - fontFamily: "Manrope_600SemiBold", - }, - calHeader: { - borderWidth: 0, - }, - dayModeHeader: { - alignSelf: "flex-start", - justifyContent: "space-between", - alignContent: "center", - width: 38, - right: 42, - height: 13, - }, - weekModeHeader: {}, - monthModeHeader: {}, - loadingContainer: { - flex: 1, - justifyContent: "center", - alignItems: "center", - }, - dayHeader: { - backgroundColor: "#4184f2", - aspectRatio: 1, - borderRadius: 100, - alignItems: "center", - justifyContent: "center", - }, - otherDayHeader: { - backgroundColor: "transparent", - color: "#919191", - aspectRatio: 1, - borderRadius: 100, - alignItems: "center", - justifyContent: "center", - }, + segmentslblStyle: { + fontSize: 12, + fontFamily: "Manrope_600SemiBold", + }, + calHeader: { + borderWidth: 0, + }, + dayModeHeader: { + alignSelf: "flex-start", + justifyContent: "space-between", + alignContent: "center", + width: 38, + right: 42, + height: 13, + }, + weekModeHeader: {}, + monthModeHeader: {}, + loadingContainer: { + flex: 1, + justifyContent: "center", + alignItems: "center", + }, + dayHeader: { + backgroundColor: "#4184f2", + aspectRatio: 1, + borderRadius: 100, + alignItems: "center", + justifyContent: "center", + }, + otherDayHeader: { + backgroundColor: "transparent", + color: "#919191", + aspectRatio: 1, + borderRadius: 100, + alignItems: "center", + justifyContent: "center", + }, }); diff --git a/ios/cally/Info.plist b/ios/cally/Info.plist index 468c1d5..15f9fca 100644 --- a/ios/cally/Info.plist +++ b/ios/cally/Info.plist @@ -118,6 +118,7 @@ $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route + $(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route UILaunchStoryboardName SplashScreen