From 10f6616cd007bdf4c3a7ab90769f0cecbea5e9b9 Mon Sep 17 00:00:00 2001 From: Milan Paunovic Date: Tue, 24 Dec 2024 16:07:18 +0100 Subject: [PATCH] Deletion fix --- .../pages/calendar/DetailedCalendar.tsx | 25 ++++--- components/pages/calendar/EventCalendar.tsx | 4 +- .../pages/calendar/useFormattedEvents.ts | 2 +- contexts/AuthContext.tsx | 6 +- firebase/functions/index.js | 2 +- hooks/firebase/useDeleteEvent.ts | 75 +++++++++++++------ hooks/firebase/useGetEvents.ts | 2 +- 7 files changed, 78 insertions(+), 38 deletions(-) diff --git a/components/pages/calendar/DetailedCalendar.tsx b/components/pages/calendar/DetailedCalendar.tsx index 2b05911..2cd4260 100644 --- a/components/pages/calendar/DetailedCalendar.tsx +++ b/components/pages/calendar/DetailedCalendar.tsx @@ -9,14 +9,16 @@ import {useFormattedEvents} from "@/components/pages/calendar/useFormattedEvents import {useCalendarControls} from "@/components/pages/calendar/useCalendarControls"; import {EventCell} from "@/components/pages/calendar/EventCell"; import {isToday} from "date-fns"; -import { View } from "react-native-ui-lib"; +import {View} from "react-native-ui-lib"; interface EventCalendarProps { calendarHeight: number; calendarWidth: number; } -export const DetailedCalendar: React.FC = ({calendarHeight, calendarWidth}) => { +const MemoizedEventCell = React.memo(EventCell); + +export const DetailedCalendar: React.FC = React.memo(({calendarHeight, calendarWidth}) => { const {profileData} = useAuthContext(); const selectedDate = useAtomValue(selectedDateAtom); const mode = useAtomValue(modeAtom); @@ -58,20 +60,21 @@ export const DetailedCalendar: React.FC = ({calendarHeight, initialDate: selectedDate.toISOString(), }), [selectedDate]); + const getAttendees = useCallback((event: any) => { + return familyMembers?.filter(member => event?.attendees?.includes(member?.uid!)) || []; + }, [familyMembers]); + const renderEvent = useCallback((event: any) => { - const attendees = useMemo(() => - familyMembers?.filter(member => event?.attendees?.includes(member?.uid!)) || [], - [familyMembers, event.attendees] - ); + const attendees = getAttendees(event); return ( - ); - }, [familyMembers, handlePressEvent]); + }, [familyMembers, handlePressEvent, getAttendees]); useEffect(() => { if (selectedDate && isToday(selectedDate)) { @@ -85,12 +88,12 @@ export const DetailedCalendar: React.FC = ({calendarHeight, {...containerProps} numberOfDays={numberOfDays} calendarWidth={calendarWidth} - onDateChanged={debouncedOnDateChanged} firstDay={firstDay} events={formattedEvents ?? []} onPressEvent={handlePressEvent} onPressBackground={handlePressCell} + > = ({calendarHeight, ); -}; +}); + +DetailedCalendar.displayName = 'DetailedCalendar'; export default DetailedCalendar; \ No newline at end of file diff --git a/components/pages/calendar/EventCalendar.tsx b/components/pages/calendar/EventCalendar.tsx index fb04fb5..55d7ff2 100644 --- a/components/pages/calendar/EventCalendar.tsx +++ b/components/pages/calendar/EventCalendar.tsx @@ -9,7 +9,7 @@ import { modeAtom, } from './atoms'; import {MonthCalendar} from "@/components/pages/calendar/MonthCalendar"; -import {DetailedCalendar} from "@/components/pages/calendar/DetailedCalendar"; +import DetailedCalendar from "@/components/pages/calendar/DetailedCalendar"; interface EventCalendarProps { calendarHeight: number; @@ -17,7 +17,7 @@ interface EventCalendarProps { } export const EventCalendar: React.FC = React.memo((props) => { - const {data: events, isLoading} = useGetEvents(); + const {isLoading} = useGetEvents(); const [mode] = useAtom(modeAtom); const {isSyncing} = useSyncEvents(); useCalSync(); diff --git a/components/pages/calendar/useFormattedEvents.ts b/components/pages/calendar/useFormattedEvents.ts index d61ea74..65597f8 100644 --- a/components/pages/calendar/useFormattedEvents.ts +++ b/components/pages/calendar/useFormattedEvents.ts @@ -31,7 +31,7 @@ interface FormattedEvent { // Precompute time constants const DAY_IN_MS = 24 * 60 * 60 * 1000; -const PERIOD_IN_MS = 45 * DAY_IN_MS; +const PERIOD_IN_MS = 5 * DAY_IN_MS; const TIME_ZONE = Intl.DateTimeFormat().resolvedOptions().timeZone; // Memoize date range calculations diff --git a/contexts/AuthContext.tsx b/contexts/AuthContext.tsx index 6dff1c3..6247b2b 100644 --- a/contexts/AuthContext.tsx +++ b/contexts/AuthContext.tsx @@ -152,7 +152,11 @@ export const AuthContextProvider: FC<{ children: ReactNode }> = ({children}) => useEffect(() => { if (!initializing) { - SplashScreen.hideAsync(); + if(auth().currentUser) { + setTimeout(() => SplashScreen.hideAsync(), 1000); + } else { + SplashScreen.hideAsync(); + } } }, [initializing]); diff --git a/firebase/functions/index.js b/firebase/functions/index.js index 637fe20..2f13915 100644 --- a/firebase/functions/index.js +++ b/firebase/functions/index.js @@ -333,7 +333,7 @@ exports.processEventBatches = functions.pubsub let notificationMessage; if (externalOrigin) { - notificationMessage = `Calendar sync completed: ${events.length} ${events.length === 1 ? 'event has' : 'events have'} been added.`; + // notificationMessage = `Calendar sync completed: ${events.length} ${events.length === 1 ? 'event has' : 'events have'} been added.`; } else { notificationMessage = events.length === 1 ? `New event "${events[0].title}" has been added to the family calendar.` diff --git a/hooks/firebase/useDeleteEvent.ts b/hooks/firebase/useDeleteEvent.ts index 9d8c83c..f696dcd 100644 --- a/hooks/firebase/useDeleteEvent.ts +++ b/hooks/firebase/useDeleteEvent.ts @@ -1,39 +1,70 @@ import {useMutation, useQueryClient} from "@tanstack/react-query"; import firestore from "@react-native-firebase/firestore"; +import {useAuthContext} from "@/contexts/AuthContext"; export const useDeleteEvent = () => { + const {user, profileData} = useAuthContext(); const queryClient = useQueryClient(); return useMutation({ mutationKey: ["deleteEvent"], mutationFn: async ({eventId, docId}: { eventId?: string; docId?: string }) => { try { - if (docId) { - await firestore() - .collection("Events") - .doc(docId) - .delete(); - } else if (eventId) { - const snapshot = await firestore() - .collection("Events") - .where("id", "==", eventId) - .get(); - - const doc = snapshot.docs[0]; - if (doc) { - await doc.ref.delete(); - } else { - console.warn("Event not found"); - } - } else { - console.warn("No identifier provided"); - } + await firestore() + .collection("Events") + .doc(eventId ?? docId) + .delete(); } catch (e) { console.error(e); + throw e; } }, - onSuccess: () => { - queryClient.invalidateQueries({queryKey: ["events"]}); + onMutate: async ({eventId, docId}) => { + await queryClient.cancelQueries({ + queryKey: ["events", user?.uid] + }); + + const previousPersonalEvents = queryClient.getQueryData(["events", user?.uid, false]); + const previousFamilyEvents = queryClient.getQueryData(["events", user?.uid, true]); + + const updateQueryData = (old: any[] | undefined) => + old?.filter(event => event.id !== (eventId ?? docId)); + + queryClient.setQueryData( + ["events", user?.uid, false], + updateQueryData + ); + queryClient.setQueryData( + ["events", user?.uid, true], + updateQueryData + ); + + return {previousPersonalEvents, previousFamilyEvents}; + }, + onError: (err, variables, context) => { + queryClient.setQueryData( + ["events", user?.uid, false], + context?.previousPersonalEvents + ); + queryClient.setQueryData( + ["events", user?.uid, true], + context?.previousFamilyEvents + ); + }, + onSettled: () => { + if (profileData?.familyId) { + firestore() + .collection("Households") + .where("familyId", "==", profileData.familyId) + .get() + .then(snapshot => { + snapshot.docs.forEach(doc => { + doc.ref.update({ + lastSyncTimestamp: firestore.FieldValue.serverTimestamp() + }); + }); + }); + } } }); }; \ No newline at end of file diff --git a/hooks/firebase/useGetEvents.ts b/hooks/firebase/useGetEvents.ts index b7114e0..b534a9c 100644 --- a/hooks/firebase/useGetEvents.ts +++ b/hooks/firebase/useGetEvents.ts @@ -139,7 +139,7 @@ export const useGetEvents = () => { return useQuery({ queryKey: ["events", user?.uid, isFamilyView], queryFn: () => fetchEvents(user?.uid!, profileData?.familyId, isFamilyView), - staleTime: 5 * 60 * 1000, + staleTime: Infinity, gcTime: Infinity, placeholderData: (previousData) => previousData, enabled: Boolean(user?.uid),