From 35e8a0f6dc76319bb4acffce142661328a12417d Mon Sep 17 00:00:00 2001 From: Thomas Demirdjian Date: Mon, 6 Oct 2025 11:06:10 +0200 Subject: [PATCH] google sign in --- src/screens/Login.js | 182 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 166 insertions(+), 16 deletions(-) diff --git a/src/screens/Login.js b/src/screens/Login.js index 126b367..7855167 100644 --- a/src/screens/Login.js +++ b/src/screens/Login.js @@ -3,7 +3,15 @@ import * as AuthSession from "expo-auth-session"; import * as GoogleAuth from "expo-auth-session/providers/google"; import * as WebBrowser from "expo-web-browser"; import React, { useEffect, useState } from "react"; -import { Pressable, Text, View } from "react-native"; +import Constants from "expo-constants"; +import { + ActivityIndicator, + Platform, + Pressable, + StyleSheet, + Text, + View, +} from "react-native"; import { useGlobal } from "reactn"; import { background } from "../assets"; import GradientButton from "../components/GradientButton.js"; @@ -21,6 +29,8 @@ import { Routes } from "../navigation"; import { navigate } from "../navigation/NavigationService.js"; import { FONT_FAMILY } from "../styles/Fonts.js"; import Palette from "../styles/Palette.js"; +import { GoogleSigninButton } from "@react-native-google-signin/google-signin"; +import Svg, { Path } from "react-native-svg"; export default ({ navigation }) => { WebBrowser.maybeCompleteAuthSession(); @@ -31,11 +41,18 @@ export default ({ navigation }) => { // Let the provider compute a compliant redirect URI for native (com.googleusercontent.apps.:/oauth2redirect) // Avoid forcing a custom scheme like musicland:// which Google can reject for native apps. + const isExpoGo = Constants?.appOwnership === "expo"; + const expoRedirectUri = AuthSession.makeRedirectUri({ useProxy: true }); + const nativeRedirectUri = getNativeGoogleRedirectUri(); + const redirectUri = + isWeb || isExpoGo ? expoRedirectUri : nativeRedirectUri || expoRedirectUri; + const [request, response, promptAsync] = GoogleAuth.useAuthRequest({ iosClientId: GOOGLE_IOS_CLIENT_ID, androidClientId: GOOGLE_ANDROID_CLIENT_ID, webClientId: GOOGLE_WEB_CLIENT_ID, expoClientId: GOOGLE_WEB_CLIENT_ID, + redirectUri, // Use Authorization Code + PKCE to comply with Google OAuth for native apps responseType: AuthSession.ResponseType.Code, usePKCE: true, @@ -79,7 +96,7 @@ export default ({ navigation }) => { setLoading(false); } else { // Use defaults from the request; don't override with proxy here - const result = await promptAsync(); + const result = await promptAsync({ useProxy: isExpoGo }); if (result?.type !== "success") { // Cancelled or errored during the browser flow setLoading(false); @@ -133,7 +150,7 @@ export default ({ navigation }) => { redirectUri: request?.redirectUri, extraParams: { code_verifier: request?.codeVerifier }, }, - discovery + discovery, ); idToken = tokenResponse?.id_token; } @@ -241,21 +258,11 @@ export default ({ navigation }) => { onPress={onLogin} disabled={loading || !email || !password} /> - {/* */} - {/**/} + loading={loading} + /> { ); }; + +const GoogleAuthButton = ({ onPress, disabled, loading }) => { + if (isWeb) { + return ( + [ + styles.webButton, + pressed && !disabled ? styles.webButtonPressed : null, + disabled ? styles.webButtonDisabled : null, + ]} + > + + + + + Continuer avec Google + {loading ? ( + + ) : ( + + )} + + + ); + } + + return ( + + + {loading ? ( + + + + ) : null} + + ); +}; + +const getNativeGoogleRedirectUri = () => { + const clientId = Platform.select({ + ios: GOOGLE_IOS_CLIENT_ID, + android: GOOGLE_ANDROID_CLIENT_ID, + default: null, + }); + + if (!clientId || !clientId.includes(".apps.googleusercontent.com")) { + return undefined; + } + + const clientPrefix = clientId.replace(".apps.googleusercontent.com", ""); + return `com.googleusercontent.apps.${clientPrefix}:/oauth2redirect`; +}; + +const styles = StyleSheet.create({ + webButton: { + alignSelf: "center", + width: "80%", + height: 48, + borderRadius: 4, + backgroundColor: Palette.white, + borderWidth: 1, + borderColor: "#DADCE0", + justifyContent: "center", + shadowColor: "#000", + shadowOffset: { width: 0, height: 1 }, + shadowOpacity: 0.12, + shadowRadius: 2, + elevation: 1, + }, + webButtonPressed: { + backgroundColor: "#F6F9FE", + }, + webButtonDisabled: { + opacity: 0.7, + }, + webContent: { + flexDirection: "row", + alignItems: "center", + justifyContent: "center", + paddingHorizontal: 12, + }, + webIconContainer: { + justifyContent: "center", + alignItems: "center", + marginRight: 12, + }, + webText: { + flex: 1, + textAlign: "center", + fontSize: 14, + color: "#3C4043", + fontFamily: FONT_FAMILY.InterSemiBold, + }, + webRightSpacer: { + width: 18, + height: 18, + }, + nativeButtonWrapper: { + alignSelf: "center", + width: "80%", + height: 50, + justifyContent: "center", + }, + nativeButton: { + width: "100%", + height: 50, + }, + nativeLoadingOverlay: { + ...StyleSheet.absoluteFillObject, + alignItems: "center", + justifyContent: "center", + }, +}); + +const GoogleLogo = () => ( + + + + + + +);