mirror of
https://github.com/urosran/cally.git
synced 2025-07-16 01:56:16 +00:00
- Implemented connecting multiple accounts for google
This commit is contained in:
@ -90,8 +90,11 @@ const CalendarSettingsPage = (props: {
|
|||||||
const userInfo = await userInfoResponse.json();
|
const userInfo = await userInfoResponse.json();
|
||||||
const googleMail = userInfo.email;
|
const googleMail = userInfo.email;
|
||||||
|
|
||||||
|
let googleAccounts = profileData?.googleAccounts;
|
||||||
|
const updatedGoogleAccounts = googleAccounts ? {...googleAccounts, [googleMail]: accessToken} : {[googleMail]: accessToken};
|
||||||
|
|
||||||
await updateUserData({
|
await updateUserData({
|
||||||
newUserData: {googleToken: accessToken, googleMail: googleMail},
|
newUserData: {googleAccounts: updatedGoogleAccounts},
|
||||||
});
|
});
|
||||||
|
|
||||||
await fetchAndSaveGoogleEvents({token: accessToken, email: googleMail})
|
await fetchAndSaveGoogleEvents({token: accessToken, email: googleMail})
|
||||||
@ -263,11 +266,14 @@ const CalendarSettingsPage = (props: {
|
|||||||
debouncedUpdateUserData(color);
|
debouncedUpdateUserData(color);
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearToken = async (provider: "google" | "outlook" | "apple") => {
|
const clearToken = async (provider: "google" | "outlook" | "apple", email: string) => {
|
||||||
const newUserData: Partial<UserProfile> = {};
|
const newUserData: Partial<UserProfile> = {};
|
||||||
if (provider === "google") {
|
if (provider === "google") {
|
||||||
newUserData.googleToken = null;
|
let googleAccounts = profileData?.googleAccounts;
|
||||||
newUserData.googleMail = null;
|
if (googleAccounts) {
|
||||||
|
googleAccounts[email] = null;
|
||||||
|
newUserData.googleAccounts = googleAccounts;
|
||||||
|
}
|
||||||
} else if (provider === "outlook") {
|
} else if (provider === "outlook") {
|
||||||
newUserData.microsoftToken = null;
|
newUserData.microsoftToken = null;
|
||||||
newUserData.outlookMail = null;
|
newUserData.outlookMail = null;
|
||||||
@ -278,6 +284,16 @@ const CalendarSettingsPage = (props: {
|
|||||||
await updateUserData({newUserData});
|
await updateUserData({newUserData});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let isConnectedToGoogle = false;
|
||||||
|
if (profileData?.googleAccounts) {
|
||||||
|
Object.values(profileData?.googleAccounts).forEach((item) => {
|
||||||
|
if (item !== null) {
|
||||||
|
isConnectedToGoogle = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollView>
|
<ScrollView>
|
||||||
<View marginH-30 marginB-30>
|
<View marginH-30 marginB-30>
|
||||||
@ -378,8 +394,8 @@ const CalendarSettingsPage = (props: {
|
|||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onPress={() => !profileData?.googleToken ? promptAsync() : clearToken("google")}
|
onPress={() => promptAsync()}
|
||||||
label={profileData?.googleToken ? `Disconnect ${profileData.googleMail}` : "Connect Google"}
|
label={"Connect Google"}
|
||||||
labelStyle={styles.addCalLbl}
|
labelStyle={styles.addCalLbl}
|
||||||
labelProps={{
|
labelProps={{
|
||||||
numberOfLines: 2
|
numberOfLines: 2
|
||||||
@ -393,8 +409,29 @@ const CalendarSettingsPage = (props: {
|
|||||||
color="black"
|
color="black"
|
||||||
text70BL
|
text70BL
|
||||||
/>
|
/>
|
||||||
|
{profileData?.googleAccounts ? Object.keys(profileData?.googleAccounts)?.map((googleMail) => {
|
||||||
|
const googleToken = profileData?.googleAccounts?.[googleMail];
|
||||||
|
return googleToken && <Button
|
||||||
|
key={googleMail}
|
||||||
|
onPress={() => clearToken("google", googleMail)}
|
||||||
|
label={`Disconnect ${googleMail}`}
|
||||||
|
labelStyle={styles.addCalLbl}
|
||||||
|
labelProps={{
|
||||||
|
numberOfLines: 2
|
||||||
|
}}
|
||||||
|
iconSource={() => (
|
||||||
|
<View marginR-15>
|
||||||
|
<GoogleIcon/>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
style={styles.addCalBtn}
|
||||||
|
color="black"
|
||||||
|
text70BL
|
||||||
|
/>
|
||||||
|
}) : null}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onPress={() => !profileData?.appleToken ? handleAppleSignIn() : clearToken("google")}
|
onPress={() => !profileData?.appleToken ? handleAppleSignIn() : clearToken("apple")}
|
||||||
label={profileData?.appleToken ? `Disconnect ${profileData.appleMail}` : "Connect Apple"}
|
label={profileData?.appleToken ? `Disconnect ${profileData.appleMail}` : "Connect Apple"}
|
||||||
labelStyle={styles.addCalLbl}
|
labelStyle={styles.addCalLbl}
|
||||||
labelProps={{
|
labelProps={{
|
||||||
@ -426,7 +463,7 @@ const CalendarSettingsPage = (props: {
|
|||||||
text70BL
|
text70BL
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{(profileData?.googleMail || profileData?.outlookMail || profileData?.appleMail) && (
|
{(isConnectedToGoogle || profileData?.outlookMail || profileData?.appleMail) && (
|
||||||
<>
|
<>
|
||||||
<Text style={styles.subTitle} marginT-30 marginB-20>
|
<Text style={styles.subTitle} marginT-30 marginB-20>
|
||||||
Connected Calendars
|
Connected Calendars
|
||||||
@ -434,41 +471,38 @@ const CalendarSettingsPage = (props: {
|
|||||||
|
|
||||||
<View style={styles.noPaddingCard}>
|
<View style={styles.noPaddingCard}>
|
||||||
<View style={{marginTop: 20}}>
|
<View style={{marginTop: 20}}>
|
||||||
{!!profileData?.googleMail && (
|
{Object.keys(profileData?.googleAccounts)?.map((googleEmail) => {
|
||||||
<TouchableOpacity
|
const googleToken = profileData?.googleAccounts?.[googleEmail];
|
||||||
onPress={() => fetchAndSaveGoogleEvents({
|
return googleToken && (
|
||||||
token: profileData?.googleToken!,
|
<TouchableOpacity
|
||||||
email: profileData?.googleMail!
|
onPress={() => fetchAndSaveGoogleEvents({token: googleToken, email: googleEmail})}
|
||||||
})}
|
>
|
||||||
>
|
<View row paddingR-20 center>
|
||||||
<View row paddingR-20 center>
|
<Button
|
||||||
<Button
|
disabled={isSyncingGoogle}
|
||||||
disabled={isSyncingGoogle}
|
onPress={() => fetchAndSaveGoogleEvents({token: googleToken, email: googleEmail})}
|
||||||
onPress={() => fetchAndSaveGoogleEvents({
|
label={`Sync ${googleEmail}`}
|
||||||
token: profileData?.googleToken!,
|
labelStyle={styles.addCalLbl}
|
||||||
email: profileData?.googleMail!
|
labelProps={{numberOfLines: 3}}
|
||||||
})}
|
iconSource={() => (
|
||||||
label={`Sync ${profileData?.googleMail}`}
|
<View marginR-15>
|
||||||
labelStyle={styles.addCalLbl}
|
<GoogleIcon/>
|
||||||
labelProps={{numberOfLines: 3}}
|
</View>
|
||||||
iconSource={() => (
|
)}
|
||||||
<View marginR-15>
|
style={styles.addCalBtn}
|
||||||
<GoogleIcon/>
|
color="black"
|
||||||
</View>
|
text70BL
|
||||||
)}
|
/>
|
||||||
style={styles.addCalBtn}
|
|
||||||
color="black"
|
|
||||||
text70BL
|
|
||||||
/>
|
|
||||||
|
|
||||||
{isSyncingGoogle ? (
|
{isSyncingGoogle ? (
|
||||||
<ActivityIndicator/>
|
<ActivityIndicator/>
|
||||||
) : (
|
) : (
|
||||||
<Ionicons name={"refresh"} size={20} color={"#000000"}/>
|
<Ionicons name={"refresh"} size={20} color={"#000000"}/>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
)}
|
)
|
||||||
|
})}
|
||||||
|
|
||||||
|
|
||||||
{!!profileData?.appleMail && (
|
{!!profileData?.appleMail && (
|
||||||
|
@ -188,11 +188,17 @@ exports.refreshTokens = functions.pubsub.schedule('every 12 hours').onRun(async
|
|||||||
profilesSnapshot.forEach(async (profileDoc) => {
|
profilesSnapshot.forEach(async (profileDoc) => {
|
||||||
const profileData = profileDoc.data();
|
const profileData = profileDoc.data();
|
||||||
|
|
||||||
if (profileData.googleToken) {
|
if (profileData.googleAccounts) {
|
||||||
try {
|
try {
|
||||||
const refreshedGoogleToken = await refreshGoogleToken(profileData.googleToken);
|
for (const googleEmail of Object.keys(profileData?.googleAccounts)) {
|
||||||
await profileDoc.ref.update({googleToken: refreshedGoogleToken});
|
const googleToken = profileData?.googleAccounts?.[googleEmail];
|
||||||
console.log(`Google token updated for user ${profileDoc.id}`);
|
if (googleToken) {
|
||||||
|
const refreshedGoogleToken = await refreshGoogleToken(googleToken);
|
||||||
|
const updatedGoogleAccounts = {...profileData.googleAccounts, [googleEmail]: refreshedGoogleToken};
|
||||||
|
await profileDoc.ref.update({googleAccounts: updatedGoogleAccounts});
|
||||||
|
console.log(`Google token updated for user ${profileDoc.id}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error refreshing Google token for user ${profileDoc.id}:`, error.message);
|
console.error(`Error refreshing Google token for user ${profileDoc.id}:`, error.message);
|
||||||
}
|
}
|
||||||
|
@ -18,15 +18,14 @@ export interface UserProfile {
|
|||||||
familyId?: string;
|
familyId?: string;
|
||||||
uid?: string;
|
uid?: string;
|
||||||
pfp?: string;
|
pfp?: string;
|
||||||
googleToken?: string | null;
|
|
||||||
microsoftToken?: string | null;
|
microsoftToken?: string | null;
|
||||||
appleToken?: string | null;
|
appleToken?: string | null;
|
||||||
eventColor?: string | null;
|
eventColor?: string | null;
|
||||||
googleMail?: string | null;
|
|
||||||
outlookMail?: string | null;
|
outlookMail?: string | null;
|
||||||
appleMail?: string | null;
|
appleMail?: string | null;
|
||||||
timeZone?: string | null;
|
timeZone?: string | null;
|
||||||
firstDayOfWeek?: string | null;
|
firstDayOfWeek?: string | null;
|
||||||
|
googleAccounts?: Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ParentProfile extends UserProfile {
|
export interface ParentProfile extends UserProfile {
|
||||||
|
@ -14,12 +14,12 @@ export const useFetchAndSaveGoogleEvents = () => {
|
|||||||
const timeMin = new Date(new Date().setFullYear(new Date().getFullYear() - 1));
|
const timeMin = new Date(new Date().setFullYear(new Date().getFullYear() - 1));
|
||||||
const timeMax = new Date(new Date().setFullYear(new Date().getFullYear() + 5));
|
const timeMax = new Date(new Date().setFullYear(new Date().getFullYear() + 5));
|
||||||
|
|
||||||
console.log("Token: ", token ?? profileData?.googleToken);
|
console.log("Token: ", token);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetchGoogleCalendarEvents(
|
const response = await fetchGoogleCalendarEvents(
|
||||||
token ?? profileData?.googleToken,
|
token,
|
||||||
email ?? profileData?.googleMail,
|
email,
|
||||||
profileData?.familyId,
|
profileData?.familyId,
|
||||||
timeMin.toISOString().slice(0, -5) + "Z",
|
timeMin.toISOString().slice(0, -5) + "Z",
|
||||||
timeMax.toISOString().slice(0, -5) + "Z"
|
timeMax.toISOString().slice(0, -5) + "Z"
|
||||||
|
Reference in New Issue
Block a user