mirror of
https://github.com/urosran/cally.git
synced 2025-07-10 07:07:16 +00:00
Microsoft sync added
This commit is contained in:
@ -29,6 +29,7 @@
|
||||
<data android:scheme="myapp"/>
|
||||
<data android:scheme="com.cally.app"/>
|
||||
<data android:scheme="exp+cally"/>
|
||||
<data android:scheme="callyplanner"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false"/>
|
||||
|
2
app.json
2
app.json
@ -5,7 +5,7 @@
|
||||
"version": "1.0.0",
|
||||
"orientation": "portrait",
|
||||
"icon": "./assets/images/icon.png",
|
||||
"scheme": "myapp",
|
||||
"scheme": "callyplanner",
|
||||
"userInterfaceStyle": "light",
|
||||
"splash": {
|
||||
"image": "./assets/images/splash.png",
|
||||
|
@ -10,6 +10,8 @@ export async function fetchMicrosoftCalendarEvents(token, startDate, endDate) {
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
console.log(data, startDate, endDate)
|
||||
|
||||
const microsoftEvents = [];
|
||||
data?.value?.forEach((item) => {
|
||||
const start = item.start;
|
||||
@ -33,6 +35,8 @@ export async function fetchMicrosoftCalendarEvents(token, startDate, endDate) {
|
||||
endDate: endDateTime,
|
||||
allDay: item.isAllDay,
|
||||
};
|
||||
|
||||
|
||||
microsoftEvents.push(microsoftEvent);
|
||||
});
|
||||
|
||||
|
@ -16,11 +16,11 @@ import {
|
||||
} from "react-native-ui-lib";
|
||||
import { TouchableOpacity } from "react-native";
|
||||
import { ManuallyAddEventModal } from "@/components/pages/calendar/ManuallyAddEventModal";
|
||||
import AddChore from "../todos/AddChore";
|
||||
import AddChoreDialog from "../todos/AddChoreDialog";
|
||||
import { ToDosContextProvider } from "@/contexts/ToDosContext";
|
||||
import UploadImageDialog from "./UploadImageDialog";
|
||||
|
||||
|
||||
export const AddEventDialog = () => {
|
||||
const [show, setShow] = useState(false);
|
||||
const [showManualInputModal, setShowManualInputModal] = useState(false);
|
||||
|
@ -1,321 +1,371 @@
|
||||
import { AntDesign, Ionicons } from "@expo/vector-icons";
|
||||
import React, { useState } from "react";
|
||||
import { Button, Checkbox, Text, View } from "react-native-ui-lib";
|
||||
import { StyleSheet } from "react-native";
|
||||
import { colorMap } from "@/contexts/SettingsContext";
|
||||
import { TouchableOpacity } from "react-native-gesture-handler";
|
||||
import { fetchGoogleCalendarEvents } from "@/calendar-integration/google-calendar-utils";
|
||||
import { fetchMicrosoftCalendarEvents } from "@/calendar-integration/microsoft-calendar-utils";
|
||||
import { useCreateEventFromProvider } from "@/hooks/firebase/useCreateEvent";
|
||||
import { useAuthContext } from "@/contexts/AuthContext";
|
||||
import { useUpdateUserData } from "@/hooks/firebase/useUpdateUserData";
|
||||
import { GoogleSignin } from "@react-native-google-signin/google-signin";
|
||||
import { authorize } from "react-native-app-auth";
|
||||
import {AntDesign, Ionicons} from "@expo/vector-icons";
|
||||
import React, {useState} from "react";
|
||||
import {Button, Checkbox, Text, View} from "react-native-ui-lib";
|
||||
import {ScrollView, StyleSheet} from "react-native";
|
||||
import {colorMap} from "@/contexts/SettingsContext";
|
||||
import {TouchableOpacity} from "react-native-gesture-handler";
|
||||
import {fetchGoogleCalendarEvents} from "@/calendar-integration/google-calendar-utils";
|
||||
import {fetchMicrosoftCalendarEvents} from "@/calendar-integration/microsoft-calendar-utils";
|
||||
import {useCreateEventFromProvider} from "@/hooks/firebase/useCreateEvent";
|
||||
import {useAuthContext} from "@/contexts/AuthContext";
|
||||
import {useUpdateUserData} from "@/hooks/firebase/useUpdateUserData";
|
||||
import {GoogleSignin} from "@react-native-google-signin/google-signin";
|
||||
import * as AuthSession from "expo-auth-session";
|
||||
|
||||
GoogleSignin.configure({
|
||||
webClientId:
|
||||
"406146460310-hjadmfa1gg4ptaouira5rkhu0djlo5ut.apps.googleusercontent.com",
|
||||
scopes: ["profile", "email"], // Note: add calendar scope
|
||||
webClientId:
|
||||
"406146460310-hjadmfa1gg4ptaouira5rkhu0djlo5ut.apps.googleusercontent.com",
|
||||
scopes: ["profile", "email"], // Note: add calendar scope
|
||||
});
|
||||
|
||||
const GoogleLogin = async () => {
|
||||
return await GoogleSignin.signIn();
|
||||
return await GoogleSignin.signIn();
|
||||
};
|
||||
|
||||
const microsoftConfig = {
|
||||
issuer: "https://login.microsoftonline.com/common",
|
||||
clientId: "<your-client-id>", // Replace with your microsoft client id
|
||||
redirectUrl: "<your-redirect-uri>", // replace with your redirect uri added in microsoft portal
|
||||
scopes: ["openid", "profile", "email"], // Add calendar scope
|
||||
serviceConfiguration: {
|
||||
clientId: "13c79071-1066-40a9-9f71-b8c4b138b4af", // Replace with your Microsoft client ID
|
||||
redirectUri: AuthSession.makeRedirectUri({path: "settings"}), // Generate redirect URI automatically for Expo
|
||||
scopes: [
|
||||
"openid",
|
||||
"profile",
|
||||
"email",
|
||||
"offline_access",
|
||||
"Calendars.ReadWrite", // Scope for reading calendar events
|
||||
],
|
||||
authorizationEndpoint:
|
||||
"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
|
||||
tokenEndpoint: "https://login.microsoftonline.com/common/oauth2/v2.0/token",
|
||||
revocationEndpoint:
|
||||
"https://login.microsoftonline.com/common/oauth2/v2.0/logout",
|
||||
},
|
||||
useNonce: true,
|
||||
usePKCE: true, //For iOS, we have added the useNonce and usePKCE parameters, which are recommended for security reasons.
|
||||
additionalParameters: {
|
||||
prompt: "consent",
|
||||
},
|
||||
"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
|
||||
tokenEndpoint: "https://login.microsoftonline.com/common/oauth2/v2.0/token"
|
||||
};
|
||||
|
||||
const CalendarSettingsPage = (props: {
|
||||
setSelectedPage: (page: number) => void;
|
||||
setSelectedPage: (page: number) => void;
|
||||
}) => {
|
||||
const [selectedColor, setSelectedColor] = useState<string>(colorMap.pink);
|
||||
const [startDate, setStartDate] = useState<boolean>(true);
|
||||
const { profileData } = useAuthContext();
|
||||
const [selectedColor, setSelectedColor] = useState<string>(colorMap.pink);
|
||||
const [startDate, setStartDate] = useState<boolean>(true);
|
||||
const {profileData} = useAuthContext();
|
||||
|
||||
const { mutateAsync: createEventFromProvider } = useCreateEventFromProvider();
|
||||
const { mutateAsync: updateUserData } = useUpdateUserData();
|
||||
const {mutateAsync: createEventFromProvider} = useCreateEventFromProvider();
|
||||
const {mutateAsync: updateUserData} = useUpdateUserData();
|
||||
|
||||
const fetchAndSaveGoogleEvents = () => {
|
||||
const timeMin = new Date(new Date().setHours(0, 0, 0, 0));
|
||||
const timeMax = new Date(
|
||||
new Date(new Date().setHours(0, 0, 0, 0)).setDate(timeMin.getDate() + 30),
|
||||
);
|
||||
const fetchAndSaveGoogleEvents = () => {
|
||||
const timeMin = new Date(new Date().setHours(0, 0, 0, 0));
|
||||
const timeMax = new Date(
|
||||
new Date(new Date().setHours(0, 0, 0, 0)).setDate(timeMin.getDate() + 30)
|
||||
);
|
||||
|
||||
fetchGoogleCalendarEvents(
|
||||
profileData?.googleToken,
|
||||
timeMin.toISOString().slice(0, -5) + "Z",
|
||||
timeMax.toISOString().slice(0, -5) + "Z",
|
||||
).then((response) => {
|
||||
response?.forEach((item) => saveData(item));
|
||||
});
|
||||
};
|
||||
fetchGoogleCalendarEvents(
|
||||
profileData?.googleToken,
|
||||
timeMin.toISOString().slice(0, -5) + "Z",
|
||||
timeMax.toISOString().slice(0, -5) + "Z",
|
||||
).then((response) => {
|
||||
response?.forEach((item) => saveData(item));
|
||||
});
|
||||
};
|
||||
|
||||
async function saveData(item) {
|
||||
await createEventFromProvider(item);
|
||||
}
|
||||
async function saveData(item: any) {
|
||||
await createEventFromProvider(item);
|
||||
}
|
||||
|
||||
const fetchAndSaveMicrosoftEvents = () => {
|
||||
const startDateTime = new Date(new Date().setHours(0, 0, 0, 0));
|
||||
const endDateTime = new Date(
|
||||
new Date(new Date().setHours(0, 0, 0, 0)).setDate(
|
||||
startDateTime.getDate() + 30,
|
||||
),
|
||||
);
|
||||
const fetchAndSaveMicrosoftEvents = () => {
|
||||
const startDateTime = new Date(new Date().setHours(0, 0, 0, 0));
|
||||
const endDateTime = new Date(
|
||||
new Date(new Date().setHours(0, 0, 0, 0)).setDate(
|
||||
startDateTime.getDate() + 30
|
||||
)
|
||||
);
|
||||
|
||||
fetchMicrosoftCalendarEvents(
|
||||
profileData?.microsoftToken,
|
||||
startDateTime.toISOString().slice(0, -5) + "Z",
|
||||
endDateTime.toISOString().slice(0, -5) + "Z",
|
||||
).then((response) => {
|
||||
response?.forEach((item) => saveData(item));
|
||||
});
|
||||
};
|
||||
|
||||
const handleGoogleLogin = async () => {
|
||||
try {
|
||||
const response = await GoogleLogin();
|
||||
if (response) {
|
||||
const googleUserData = response.data;
|
||||
let idToken = googleUserData?.idToken;
|
||||
fetchMicrosoftCalendarEvents(
|
||||
profileData?.microsoftToken,
|
||||
startDateTime.toISOString().slice(0, -5) + "Z",
|
||||
endDateTime.toISOString().slice(0, -5) + "Z"
|
||||
).then((response) => {
|
||||
console.log(response)
|
||||
response?.forEach((item) => saveData(item));
|
||||
});
|
||||
};
|
||||
|
||||
if (idToken) {
|
||||
await updateUserData({ newUserData: { googleToken: idToken } });
|
||||
const handleGoogleLogin = async () => {
|
||||
try {
|
||||
const response = await GoogleLogin();
|
||||
if (response) {
|
||||
const googleUserData = response.data;
|
||||
let idToken = googleUserData?.idToken;
|
||||
|
||||
if (idToken) {
|
||||
await updateUserData({newUserData: {googleToken: idToken}});
|
||||
}
|
||||
}
|
||||
} catch (apiError) {
|
||||
console.log(apiError || "Something went wrong");
|
||||
}
|
||||
}
|
||||
} catch (apiError) {
|
||||
console.log(apiError || "Something went wrong");
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const handleMicrosoftSignIn = async () => {
|
||||
try {
|
||||
const { idToken } = await authorize(microsoftConfig);
|
||||
if (idToken) {
|
||||
await updateUserData({ newUserData: { microsoftToken: idToken } });
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
const handleMicrosoftSignIn = async () => {
|
||||
try {
|
||||
console.log("Starting Microsoft sign-in...");
|
||||
|
||||
return (
|
||||
<View marginH-30>
|
||||
<TouchableOpacity onPress={() => props.setSelectedPage(0)}>
|
||||
<View row marginT-20 marginB-35 centerV>
|
||||
<Ionicons name="chevron-back" size={22} color="#979797" />
|
||||
<Text text70 color="#979797">
|
||||
Return to main settings
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<Text text60R>Calendar settings</Text>
|
||||
<View style={styles.card}>
|
||||
<Text text70 marginB-14>
|
||||
Event Color Preference
|
||||
</Text>
|
||||
<View row spread>
|
||||
<TouchableOpacity onPress={() => setSelectedColor(colorMap.pink)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.pink}>
|
||||
{selectedColor == colorMap.pink && (
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => setSelectedColor(colorMap.orange)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.orange}>
|
||||
{selectedColor == colorMap.orange && (
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => setSelectedColor(colorMap.green)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.green}>
|
||||
{selectedColor == colorMap.green && (
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => setSelectedColor(colorMap.teal)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.teal}>
|
||||
{selectedColor == colorMap.teal && (
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => setSelectedColor(colorMap.purple)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.purple}>
|
||||
{selectedColor == colorMap.purple && (
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.card}>
|
||||
<Text text70>Weekly Start Date</Text>
|
||||
<View row marginV-5 marginT-20>
|
||||
<Checkbox
|
||||
value={startDate}
|
||||
style={styles.checkbox}
|
||||
color="#ea156d"
|
||||
onValueChange={() => setStartDate(true)}
|
||||
/>
|
||||
<View row marginL-8>
|
||||
<Text text70>Sundays</Text>
|
||||
<Text text70 color="gray">
|
||||
{" "}
|
||||
(default)
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View row marginV-5>
|
||||
<Checkbox
|
||||
value={!startDate}
|
||||
style={styles.checkbox}
|
||||
color="#ea156d"
|
||||
onValueChange={() => setStartDate(false)}
|
||||
/>
|
||||
<Text text70 marginL-8>
|
||||
Mondays
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.card}>
|
||||
<Text text70>Add Calendar</Text>
|
||||
<View style={{ marginTop: 20 }}>
|
||||
<Button
|
||||
label={"Connect Google"}
|
||||
iconSource={() => (
|
||||
<View
|
||||
backgroundColor="#ededed"
|
||||
width={40}
|
||||
height={40}
|
||||
style={{ borderRadius: 50 }}
|
||||
marginR-10
|
||||
centerV
|
||||
centerH
|
||||
>
|
||||
<Ionicons name="logo-google" size={22} color="#979797" />
|
||||
</View>
|
||||
)}
|
||||
backgroundColor="white"
|
||||
color="#464039"
|
||||
borderRadius={15}
|
||||
onPress={handleGoogleLogin}
|
||||
/>
|
||||
<Button
|
||||
label={"Connect Microsoft"}
|
||||
iconSource={() => (
|
||||
<View
|
||||
backgroundColor="#ededed"
|
||||
width={40}
|
||||
height={40}
|
||||
style={{ borderRadius: 50 }}
|
||||
marginR-10
|
||||
centerV
|
||||
centerH
|
||||
>
|
||||
<Ionicons name="logo-microsoft" size={22} color="#979797" />
|
||||
const authRequest = new AuthSession.AuthRequest({
|
||||
clientId: microsoftConfig.clientId,
|
||||
scopes: microsoftConfig.scopes,
|
||||
redirectUri: microsoftConfig.redirectUri,
|
||||
responseType: AuthSession.ResponseType.Code,
|
||||
usePKCE: true, // Enable PKCE
|
||||
});
|
||||
|
||||
console.log("Auth request created:", authRequest);
|
||||
|
||||
const authResult = await authRequest.promptAsync({
|
||||
authorizationEndpoint: microsoftConfig.authorizationEndpoint,
|
||||
});
|
||||
|
||||
console.log("Auth result:", authResult);
|
||||
|
||||
if (authResult.type === "success" && authResult.params?.code) {
|
||||
const code = authResult.params.code;
|
||||
console.log("Authorization code received:", code);
|
||||
|
||||
// Exchange authorization code for tokens
|
||||
const tokenResponse = await fetch(microsoftConfig.tokenEndpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: `client_id=${microsoftConfig.clientId}&redirect_uri=${encodeURIComponent(
|
||||
microsoftConfig.redirectUri
|
||||
)}&grant_type=authorization_code&code=${code}&code_verifier=${
|
||||
authRequest.codeVerifier
|
||||
}&scope=${encodeURIComponent("https://graph.microsoft.com/Calendars.ReadWrite offline_access")}`,
|
||||
});
|
||||
|
||||
|
||||
console.log("Token response status:", tokenResponse.status);
|
||||
|
||||
if (!tokenResponse.ok) {
|
||||
console.error("Token exchange failed:", await tokenResponse.text());
|
||||
return;
|
||||
}
|
||||
|
||||
const tokenData = await tokenResponse.json();
|
||||
console.log("Token data received:", tokenData);
|
||||
|
||||
if (tokenData?.id_token) {
|
||||
console.log("ID token received, updating user data...");
|
||||
await updateUserData({newUserData: {microsoftToken: tokenData.access_token}});
|
||||
console.log("User data updated successfully.");
|
||||
}
|
||||
} else {
|
||||
console.warn("Authentication was not successful:", authResult);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error during Microsoft sign-in:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ScrollView>
|
||||
<View marginH-30>
|
||||
<TouchableOpacity onPress={() => props.setSelectedPage(0)}>
|
||||
<View row marginT-20 marginB-35 centerV>
|
||||
<Ionicons name="chevron-back" size={22} color="#979797"/>
|
||||
<Text text70 color="#979797">
|
||||
Return to main settings
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<Text text60R>Calendar settings</Text>
|
||||
<View style={styles.card}>
|
||||
<Text text70 marginB-14>
|
||||
Event Color Preference
|
||||
</Text>
|
||||
<View row spread>
|
||||
<TouchableOpacity onPress={() => setSelectedColor(colorMap.pink)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.pink}>
|
||||
{selectedColor == colorMap.pink && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => setSelectedColor(colorMap.orange)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.orange}>
|
||||
{selectedColor == colorMap.orange && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => setSelectedColor(colorMap.green)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.green}>
|
||||
{selectedColor == colorMap.green && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => setSelectedColor(colorMap.teal)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.teal}>
|
||||
{selectedColor == colorMap.teal && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => setSelectedColor(colorMap.purple)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.purple}>
|
||||
{selectedColor == colorMap.purple && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
backgroundColor="white"
|
||||
color="#464039"
|
||||
borderRadius={15}
|
||||
onPress={handleMicrosoftSignIn}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.card}>
|
||||
<Text text70>Calendars</Text>
|
||||
<View style={{ marginTop: 20 }}>
|
||||
<Button
|
||||
label={"Sync Outlook"}
|
||||
iconSource={() => (
|
||||
<View
|
||||
backgroundColor="#ededed"
|
||||
width={40}
|
||||
height={40}
|
||||
style={{ borderRadius: 50 }}
|
||||
marginR-10
|
||||
centerV
|
||||
centerH
|
||||
>
|
||||
<Ionicons name="logo-microsoft" size={22} color="#979797" />
|
||||
</View>
|
||||
)}
|
||||
backgroundColor="white"
|
||||
color="#464039"
|
||||
borderRadius={15}
|
||||
onPress={fetchAndSaveMicrosoftEvents}
|
||||
/>
|
||||
{profileData?.googleToken !== undefined && (
|
||||
<Button
|
||||
label={"Sync Google"}
|
||||
iconSource={() => (
|
||||
<View
|
||||
backgroundColor="#ededed"
|
||||
width={40}
|
||||
height={40}
|
||||
style={{ borderRadius: 50 }}
|
||||
marginR-10
|
||||
centerV
|
||||
centerH
|
||||
>
|
||||
<Ionicons name="logo-google" size={22} color="#979797" />
|
||||
<View style={styles.card}>
|
||||
<Text text70>Weekly Start Date</Text>
|
||||
<View row marginV-5 marginT-20>
|
||||
<Checkbox
|
||||
value={startDate}
|
||||
style={styles.checkbox}
|
||||
color="#ea156d"
|
||||
onValueChange={() => setStartDate(true)}
|
||||
/>
|
||||
<View row marginL-8>
|
||||
<Text text70>Sundays</Text>
|
||||
<Text text70 color="gray">
|
||||
{" "}
|
||||
(default)
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View row marginV-5>
|
||||
<Checkbox
|
||||
value={!startDate}
|
||||
style={styles.checkbox}
|
||||
color="#ea156d"
|
||||
onValueChange={() => setStartDate(false)}
|
||||
/>
|
||||
<Text text70 marginL-8>
|
||||
Mondays
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
backgroundColor="white"
|
||||
color="#464039"
|
||||
borderRadius={15}
|
||||
onPress={fetchAndSaveGoogleEvents}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
<View style={styles.card}>
|
||||
<Text text70>Add Calendar</Text>
|
||||
<View style={{marginTop: 20}}>
|
||||
<Button
|
||||
label={"Connect Google"}
|
||||
iconSource={() => (
|
||||
<View
|
||||
backgroundColor="#ededed"
|
||||
width={40}
|
||||
height={40}
|
||||
style={{borderRadius: 50}}
|
||||
marginR-10
|
||||
centerV
|
||||
centerH
|
||||
>
|
||||
<Ionicons name="logo-google" size={22} color="#979797"/>
|
||||
</View>
|
||||
)}
|
||||
backgroundColor="white"
|
||||
color="#464039"
|
||||
borderRadius={15}
|
||||
onPress={handleGoogleLogin}
|
||||
/>
|
||||
<Button
|
||||
label={"Connect Microsoft"}
|
||||
iconSource={() => (
|
||||
<View
|
||||
backgroundColor="#ededed"
|
||||
width={40}
|
||||
height={40}
|
||||
style={{borderRadius: 50}}
|
||||
marginR-10
|
||||
centerV
|
||||
centerH
|
||||
>
|
||||
<Ionicons name="logo-microsoft" size={22} color="#979797"/>
|
||||
</View>
|
||||
)}
|
||||
backgroundColor="white"
|
||||
color="#464039"
|
||||
borderRadius={15}
|
||||
onPress={handleMicrosoftSignIn}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.card}>
|
||||
<Text text70>Calendars</Text>
|
||||
<View style={{marginTop: 20}}>
|
||||
<Button
|
||||
label={"Sync Outlook"}
|
||||
iconSource={() => (
|
||||
<View
|
||||
backgroundColor="#ededed"
|
||||
width={40}
|
||||
height={40}
|
||||
style={{borderRadius: 50}}
|
||||
marginR-10
|
||||
centerV
|
||||
centerH
|
||||
>
|
||||
<Ionicons name="logo-microsoft" size={22} color="#979797"/>
|
||||
</View>
|
||||
)}
|
||||
backgroundColor="white"
|
||||
color="#464039"
|
||||
borderRadius={15}
|
||||
onPress={fetchAndSaveMicrosoftEvents}
|
||||
/>
|
||||
{profileData?.googleToken !== undefined && (
|
||||
<Button
|
||||
label={"Sync Google"}
|
||||
iconSource={() => (
|
||||
<View
|
||||
backgroundColor="#ededed"
|
||||
width={40}
|
||||
height={40}
|
||||
style={{borderRadius: 50}}
|
||||
marginR-10
|
||||
centerV
|
||||
centerH
|
||||
>
|
||||
<Ionicons name="logo-google" size={22} color="#979797"/>
|
||||
</View>
|
||||
)}
|
||||
backgroundColor="white"
|
||||
color="#464039"
|
||||
borderRadius={15}
|
||||
onPress={fetchAndSaveGoogleEvents}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
backBtn: {
|
||||
backgroundColor: "red",
|
||||
marginLeft: -2,
|
||||
justifyContent: "flex-start",
|
||||
},
|
||||
card: {
|
||||
backgroundColor: "white",
|
||||
width: "100%",
|
||||
padding: 20,
|
||||
paddingBottom: 30,
|
||||
marginTop: 20,
|
||||
borderRadius: 20,
|
||||
},
|
||||
colorBox: {
|
||||
aspectRatio: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
width: 50,
|
||||
borderRadius: 12,
|
||||
},
|
||||
checkbox: {
|
||||
borderRadius: 50,
|
||||
},
|
||||
backBtn: {
|
||||
backgroundColor: "red",
|
||||
marginLeft: -2,
|
||||
justifyContent: "flex-start",
|
||||
},
|
||||
card: {
|
||||
backgroundColor: "white",
|
||||
width: "100%",
|
||||
padding: 20,
|
||||
paddingBottom: 30,
|
||||
marginTop: 20,
|
||||
borderRadius: 20,
|
||||
},
|
||||
colorBox: {
|
||||
aspectRatio: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
width: 50,
|
||||
borderRadius: 12,
|
||||
},
|
||||
checkbox: {
|
||||
borderRadius: 50,
|
||||
},
|
||||
});
|
||||
|
||||
export default CalendarSettingsPage;
|
||||
|
@ -14,8 +14,9 @@ export enum ProfileType {
|
||||
interface IAuthContext {
|
||||
user: FirebaseAuthTypes.User | null,
|
||||
profileType?: ProfileType,
|
||||
profileData?: UserProfile
|
||||
setProfileData: (profileData: UserProfile) => void
|
||||
profileData?: UserProfile,
|
||||
setProfileData: (profileData: UserProfile) => void,
|
||||
refreshProfileData: () => Promise<void>
|
||||
}
|
||||
|
||||
const AuthContext = createContext<IAuthContext>(undefined!)
|
||||
@ -32,8 +33,14 @@ export const AuthContextProvider: FC<{ children: ReactNode }> = ({children}) =>
|
||||
const onAuthStateChanged = async (user: FirebaseAuthTypes.User | null) => {
|
||||
setUser(user);
|
||||
|
||||
console.log(user)
|
||||
if (user) {
|
||||
await refreshProfileData();
|
||||
}
|
||||
|
||||
if (initializing) setInitializing(false);
|
||||
}
|
||||
|
||||
const refreshProfileData = async () => {
|
||||
if (user) {
|
||||
try {
|
||||
const documentSnapshot = await firestore()
|
||||
@ -42,17 +49,15 @@ export const AuthContextProvider: FC<{ children: ReactNode }> = ({children}) =>
|
||||
.get();
|
||||
if (documentSnapshot.exists) {
|
||||
setProfileType(documentSnapshot.data()?.userType);
|
||||
setProfileData(documentSnapshot.data() as UserProfile)
|
||||
setProfileData(documentSnapshot.data() as UserProfile);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error fetching user profile type:", error);
|
||||
console.error("Error fetching user profile data:", error);
|
||||
setProfileType(undefined);
|
||||
setProfileData(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
if (initializing) setInitializing(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
|
||||
@ -78,10 +83,10 @@ export const AuthContextProvider: FC<{ children: ReactNode }> = ({children}) =>
|
||||
}
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{user, profileType, profileData, setProfileData}}>
|
||||
<AuthContext.Provider value={{user, profileType, profileData, setProfileData, refreshProfileData}}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useAuthContext = () => useContext(AuthContext)!;
|
||||
export const useAuthContext = () => useContext(AuthContext)!;
|
||||
|
@ -5,26 +5,36 @@ import {UserProfile} from "@/hooks/firebase/types/profileTypes";
|
||||
import {FirebaseAuthTypes} from "@react-native-firebase/auth";
|
||||
|
||||
export const useUpdateUserData = () => {
|
||||
const {user: currentUser, setProfileData} = useAuthContext()
|
||||
const {user: currentUser, setProfileData, refreshProfileData} = useAuthContext();
|
||||
|
||||
return useMutation({
|
||||
mutationKey: ["updateUserData"],
|
||||
mutationFn: async ({newUserData, customUser}: {newUserData: Partial<UserProfile>, customUser?: FirebaseAuthTypes.User }) => {
|
||||
const user = currentUser ?? customUser
|
||||
mutationFn: async ({newUserData, customUser}: {newUserData: Partial<UserProfile>, customUser?: FirebaseAuthTypes.User }) => {
|
||||
console.log("Mutation function called with data:", { newUserData, customUser });
|
||||
|
||||
const user = currentUser ?? customUser;
|
||||
|
||||
if (user) {
|
||||
console.log("Updating user data for UID:", user.uid);
|
||||
try {
|
||||
console.log("New user data:", newUserData);
|
||||
|
||||
await firestore()
|
||||
.collection("Profiles")
|
||||
.doc(user.uid)
|
||||
.update(newUserData);
|
||||
|
||||
const profileData = await firestore().collection("Profiles").doc(user?.uid!).get()
|
||||
setProfileData(profileData.data() as UserProfile)
|
||||
console.log("User data updated successfully, fetching updated profile...");
|
||||
|
||||
await refreshProfileData()
|
||||
|
||||
console.log("Profile data updated in context.");
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
console.error("Error updating user data:", e);
|
||||
}
|
||||
} else {
|
||||
console.warn("No user found: currentUser and customUser are both undefined.");
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -946,6 +946,12 @@ PODS:
|
||||
- abseil/meta/type_traits
|
||||
- abseil/xcprivacy
|
||||
- abseil/xcprivacy (1.20240116.2)
|
||||
- AppAuth (1.7.5):
|
||||
- AppAuth/Core (= 1.7.5)
|
||||
- AppAuth/ExternalUserAgent (= 1.7.5)
|
||||
- AppAuth/Core (1.7.5)
|
||||
- AppAuth/ExternalUserAgent (1.7.5):
|
||||
- AppAuth/Core
|
||||
- boost (1.83.0)
|
||||
- BoringSSL-GRPC (0.0.32):
|
||||
- BoringSSL-GRPC/Implementation (= 0.0.32)
|
||||
@ -956,6 +962,8 @@ PODS:
|
||||
- BVLinearGradient (2.8.3):
|
||||
- React-Core
|
||||
- DoubleConversion (1.1.6)
|
||||
- EXApplication (5.9.1):
|
||||
- ExpoModulesCore
|
||||
- EXBarCodeScanner (13.0.1):
|
||||
- EXImageLoader
|
||||
- ExpoModulesCore
|
||||
@ -1178,18 +1186,26 @@ PODS:
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- Yoga
|
||||
- ExpoAdapterGoogleSignIn (13.1.0):
|
||||
- ExpoModulesCore
|
||||
- GoogleSignIn (~> 7.1)
|
||||
- React-Core
|
||||
- ExpoAsset (10.0.10):
|
||||
- ExpoModulesCore
|
||||
- ExpoCamera (15.0.16):
|
||||
- ExpoModulesCore
|
||||
- ZXingObjC/OneD
|
||||
- ZXingObjC/PDF417
|
||||
- ExpoCrypto (13.0.2):
|
||||
- ExpoModulesCore
|
||||
- ExpoFileSystem (17.0.1):
|
||||
- ExpoModulesCore
|
||||
- ExpoFont (12.0.10):
|
||||
- ExpoModulesCore
|
||||
- ExpoHead (3.5.23):
|
||||
- ExpoModulesCore
|
||||
- ExpoImagePicker (15.0.7):
|
||||
- ExpoModulesCore
|
||||
- ExpoKeepAwake (13.0.2):
|
||||
- ExpoModulesCore
|
||||
- ExpoModulesCore (1.12.24):
|
||||
@ -1335,6 +1351,10 @@ PODS:
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- nanopb (< 2.30911.0, >= 2.30908.0)
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- GoogleSignIn (7.1.0):
|
||||
- AppAuth (< 2.0, >= 1.7.3)
|
||||
- GTMAppAuth (< 5.0, >= 4.1.1)
|
||||
- GTMSessionFetcher/Core (~> 3.3)
|
||||
- GoogleUtilities/AppDelegateSwizzler (7.13.3):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Logger
|
||||
@ -1438,6 +1458,9 @@ PODS:
|
||||
- gRPC-Core/Privacy (= 1.62.5)
|
||||
- gRPC-Core/Interface (1.62.5)
|
||||
- gRPC-Core/Privacy (1.62.5)
|
||||
- GTMAppAuth (4.1.1):
|
||||
- AppAuth/Core (~> 1.7)
|
||||
- GTMSessionFetcher/Core (< 4.0, >= 3.3)
|
||||
- GTMSessionFetcher/Core (3.5.0)
|
||||
- hermes-engine (0.74.3):
|
||||
- hermes-engine/Pre-built (= 0.74.3)
|
||||
@ -2379,6 +2402,9 @@ PODS:
|
||||
- React-Mapbuffer (0.74.3):
|
||||
- glog
|
||||
- React-debug
|
||||
- react-native-app-auth (8.0.0):
|
||||
- AppAuth (>= 1.7.3)
|
||||
- React-Core
|
||||
- react-native-blur (4.4.0):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
@ -2678,6 +2704,9 @@ PODS:
|
||||
- ReactCommon/turbomodule/bridging
|
||||
- ReactCommon/turbomodule/core
|
||||
- Yoga
|
||||
- RNGoogleSignin (13.1.0):
|
||||
- GoogleSignIn (~> 7.1)
|
||||
- React-Core
|
||||
- RNReanimated (3.10.1):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
@ -2735,6 +2764,7 @@ DEPENDENCIES:
|
||||
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
||||
- BVLinearGradient (from `../node_modules/react-native-linear-gradient`)
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- EXApplication (from `../node_modules/expo-application/ios`)
|
||||
- EXBarCodeScanner (from `../node_modules/expo-barcode-scanner/ios`)
|
||||
- EXConstants (from `../node_modules/expo-constants/ios`)
|
||||
- EXImageLoader (from `../node_modules/expo-image-loader/ios`)
|
||||
@ -2745,11 +2775,14 @@ DEPENDENCIES:
|
||||
- expo-dev-launcher (from `../node_modules/expo-dev-launcher`)
|
||||
- expo-dev-menu (from `../node_modules/expo-dev-menu`)
|
||||
- expo-dev-menu-interface (from `../node_modules/expo-dev-menu-interface/ios`)
|
||||
- "ExpoAdapterGoogleSignIn (from `../node_modules/@react-native-google-signin/google-signin/expo/ios`)"
|
||||
- ExpoAsset (from `../node_modules/expo-asset/ios`)
|
||||
- ExpoCamera (from `../node_modules/expo-camera/ios`)
|
||||
- ExpoCrypto (from `../node_modules/expo-crypto/ios`)
|
||||
- ExpoFileSystem (from `../node_modules/expo-file-system/ios`)
|
||||
- ExpoFont (from `../node_modules/expo-font/ios`)
|
||||
- ExpoHead (from `../node_modules/expo-router/ios`)
|
||||
- ExpoImagePicker (from `../node_modules/expo-image-picker/ios`)
|
||||
- ExpoKeepAwake (from `../node_modules/expo-keep-awake/ios`)
|
||||
- ExpoModulesCore (from `../node_modules/expo-modules-core`)
|
||||
- ExpoSystemUI (from `../node_modules/expo-system-ui/ios`)
|
||||
@ -2786,6 +2819,7 @@ DEPENDENCIES:
|
||||
- React-jsitracing (from `../node_modules/react-native/ReactCommon/hermes/executor/`)
|
||||
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
|
||||
- React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
|
||||
- react-native-app-auth (from `../node_modules/react-native-app-auth`)
|
||||
- "react-native-blur (from `../node_modules/@react-native-community/blur`)"
|
||||
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||
- React-nativeconfig (from `../node_modules/react-native/ReactCommon`)
|
||||
@ -2819,6 +2853,7 @@ DEPENDENCIES:
|
||||
- "RNFBFirestore (from `../node_modules/@react-native-firebase/firestore`)"
|
||||
- "RNFBFunctions (from `../node_modules/@react-native-firebase/functions`)"
|
||||
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||
- "RNGoogleSignin (from `../node_modules/@react-native-google-signin/google-signin`)"
|
||||
- RNReanimated (from `../node_modules/react-native-reanimated`)
|
||||
- RNScreens (from `../node_modules/react-native-screens`)
|
||||
- RNSVG (from `../node_modules/react-native-svg`)
|
||||
@ -2827,6 +2862,7 @@ DEPENDENCIES:
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- abseil
|
||||
- AppAuth
|
||||
- BoringSSL-GRPC
|
||||
- Firebase
|
||||
- FirebaseAppCheckInterop
|
||||
@ -2845,9 +2881,11 @@ SPEC REPOS:
|
||||
- FirebaseSessions
|
||||
- FirebaseSharedSwift
|
||||
- GoogleDataTransport
|
||||
- GoogleSignIn
|
||||
- GoogleUtilities
|
||||
- "gRPC-C++"
|
||||
- gRPC-Core
|
||||
- GTMAppAuth
|
||||
- GTMSessionFetcher
|
||||
- leveldb-library
|
||||
- nanopb
|
||||
@ -2864,6 +2902,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native-linear-gradient"
|
||||
DoubleConversion:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
|
||||
EXApplication:
|
||||
:path: "../node_modules/expo-application/ios"
|
||||
EXBarCodeScanner:
|
||||
:path: "../node_modules/expo-barcode-scanner/ios"
|
||||
EXConstants:
|
||||
@ -2884,16 +2924,22 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/expo-dev-menu"
|
||||
expo-dev-menu-interface:
|
||||
:path: "../node_modules/expo-dev-menu-interface/ios"
|
||||
ExpoAdapterGoogleSignIn:
|
||||
:path: "../node_modules/@react-native-google-signin/google-signin/expo/ios"
|
||||
ExpoAsset:
|
||||
:path: "../node_modules/expo-asset/ios"
|
||||
ExpoCamera:
|
||||
:path: "../node_modules/expo-camera/ios"
|
||||
ExpoCrypto:
|
||||
:path: "../node_modules/expo-crypto/ios"
|
||||
ExpoFileSystem:
|
||||
:path: "../node_modules/expo-file-system/ios"
|
||||
ExpoFont:
|
||||
:path: "../node_modules/expo-font/ios"
|
||||
ExpoHead:
|
||||
:path: "../node_modules/expo-router/ios"
|
||||
ExpoImagePicker:
|
||||
:path: "../node_modules/expo-image-picker/ios"
|
||||
ExpoKeepAwake:
|
||||
:path: "../node_modules/expo-keep-awake/ios"
|
||||
ExpoModulesCore:
|
||||
@ -2963,6 +3009,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/logger"
|
||||
React-Mapbuffer:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
react-native-app-auth:
|
||||
:path: "../node_modules/react-native-app-auth"
|
||||
react-native-blur:
|
||||
:path: "../node_modules/@react-native-community/blur"
|
||||
react-native-safe-area-context:
|
||||
@ -3029,6 +3077,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/@react-native-firebase/functions"
|
||||
RNGestureHandler:
|
||||
:path: "../node_modules/react-native-gesture-handler"
|
||||
RNGoogleSignin:
|
||||
:path: "../node_modules/@react-native-google-signin/google-signin"
|
||||
RNReanimated:
|
||||
:path: "../node_modules/react-native-reanimated"
|
||||
RNScreens:
|
||||
@ -3040,10 +3090,12 @@ EXTERNAL SOURCES:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
abseil: d121da9ef7e2ff4cab7666e76c5a3e0915ae08c3
|
||||
AppAuth: 501c04eda8a8d11f179dbe8637b7a91bb7e5d2fa
|
||||
boost: d3f49c53809116a5d38da093a8aa78bf551aed09
|
||||
BoringSSL-GRPC: 1e2348957acdbcad360b80a264a90799984b2ba6
|
||||
BVLinearGradient: 880f91a7854faff2df62518f0281afb1c60d49a3
|
||||
DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5
|
||||
EXApplication: c08200c34daca7af7fd76ac4b9d606077410e8ad
|
||||
EXBarCodeScanner: e2dd9b42c1b522a2adc9202b1dfbc64cb34456d1
|
||||
EXConstants: 409690fbfd5afea964e5e9d6c4eb2c2b59222c59
|
||||
EXImageLoader: ab589d67d6c5f2c33572afea9917304418566334
|
||||
@ -3054,11 +3106,14 @@ SPEC CHECKSUMS:
|
||||
expo-dev-launcher: fe4f2c0a0aa627449eeaec5f9f11e04090f97c40
|
||||
expo-dev-menu: 5b14897ecce3a8cf9e9cf9109344c2c192a3766a
|
||||
expo-dev-menu-interface: be32c09f1e03833050f0ee290dcc86b3ad0e73e4
|
||||
ExpoAdapterGoogleSignIn: da10ae7e7c1d73a10c2facebcdfe5ebea8e073ce
|
||||
ExpoAsset: 323700f291684f110fb55f0d4022a3362ea9f875
|
||||
ExpoCamera: 929be541d1c1319fcf32f9f5d9df8b97804346b5
|
||||
ExpoCrypto: 156078f266bf28f80ecf5e2a9c3a0d6ffce07a1c
|
||||
ExpoFileSystem: 80bfe850b1f9922c16905822ecbf97acd711dc51
|
||||
ExpoFont: 00756e6c796d8f7ee8d211e29c8b619e75cbf238
|
||||
ExpoHead: fcb28a68ed4ba28f177394d2dfb8a0a8824cd103
|
||||
ExpoImagePicker: 12a420923383ae38dccb069847218f27a3b87816
|
||||
ExpoKeepAwake: 3b8815d9dd1d419ee474df004021c69fdd316d08
|
||||
ExpoModulesCore: db3e31e694684f08223d713e89f7648c6d3e04d0
|
||||
ExpoSystemUI: d4f065a016cae6721b324eb659cdee4d4cf0cb26
|
||||
@ -3085,9 +3140,11 @@ SPEC CHECKSUMS:
|
||||
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
|
||||
glog: fdfdfe5479092de0c4bdbebedd9056951f092c4f
|
||||
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
|
||||
GoogleSignIn: d4281ab6cf21542b1cfaff85c191f230b399d2db
|
||||
GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15
|
||||
"gRPC-C++": e725ef63c4475d7cdb7e2cf16eb0fde84bd9ee51
|
||||
gRPC-Core: eee4be35df218649fe66d721a05a7f27a28f069b
|
||||
GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de
|
||||
GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6
|
||||
hermes-engine: 1f547997900dd0752dc0cc0ae6dd16173c49e09b
|
||||
leveldb-library: e8eadf9008a61f9e1dde3978c086d2b6d9b9dc28
|
||||
@ -3118,6 +3175,7 @@ SPEC CHECKSUMS:
|
||||
React-jsitracing: 1aa5681c353b41573b03e0e480a5adf5fa1c56d8
|
||||
React-logger: fa92ba4d3a5d39ac450f59be2a3cec7b099f0304
|
||||
React-Mapbuffer: 70da5955150a58732e9336a0c7e71cd49e909f25
|
||||
react-native-app-auth: c4a3b4edc11100070d8d7bc48d55fb66668cead9
|
||||
react-native-blur: b58f3155f534d975b7647593d93a2e907513addd
|
||||
react-native-safe-area-context: a240ad4b683349e48b1d51fed1611138d1bdad97
|
||||
React-nativeconfig: 84806b820491db30175afbf027e99e8415dc63f0
|
||||
@ -3152,6 +3210,7 @@ SPEC CHECKSUMS:
|
||||
RNFBFirestore: e47cdde04ea3d9e73e58e037e1aa1d0b1141c316
|
||||
RNFBFunctions: 738cc9e2177d060d29b5d143ef2f9ed0eda4bb1f
|
||||
RNGestureHandler: 20a4307fd21cbff339abfcfa68192f3f0a6a518b
|
||||
RNGoogleSignin: 9e68b9bcc3888219357924e32ee563624745647d
|
||||
RNReanimated: d51431fd3597a8f8320319dce8e42cee82a5445f
|
||||
RNScreens: 30249f9331c3b00ae7cb7922e11f58b3ed369c07
|
||||
RNSVG: 4590aa95758149fa27c5c83e54a6a466349a1688
|
||||
@ -3161,4 +3220,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: 50f618790da7cbbfd5c5e988b7f9370bd45d34a6
|
||||
|
||||
COCOAPODS: 1.14.3
|
||||
COCOAPODS: 1.15.2
|
||||
|
@ -293,7 +293,9 @@
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-cally/Pods-cally-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/AppAuth/AppAuthCore_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/BoringSSL-GRPC/openssl_grpc.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/EXApplication/ExpoApplication_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/ExpoConstants_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle",
|
||||
@ -306,8 +308,10 @@
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseFirestore/FirebaseFirestore_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseFirestoreInternal/FirebaseFirestoreInternal_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/GTMAppAuth/GTMAppAuth_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher/GTMSessionFetcher_Core_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleSignIn/GoogleSignIn.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/PromisesSwift/Promises_Privacy.bundle",
|
||||
@ -322,7 +326,9 @@
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AppAuthCore_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/openssl_grpc.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoApplication_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoConstants_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle",
|
||||
@ -335,8 +341,10 @@
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseFirestore_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseFirestoreInternal_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GTMAppAuth_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GTMSessionFetcher_Core_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleSignIn.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Promises_Privacy.bundle",
|
||||
@ -429,7 +437,7 @@
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cally.app;
|
||||
PRODUCT_NAME = "KaliFamilyPlanner";
|
||||
PRODUCT_NAME = KaliFamilyPlanner;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "cally/cally-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -460,7 +468,7 @@
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.cally.app;
|
||||
PRODUCT_NAME = "KaliFamilyPlanner";
|
||||
PRODUCT_NAME = KaliFamilyPlanner;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "cally/cally-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTLinkingManager.h>
|
||||
#import "RNAppAuthAuthorizationFlowManager.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
<dict>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>myapp</string>
|
||||
<string>callyplanner</string>
|
||||
<string>com.cally.app</string>
|
||||
</array>
|
||||
</dict>
|
||||
@ -75,6 +75,8 @@
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>SplashScreen</string>
|
||||
|
@ -40,6 +40,7 @@
|
||||
"@react-navigation/native": "^6.0.2",
|
||||
"date-fns": "^3.6.0",
|
||||
"expo": "~51.0.24",
|
||||
"expo-auth-session": "^5.5.2",
|
||||
"expo-barcode-scanner": "~13.0.1",
|
||||
"expo-build-properties": "~0.12.4",
|
||||
"expo-camera": "~15.0.16",
|
||||
|
Reference in New Issue
Block a user