From 3273e7a0fbbce82f4ce6cacbcdb7b6d6848f6c1b Mon Sep 17 00:00:00 2001 From: JustZvan Date: Mon, 6 Apr 2026 15:32:51 +0200 Subject: feat: gallery scanning preferences --- lib/google-auth.ts | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 lib/google-auth.ts (limited to 'lib/google-auth.ts') diff --git a/lib/google-auth.ts b/lib/google-auth.ts new file mode 100644 index 0000000..769da55 --- /dev/null +++ b/lib/google-auth.ts @@ -0,0 +1,116 @@ +import { ResponseType } from "expo-auth-session"; +import * as Google from "expo-auth-session/providers/google"; +import Constants from "expo-constants"; +import * as WebBrowser from "expo-web-browser"; +import { useEffect, useMemo, useState } from "react"; +import { useAuth } from "./auth"; +import { t } from "./locales"; + +WebBrowser.maybeCompleteAuthSession(); + +type GoogleClientIds = { + iosClientId?: string; + androidClientId?: string; + webClientId?: string; +}; + +function getGoogleClientIds(): GoogleClientIds { + const env = (process as any)?.env || {}; + const extra = + (Constants.manifest as any)?.extra || + (Constants.expoConfig as any)?.extra || + {}; + + return { + iosClientId: + env.EXPO_PUBLIC_GOOGLE_IOS_CLIENT_ID || extra.GOOGLE_IOS_CLIENT_ID, + androidClientId: + env.EXPO_PUBLIC_GOOGLE_ANDROID_CLIENT_ID || + extra.GOOGLE_ANDROID_CLIENT_ID, + webClientId: + env.EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID || + extra.GOOGLE_WEB_CLIENT_ID || + env.EXPO_PUBLIC_GOOGLE_EXPO_CLIENT_ID || + extra.GOOGLE_EXPO_CLIENT_ID, + }; +} + +export function useGoogleAuth() { + const { signInWithGoogle } = useAuth(); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(""); + + const clientIds = useMemo(() => getGoogleClientIds(), []); + + const [request, response, promptAsync] = Google.useAuthRequest({ + iosClientId: clientIds.iosClientId, + androidClientId: clientIds.androidClientId, + webClientId: clientIds.webClientId, + responseType: ResponseType.IdToken, + scopes: ["openid", "profile", "email"], + selectAccount: true, + }); + + useEffect(() => { + const run = async () => { + if (!response) return; + + if (response.type === "success") { + const idToken = + response.params?.id_token || response.authentication?.idToken; + + if (!idToken) { + setError(t("googleMissingIdToken")); + setIsLoading(false); + return; + } + + const result = await signInWithGoogle(idToken); + if (!result.success) { + setError(result.reason || t("googleSignInError")); + } + setIsLoading(false); + return; + } + + if (response.type === "error") { + setError(response.error?.message || t("googleSignInError")); + } + + // On cancel/dismissed/locked, just reset loading and keep the current screen state. + setIsLoading(false); + }; + + run().catch(() => { + setError(t("googleSignInError")); + setIsLoading(false); + }); + }, [response, signInWithGoogle]); + + const continueWithGoogle = async () => { + setError(""); + + if (!request) { + setError(t("googleConfigMissing")); + return; + } + + setIsLoading(true); + + try { + const result = await promptAsync(); + if (result.type === "cancel" || result.type === "dismiss") { + setIsLoading(false); + } + } catch { + setError(t("googleSignInError")); + setIsLoading(false); + } + }; + + return { + continueWithGoogle, + isLoading, + error, + }; +} -- cgit v1.2.3