mirror of
https://github.com/urosran/cally.git
synced 2025-07-14 17:25:46 +00:00
Syncing rework
This commit is contained in:
@ -1,107 +1,37 @@
|
||||
import { useMutation, useQueryClient } from "react-query";
|
||||
import { fetchGoogleCalendarEvents } from "@/calendar-integration/google-calendar-utils";
|
||||
import { useAuthContext } from "@/contexts/AuthContext";
|
||||
import { useCreateEventsFromProvider } from "@/hooks/firebase/useCreateEvent";
|
||||
import { useClearTokens } from "@/hooks/firebase/useClearTokens";
|
||||
import { useUpdateUserData } from "@/hooks/firebase/useUpdateUserData";
|
||||
import {useMutation, useQueryClient} from "react-query";
|
||||
import {useAuthContext} from "@/contexts/AuthContext";
|
||||
import functions from "@react-native-firebase/functions";
|
||||
|
||||
interface SyncResponse {
|
||||
success: boolean;
|
||||
eventCount: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export const useFetchAndSaveGoogleEvents = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const { profileData } = useAuthContext();
|
||||
const { mutateAsync: createEventsFromProvider } = useCreateEventsFromProvider();
|
||||
const { mutateAsync: clearToken } = useClearTokens();
|
||||
const { mutateAsync: updateUserData } = useUpdateUserData();
|
||||
|
||||
return useMutation({
|
||||
mutationKey: ["fetchAndSaveGoogleEvents", "sync"],
|
||||
mutationFn: async ({ token, email, date, refreshToken }: { token?: string; refreshToken?: string; email?: string; date?: Date }) => {
|
||||
const baseDate = date || new Date();
|
||||
const timeMin = new Date(baseDate.setMonth(baseDate.getMonth() - 1)).toISOString().slice(0, -5) + "Z";
|
||||
const timeMax = new Date(baseDate.setMonth(baseDate.getMonth() + 2)).toISOString().slice(0, -5) + "Z";
|
||||
mutationFn: async ({ email }: { email?: string }) => {
|
||||
if (!email || !profileData?.googleAccounts?.[email]) {
|
||||
throw new Error("No valid Google account found");
|
||||
}
|
||||
|
||||
console.log("Token: ", token);
|
||||
try {
|
||||
const response = await functions()
|
||||
.httpsCallable('triggerGoogleSync')({ email });
|
||||
|
||||
const tryFetchEvents = async (isRetry = false) => {
|
||||
try {
|
||||
const response = await fetchGoogleCalendarEvents(
|
||||
token,
|
||||
email,
|
||||
profileData?.familyId,
|
||||
timeMin,
|
||||
timeMax
|
||||
);
|
||||
|
||||
if (!response.success) {
|
||||
await clearToken({ email: email!, provider: "google" });
|
||||
return; // Stop refetching if clearing the token
|
||||
}
|
||||
|
||||
console.log("Google Calendar events fetched:", response);
|
||||
|
||||
const items = response?.googleEvents?.map((item) => {
|
||||
if (item.allDay) {
|
||||
item.startDate = new Date(item.startDate.setHours(0, 0, 0, 0));
|
||||
item.endDate = item.startDate;
|
||||
}
|
||||
return item;
|
||||
}) || [];
|
||||
|
||||
await createEventsFromProvider(items);
|
||||
} catch (error) {
|
||||
console.error("Error fetching Google Calendar events:", error);
|
||||
|
||||
if (!isRetry) {
|
||||
const refreshedToken = await handleRefreshToken(email, refreshToken);
|
||||
if (refreshedToken) {
|
||||
await updateUserData({
|
||||
newUserData: {
|
||||
googleAccounts: {
|
||||
...profileData.googleAccounts,
|
||||
[email!]: { ...profileData.googleAccounts[email!], accessToken: refreshedToken },
|
||||
},
|
||||
},
|
||||
});
|
||||
return tryFetchEvents(true); // Retry once after refreshing
|
||||
} else {
|
||||
await clearToken({ email: email!, provider: "google" });
|
||||
console.error(`Token refresh failed; token cleared for ${email}`);
|
||||
throw error;
|
||||
}
|
||||
} else {
|
||||
console.error(`Retry failed after refreshing token for user ${profileData?.email}:`, error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return tryFetchEvents();
|
||||
return response.data as SyncResponse;
|
||||
} catch (error: any) {
|
||||
console.error("Error initiating Google Calendar sync:", error);
|
||||
throw new Error(error.details?.message || error.message || "Failed to sync calendar");
|
||||
}
|
||||
},
|
||||
onSuccess: () => {
|
||||
onSuccess: (data) => {
|
||||
queryClient.invalidateQueries(["events"]);
|
||||
},
|
||||
console.log(`Successfully synced ${data.eventCount} events`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
async function handleRefreshToken(email: string, refreshToken: string) {
|
||||
if (!refreshToken) return null;
|
||||
|
||||
try {
|
||||
const response = await fetch('https://oauth2.googleapis.com/token', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: refreshToken,
|
||||
client_id: "406146460310-2u67ab2nbhu23trp8auho1fq4om29fc0.apps.googleusercontent.com",
|
||||
}),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
return data.access_token;
|
||||
} catch (error) {
|
||||
console.error("Error refreshing Google token:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user