Syncing rework

This commit is contained in:
Milan Paunovic
2024-11-26 21:13:54 +01:00
parent 5cfdc84055
commit f2af60111b
14 changed files with 960 additions and 595 deletions

View File

@ -1,51 +1,82 @@
import {useQuery} from "react-query";
import {useQuery, useQueryClient} from "react-query";
import firestore from "@react-native-firebase/firestore";
import {useAuthContext} from "@/contexts/AuthContext";
import {useAtomValue} from "jotai";
import {isFamilyViewAtom} from "@/components/pages/calendar/atoms";
import {colorMap} from "@/constants/colorMap";
import {uuidv4} from "@firebase/util";
import {useEffect} from "react";
export const useGetEvents = () => {
const {user, profileData} = useAuthContext();
const isFamilyView = useAtomValue(isFamilyViewAtom);
const queryClient = useQueryClient();
useEffect(() => {
if (!profileData?.familyId) return;
console.log(`[SYNC] Setting up sync listener for family: ${profileData.familyId}`);
const unsubscribe = firestore()
.collection('Households')
.where("familyId", "==", profileData.familyId)
.onSnapshot((snapshot) => {
snapshot.docChanges().forEach((change) => {
if (change.type === 'modified') {
const data = change.doc.data();
if (data?.lastSyncTimestamp) {
console.log(`[SYNC] Change detected at ${data.lastSyncTimestamp.toDate()}`);
console.log(`[SYNC] Household ${change.doc.id} triggered refresh`);
queryClient.invalidateQueries(["events", user?.uid, isFamilyView]);
}
}
});
}, (error) => {
console.error('[SYNC] Listener error:', error);
});
return () => {
console.log('[SYNC] Cleaning up sync listener');
unsubscribe();
};
}, [profileData?.familyId, user?.uid, isFamilyView, queryClient]);
return useQuery({
queryKey: ["events", user?.uid, isFamilyView],
queryFn: async () => {
console.log(`Fetching events - Family View: ${isFamilyView}, User: ${user?.uid}`);
const db = firestore();
const userId = user?.uid;
const familyId = profileData?.familyId;
let allEvents = [];
if (isFamilyView) {
// Get public family events
const publicFamilyEvents = await db.collection("Events")
.where("familyId", "==", familyId)
.where("private", "==", false)
.get();
// Get private events where user is creator
const privateCreatorEvents = await db.collection("Events")
.where("familyId", "==", familyId)
.where("private", "==", true)
.where("creatorId", "==", userId)
.get();
// Get private events where user is attendee
const privateAttendeeEvents = await db.collection("Events")
.where("private", "==", true)
.where("attendees", "array-contains", userId)
.get();
console.log(`Found ${publicFamilyEvents.size} public events, ${privateCreatorEvents.size} private creator events, ${privateAttendeeEvents.size} private attendee events`);
allEvents = [
...publicFamilyEvents.docs.map(doc => doc.data()),
...privateCreatorEvents.docs.map(doc => doc.data()),
...privateAttendeeEvents.docs.map(doc => doc.data())
...publicFamilyEvents.docs.map(doc => ({...doc.data(), id: doc.id})),
...privateCreatorEvents.docs.map(doc => ({...doc.data(), id: doc.id})),
...privateAttendeeEvents.docs.map(doc => ({...doc.data(), id: doc.id}))
];
} else {
// Personal view: Only show events where user is creator or attendee
const [creatorEvents, attendeeEvents] = await Promise.all([
db.collection("Events")
.where("creatorId", "==", userId)
@ -55,24 +86,28 @@ export const useGetEvents = () => {
.get()
]);
console.log(`Found ${creatorEvents.size} creator events, ${attendeeEvents.size} attendee events`);
allEvents = [
...creatorEvents.docs.map(doc => doc.data()),
...attendeeEvents.docs.map(doc => doc.data())
...creatorEvents.docs.map(doc => ({...doc.data(), id: doc.id})),
...attendeeEvents.docs.map(doc => ({...doc.data(), id: doc.id}))
];
}
// Ensure uniqueness
const uniqueEventsMap = new Map();
allEvents.forEach(event => {
if (event.id) {
uniqueEventsMap.set(event.id, event);
} else {
uniqueEventsMap.set(uuidv4(), event);
const newId = uuidv4();
console.log(`Generated new ID for event without ID: ${newId}`);
uniqueEventsMap.set(newId, {...event, id: newId});
}
});
// Map events with creator colors
return await Promise.all(
console.log(`Processing ${uniqueEventsMap.size} unique events`);
const processedEvents = await Promise.all(
Array.from(uniqueEventsMap.values()).map(async (event) => {
const profileSnapshot = await db
.collection("Profiles")
@ -96,9 +131,15 @@ export const useGetEvents = () => {
};
})
);
console.log(`Events processing completed, returning ${processedEvents.length} events`);
return processedEvents;
},
staleTime: Infinity,
cacheTime: Infinity,
staleTime: 5 * 60 * 1000,
cacheTime: 30 * 60 * 1000,
keepPreviousData: true,
onError: (error) => {
console.error('Error fetching events:', error);
}
});
};
};