From d085423eaccd7da504908109c19bd30ce82420de Mon Sep 17 00:00:00 2001 From: ChrisMattew Date: Wed, 18 Dec 2024 12:19:42 +0100 Subject: [PATCH 1/5] refactor(AuthErrorComponent): remove onRetry function from navigation params and move spid request states on redux --- ts/features/common/store/reducers/index.ts | 8 +- ts/features/spidLogin/store/actions/index.ts | 22 +++++ ts/features/spidLogin/store/reducers/index.ts | 84 +++++++++++++++++++ .../spidLogin/store/selectors/index.ts | 7 ++ ts/features/spidLogin/types/index.ts | 26 ++++++ ts/screens/authentication/AuthErrorScreen.tsx | 19 +++-- ts/screens/authentication/IdpLoginScreen.tsx | 42 +++++----- .../authentication/idpAuthSessionHandler.tsx | 44 +++++----- ts/store/actions/types.ts | 4 +- 9 files changed, 207 insertions(+), 49 deletions(-) create mode 100644 ts/features/spidLogin/store/actions/index.ts create mode 100644 ts/features/spidLogin/store/reducers/index.ts create mode 100644 ts/features/spidLogin/store/selectors/index.ts create mode 100644 ts/features/spidLogin/types/index.ts diff --git a/ts/features/common/store/reducers/index.ts b/ts/features/common/store/reducers/index.ts index a2ea0e60c39..978935f24c1 100644 --- a/ts/features/common/store/reducers/index.ts +++ b/ts/features/common/store/reducers/index.ts @@ -56,6 +56,10 @@ import { landingScreenBannersReducer, LandingScreenBannerState } from "../../../landingScreenMultiBanner/store/reducer"; +import { + spidLoginReducer, + SpidLoginState +} from "../../../spidLogin/store/reducers"; type LoginFeaturesState = { testLogin: TestLoginState; @@ -63,6 +67,7 @@ type LoginFeaturesState = { fastLogin: FastLoginState; cieLogin: CieLoginState & PersistPartial; loginInfo: LoginInfoState; + spidLogin: SpidLoginState; }; export type FeaturesState = { @@ -96,7 +101,8 @@ const rootReducer = combineReducers({ nativeLogin: nativeLoginReducer, fastLogin: fastLoginReducer, cieLogin: cieLoginPersistor, - loginInfo: loginInfoReducer + loginInfo: loginInfoReducer, + spidLogin: spidLoginReducer }), wallet: walletReducer, fims: fimsReducer, diff --git a/ts/features/spidLogin/store/actions/index.ts b/ts/features/spidLogin/store/actions/index.ts new file mode 100644 index 00000000000..abd34ed11d1 --- /dev/null +++ b/ts/features/spidLogin/store/actions/index.ts @@ -0,0 +1,22 @@ +import { ActionType, createStandardAction } from "typesafe-actions"; +import * as pot from "@pagopa/ts-commons/lib/pot"; +import { ErrorType, NativeLoginRequestInfo } from "../../types"; + +export const setNativeLoginRequestInfo = createStandardAction( + "SET_NATIVE_LOGIN_REQUEST_INFO" +)(); +export const incrementNativeLoginNativeAttempts = createStandardAction( + "INCREMENT_NATIVE_LOGIN_NATIVE_ATTEMPTS" +)(); +export const setStandardLoginRequestState = createStandardAction( + "SET_STNDARD_LOGIN_REQUEST_STATE" +)>(); +export const setStandardLoginInLoadingState = createStandardAction( + "SET_STANDARD_LOGIN_IN_LOADING_STATE" +)(); + +export type SpidConfigActions = + | ActionType + | ActionType + | ActionType + | ActionType; diff --git a/ts/features/spidLogin/store/reducers/index.ts b/ts/features/spidLogin/store/reducers/index.ts new file mode 100644 index 00000000000..67dab16796f --- /dev/null +++ b/ts/features/spidLogin/store/reducers/index.ts @@ -0,0 +1,84 @@ +import { getType } from "typesafe-actions"; +import * as pot from "@pagopa/ts-commons/lib/pot"; +import { Action } from "../../../../store/actions/types"; +import { StandardLoginRequestInfo, NativeLoginRequestInfo } from "../../types"; +import { + incrementNativeLoginNativeAttempts, + setStandardLoginRequestState, + setNativeLoginRequestInfo, + setStandardLoginInLoadingState +} from "../actions"; + +export type SpidLoginState = { + nativeLogin: { + requestInfo: NativeLoginRequestInfo; + }; + standardLogin: { + requestInfo: StandardLoginRequestInfo; + }; +}; + +const spidLoginInitialState: SpidLoginState = { + nativeLogin: { + requestInfo: { + requestState: "LOADING", + nativeAttempts: 0 + } + }, + standardLogin: { + requestInfo: { + requestState: pot.noneLoading + } + } +}; + +export const spidLoginReducer = ( + state: SpidLoginState = spidLoginInitialState, + action: Action +): SpidLoginState => { + switch (action.type) { + case getType(setNativeLoginRequestInfo): + return { + ...state, + nativeLogin: { + ...state.nativeLogin, + requestInfo: action.payload + } + }; + case getType(incrementNativeLoginNativeAttempts): + return { + ...state, + nativeLogin: { + ...state.nativeLogin, + requestInfo: { + requestState: "LOADING", + nativeAttempts: state.nativeLogin.requestInfo.nativeAttempts + 1 + } + } + }; + case getType(setStandardLoginRequestState): + return { + ...state, + standardLogin: { + ...state.standardLogin, + requestInfo: { + ...state.standardLogin.requestInfo, + requestState: action.payload + } + } + }; + case getType(setStandardLoginInLoadingState): + return { + ...state, + standardLogin: { + ...state.standardLogin, + requestInfo: { + ...state.standardLogin.requestInfo, + requestState: pot.noneLoading + } + } + }; + default: + return state; + } +}; diff --git a/ts/features/spidLogin/store/selectors/index.ts b/ts/features/spidLogin/store/selectors/index.ts new file mode 100644 index 00000000000..9e4c53d55ff --- /dev/null +++ b/ts/features/spidLogin/store/selectors/index.ts @@ -0,0 +1,7 @@ +import { GlobalState } from "../../../../store/reducers/types"; + +export const nativeLoginRequestInfoSelector = (state: GlobalState) => + state.features.loginFeatures.spidLogin.nativeLogin.requestInfo; + +export const standardLoginRequestInfoSelector = (state: GlobalState) => + state.features.loginFeatures.spidLogin.standardLogin.requestInfo; diff --git a/ts/features/spidLogin/types/index.ts b/ts/features/spidLogin/types/index.ts new file mode 100644 index 00000000000..497e41bac48 --- /dev/null +++ b/ts/features/spidLogin/types/index.ts @@ -0,0 +1,26 @@ +import * as pot from "@pagopa/ts-commons/lib/pot"; + +export enum ErrorType { + "LOADING_ERROR" = "LOADING_ERROR", + "LOGIN_ERROR" = "LOGIN_ERROR" +} + +export type RequestInfoPositiveStates = { + requestState: "LOADING" | "AUTHORIZED" | "AUTHORIZING"; + nativeAttempts: number; +}; + +export type RequestInfoError = { + requestState: "ERROR"; + errorType: ErrorType; + errorCodeOrMessage?: string; + nativeAttempts: number; +}; + +export type NativeLoginRequestInfo = + | RequestInfoPositiveStates + | RequestInfoError; + +export type StandardLoginRequestInfo = { + requestState: pot.Pot; +}; diff --git a/ts/screens/authentication/AuthErrorScreen.tsx b/ts/screens/authentication/AuthErrorScreen.tsx index a8cca27fde7..9a34bbeef22 100644 --- a/ts/screens/authentication/AuthErrorScreen.tsx +++ b/ts/screens/authentication/AuthErrorScreen.tsx @@ -8,6 +8,11 @@ import { useIONavigation } from "../../navigation/params/AppParamsList"; import ROUTES from "../../navigation/routes"; import { CieIdLoginProps } from "../../features/cieLogin/components/CieIdLoginWebView"; import { AuthenticationParamsList } from "../../navigation/params/AuthenticationParamsList"; +import { useIODispatch } from "../../store/hooks"; +import { + incrementNativeLoginNativeAttempts, + setStandardLoginInLoadingState +} from "../../features/spidLogin/store/actions"; import { UnlockAccessProps } from "./UnlockAccessComponent"; import AuthErrorComponent from "./components/AuthErrorComponent"; @@ -17,12 +22,11 @@ type CommonAuthErrorScreenProps = { type SpidProps = { authMethod: "SPID"; - onRetry: () => void; + isNativeLogin?: boolean; }; type CieIdProps = { authMethod: "CIE_ID"; - onRetry?: () => void; params: CieIdLoginProps; }; @@ -40,6 +44,7 @@ const authScreenByAuthMethod = { }; const AuthErrorScreen = () => { + const dispatch = useIODispatch(); const route = useRoute>(); const { errorCodeOrMessage, authMethod, authLevel } = route.params; @@ -61,11 +66,15 @@ const AuthErrorScreen = () => { }, [authMethod, route.params]); const onRetry = useCallback(() => { - if (authMethod === "SPID" || authMethod === "CIE_ID") { - route.params.onRetry?.(); + if (authMethod === "SPID") { + dispatch( + route.params.isNativeLogin + ? incrementNativeLoginNativeAttempts() + : setStandardLoginInLoadingState() + ); } navigation.navigate(ROUTES.AUTHENTICATION, getNavigationParams()); - }, [authMethod, navigation, route.params, getNavigationParams]); + }, [authMethod, navigation, route.params, getNavigationParams, dispatch]); const onCancel = useCallback(() => { navigation.navigate(ROUTES.AUTHENTICATION, { diff --git a/ts/screens/authentication/IdpLoginScreen.tsx b/ts/screens/authentication/IdpLoginScreen.tsx index 8f0b31a3d2b..6ba2346131b 100644 --- a/ts/screens/authentication/IdpLoginScreen.tsx +++ b/ts/screens/authentication/IdpLoginScreen.tsx @@ -52,6 +52,8 @@ import { handleSendAssistanceLog } from "../../utils/supportAssistance"; import { getUrlBasepath } from "../../utils/url"; +import { standardLoginRequestInfoSelector } from "../../features/spidLogin/store/selectors"; +import { setStandardLoginRequestState } from "../../features/spidLogin/store/actions"; import { originSchemasWhiteList } from "./originSchemasWhiteList"; enum ErrorType { @@ -79,7 +81,7 @@ const styles = StyleSheet.create({ */ const IdpLoginScreen = () => { const dispatch = useIODispatch(); - const { navigate } = useIONavigation(); + const { replace } = useIONavigation(); const selectedIdp = useIOSelector(selectedIdentityProviderSelector, _isEqual); const selectedIdpTextData = useIOSelector( idpContextualHelpDataFromIdSelector(selectedIdp?.id), @@ -95,25 +97,27 @@ const IdpLoginScreen = () => { _isEqual ); - const [requestState, setRequestState] = useState>( - pot.noneLoading - ); + const { requestState } = useIOSelector(standardLoginRequestInfoSelector); const [errorCodeOrMessage, setErrorCodeOrMessage] = useState< string | undefined >(undefined); const [loginTrace, setLoginTrace] = useState(undefined); + const setRequestState = useCallback( + (req: pot.Pot) => { + dispatch(setStandardLoginRequestState(req)); + }, + [dispatch] + ); + const handleOnLollipopCheckFailure = useCallback(() => { setRequestState(pot.noneError(ErrorType.LOGIN_ERROR)); - }, []); + }, [setRequestState]); const idpId = loggedOutWithIdpAuth?.idp.id; const loginUri = idpId ? getIdpLoginUri(idpId, 2) : undefined; - const { - retryLollipopLogin, - shouldBlockUrlNavigationWhileCheckingLollipop, - webviewSource - } = useLollipopLoginSource(handleOnLollipopCheckFailure, loginUri); + const { shouldBlockUrlNavigationWhileCheckingLollipop, webviewSource } = + useLollipopLoginSource(handleOnLollipopCheckFailure, loginUri); const choosenTool = useMemo( () => assistanceToolRemoteConfig(assistanceToolConfig), @@ -138,7 +142,7 @@ const IdpLoginScreen = () => { setRequestState(pot.noneError(ErrorType.LOADING_ERROR)); } }, - [loggedOutWithIdpAuth?.idp.id] + [loggedOutWithIdpAuth?.idp.id, setRequestState] ); const handleLoginFailure = useCallback( @@ -170,7 +174,7 @@ const IdpLoginScreen = () => { setRequestState(pot.noneError(ErrorType.LOGIN_ERROR)); setErrorCodeOrMessage(code || message); }, - [dispatch, choosenTool, idp] + [dispatch, choosenTool, idp, setRequestState] ); const handleLoginSuccess = useCallback( @@ -183,11 +187,6 @@ const IdpLoginScreen = () => { [choosenTool, dispatch, idp] ); - const onRetryButtonPressed = useCallback((): void => { - setRequestState(pot.noneLoading); - retryLollipopLogin(); - }, [retryLollipopLogin]); - const handleNavigationStateChange = useCallback( (event: WebViewNavigation) => { const url = event.url; @@ -212,7 +211,7 @@ const IdpLoginScreen = () => { event.loading || isAssertion ? pot.noneLoading : pot.some(true) ); }, - [dispatch, loginTrace] + [dispatch, loginTrace, setRequestState] ); const handleShouldStartLoading = useCallback( @@ -265,16 +264,15 @@ const IdpLoginScreen = () => { }; const navigateToAuthErrorScreen = useCallback(() => { - navigate(ROUTES.AUTHENTICATION, { + replace(ROUTES.AUTHENTICATION, { screen: ROUTES.AUTH_ERROR_SCREEN, params: { errorCodeOrMessage, authMethod: "SPID", - authLevel: "L2", - onRetry: onRetryButtonPressed + authLevel: "L2" } }); - }, [errorCodeOrMessage, onRetryButtonPressed, navigate]); + }, [errorCodeOrMessage, replace]); useEffect(() => { if (pot.isError(requestState)) { diff --git a/ts/screens/authentication/idpAuthSessionHandler.tsx b/ts/screens/authentication/idpAuthSessionHandler.tsx index 62902134f9d..c2444f98ddd 100644 --- a/ts/screens/authentication/idpAuthSessionHandler.tsx +++ b/ts/screens/authentication/idpAuthSessionHandler.tsx @@ -11,7 +11,7 @@ import * as O from "fp-ts/lib/Option"; import * as T from "fp-ts/lib/Task"; import * as TE from "fp-ts/lib/TaskEither"; import * as React from "react"; -import { useCallback, useEffect, useMemo, useState } from "react"; +import { useCallback, useEffect, useMemo } from "react"; import { AppState, SafeAreaView, StyleSheet, View } from "react-native"; import I18n from "../../i18n"; import { mixpanelTrack } from "../../mixpanel"; @@ -59,6 +59,8 @@ import { handleSendAssistanceLog } from "../../utils/supportAssistance"; import { emptyContextualHelp } from "../../utils/emptyContextualHelp"; +import { nativeLoginRequestInfoSelector } from "../../features/spidLogin/store/selectors"; +import { setNativeLoginRequestInfo } from "../../features/spidLogin/store/actions"; const styles = StyleSheet.create({ errorContainer: { @@ -115,13 +117,17 @@ const idpAuthSession = ( // This page is used in the native login process. export const AuthSessionPage = () => { - const [requestInfo, setRequestInfo] = useState({ - requestState: "LOADING", - nativeAttempts: 0 - }); - + const dispatch = useIODispatch(); + const requestInfo = useIOSelector(nativeLoginRequestInfoSelector); const mixpanelEnabled = useIOSelector(isMixpanelEnabled); + const setRequestInfo = useCallback( + (reqInfo: RequestInfo) => { + dispatch(setNativeLoginRequestInfo(reqInfo)); + }, + [dispatch] + ); + // This is a handler for the browser login. It applies to android only. useEffect(() => { const subscription = AppState.addEventListener("change", nextAppState => { @@ -136,9 +142,7 @@ export const AuthSessionPage = () => { return () => { subscription.remove(); }; - }, [requestInfo.nativeAttempts]); - - const dispatch = useIODispatch(); + }, [requestInfo.nativeAttempts, setRequestInfo]); // We call useIOStore beacause we only need some values from store, we don't need any re-render logic const store = useIOStore(); @@ -223,7 +227,7 @@ export const AuthSessionPage = () => { nativeAttempts: requestInfo.nativeAttempts }); }, - [choosenTool, dispatch, idp, requestInfo.nativeAttempts] + [choosenTool, dispatch, idp, requestInfo.nativeAttempts, setRequestInfo] ); const handleLoginSuccess = useCallback( @@ -237,7 +241,14 @@ export const AuthSessionPage = () => { ? dispatch(loginSuccess({ token, idp })) : handleLoginFailure("n/a"); }, - [choosenTool, dispatch, handleLoginFailure, idp, requestInfo.nativeAttempts] + [ + choosenTool, + dispatch, + handleLoginFailure, + idp, + requestInfo.nativeAttempts, + setRequestInfo + ] ); // This function is executed when the native component resolve with an error or when loginUri is undefined. // About the first case, unless there is a problem with the phone crashing for other reasons, this is very unlikely to happen. @@ -268,7 +279,7 @@ export const AuthSessionPage = () => { nativeAttempts: requestInfo.nativeAttempts }); }, - [dispatch, idp, requestInfo.nativeAttempts] + [dispatch, idp, requestInfo.nativeAttempts, setRequestInfo] ); // Memoized values/func --end-- @@ -364,13 +375,6 @@ export const AuthSessionPage = () => { faqCategories: ["authentication_SPID"], canGoBack: isBackButtonEnabled(requestInfo) }); - // It is enough to set the status to loading, - // the reload will ensure that the functions necessary for correct functioning are performed. - const onRetry = () => - setRequestInfo({ - requestState: "LOADING", - nativeAttempts: requestInfo.nativeAttempts + 1 - }); if (requestInfo.requestState === "ERROR") { navigation.navigate(ROUTES.AUTHENTICATION, { @@ -379,7 +383,7 @@ export const AuthSessionPage = () => { errorCodeOrMessage: requestInfo.errorCodeOrMessage, authMethod: "SPID", authLevel: "L2", - onRetry + isNativeLogin: true } }); } diff --git a/ts/store/actions/types.ts b/ts/store/actions/types.ts index 83ff7012be7..4d8e232ab31 100644 --- a/ts/store/actions/types.ts +++ b/ts/store/actions/types.ts @@ -34,6 +34,7 @@ import { ProfileSettingsActions } from "../../features/profileSettings/store/act import { IngressScreenActions } from "../../features/ingress/store/actions"; import { MixpanelFeatureActions } from "../../features/mixpanel/store/actions"; import { LandingScreenBannerActions } from "../../features/landingScreenMultiBanner/store/actions"; +import { SpidConfigActions } from "../../features/spidLogin/store/actions"; import { AnalyticsActions } from "./analytics"; import { ApplicationActions } from "./application"; import { AuthenticationActions } from "./authentication"; @@ -105,7 +106,8 @@ export type Action = | ProfileSettingsActions | IngressScreenActions | MixpanelFeatureActions - | LandingScreenBannerActions; + | LandingScreenBannerActions + | SpidConfigActions; export type Dispatch = DispatchAPI; From 800a12dde2f137a09523d1256d8987b1aae41be9 Mon Sep 17 00:00:00 2001 From: ChrisMattew Date: Wed, 18 Dec 2024 15:13:33 +0100 Subject: [PATCH 2/5] fix(AuthErrorScreen): reset spidLoginState on cancel --- ts/features/spidLogin/store/actions/index.ts | 4 +++- ts/features/spidLogin/store/reducers/index.ts | 5 ++++- ts/screens/authentication/AuthErrorScreen.tsx | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ts/features/spidLogin/store/actions/index.ts b/ts/features/spidLogin/store/actions/index.ts index abd34ed11d1..0abd58cbcdc 100644 --- a/ts/features/spidLogin/store/actions/index.ts +++ b/ts/features/spidLogin/store/actions/index.ts @@ -14,9 +14,11 @@ export const setStandardLoginRequestState = createStandardAction( export const setStandardLoginInLoadingState = createStandardAction( "SET_STANDARD_LOGIN_IN_LOADING_STATE" )(); +export const resetSpidLoginState = createStandardAction("RESET_LOGIN_STATE")(); export type SpidConfigActions = | ActionType | ActionType | ActionType - | ActionType; + | ActionType + | ActionType; diff --git a/ts/features/spidLogin/store/reducers/index.ts b/ts/features/spidLogin/store/reducers/index.ts index 67dab16796f..bfd8477ff86 100644 --- a/ts/features/spidLogin/store/reducers/index.ts +++ b/ts/features/spidLogin/store/reducers/index.ts @@ -6,7 +6,8 @@ import { incrementNativeLoginNativeAttempts, setStandardLoginRequestState, setNativeLoginRequestInfo, - setStandardLoginInLoadingState + setStandardLoginInLoadingState, + resetSpidLoginState } from "../actions"; export type SpidLoginState = { @@ -78,6 +79,8 @@ export const spidLoginReducer = ( } } }; + case getType(resetSpidLoginState): + return spidLoginInitialState; default: return state; } diff --git a/ts/screens/authentication/AuthErrorScreen.tsx b/ts/screens/authentication/AuthErrorScreen.tsx index 9a34bbeef22..cf101bed103 100644 --- a/ts/screens/authentication/AuthErrorScreen.tsx +++ b/ts/screens/authentication/AuthErrorScreen.tsx @@ -11,6 +11,7 @@ import { AuthenticationParamsList } from "../../navigation/params/Authentication import { useIODispatch } from "../../store/hooks"; import { incrementNativeLoginNativeAttempts, + resetSpidLoginState, setStandardLoginInLoadingState } from "../../features/spidLogin/store/actions"; import { UnlockAccessProps } from "./UnlockAccessComponent"; @@ -77,10 +78,11 @@ const AuthErrorScreen = () => { }, [authMethod, navigation, route.params, getNavigationParams, dispatch]); const onCancel = useCallback(() => { + dispatch(resetSpidLoginState()); navigation.navigate(ROUTES.AUTHENTICATION, { screen: ROUTES.AUTHENTICATION_LANDING }); - }, [navigation]); + }, [navigation, dispatch]); return ( Date: Wed, 18 Dec 2024 15:18:29 +0100 Subject: [PATCH 3/5] chore: update snapshots --- .../__tests__/__snapshots__/index.test.ts.snap | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ts/features/common/store/reducers/__tests__/__snapshots__/index.test.ts.snap b/ts/features/common/store/reducers/__tests__/__snapshots__/index.test.ts.snap index 527cdcd64ce..07e535a8ca2 100644 --- a/ts/features/common/store/reducers/__tests__/__snapshots__/index.test.ts.snap +++ b/ts/features/common/store/reducers/__tests__/__snapshots__/index.test.ts.snap @@ -170,6 +170,21 @@ exports[`featuresPersistor should match snapshot 1`] = ` "nativeLogin": { "enabled": true, }, + "spidLogin": { + "nativeLogin": { + "requestInfo": { + "nativeAttempts": 0, + "requestState": "LOADING", + }, + }, + "standardLogin": { + "requestInfo": { + "requestState": { + "kind": "PotNoneLoading", + }, + }, + }, + }, "testLogin": { "kind": "idle", }, From 1c1a515d4fd2f7a6741c94a7dfef048e7505e280 Mon Sep 17 00:00:00 2001 From: ChrisMattew Date: Fri, 20 Dec 2024 17:08:32 +0100 Subject: [PATCH 4/5] chore(IdpLoginScreen): add explanation about the choice of replace instead of navigate --- ts/screens/authentication/IdpLoginScreen.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ts/screens/authentication/IdpLoginScreen.tsx b/ts/screens/authentication/IdpLoginScreen.tsx index 6ba2346131b..293ee965324 100644 --- a/ts/screens/authentication/IdpLoginScreen.tsx +++ b/ts/screens/authentication/IdpLoginScreen.tsx @@ -81,6 +81,8 @@ const styles = StyleSheet.create({ */ const IdpLoginScreen = () => { const dispatch = useIODispatch(); + // The choice was made to use `replace` instead of `navigate` because the former unmounts the current screen, + // ensuring the re-execution of the `useLollipopLoginSource` hook. const { replace } = useIONavigation(); const selectedIdp = useIOSelector(selectedIdentityProviderSelector, _isEqual); const selectedIdpTextData = useIOSelector( @@ -264,6 +266,8 @@ const IdpLoginScreen = () => { }; const navigateToAuthErrorScreen = useCallback(() => { + // The choice was made to use `replace` instead of `navigate` because the former unmounts the current screen, + // ensuring the re-execution of the `useLollipopLoginSource` hook. replace(ROUTES.AUTHENTICATION, { screen: ROUTES.AUTH_ERROR_SCREEN, params: { From 14db7aa563d460574b6d17efbf008ec60962603c Mon Sep 17 00:00:00 2001 From: ChrisMattew Date: Fri, 20 Dec 2024 17:15:21 +0100 Subject: [PATCH 5/5] perf: improve spidLogin selectors --- ts/features/spidLogin/store/selectors/index.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/ts/features/spidLogin/store/selectors/index.ts b/ts/features/spidLogin/store/selectors/index.ts index 9e4c53d55ff..5a9a9e14d72 100644 --- a/ts/features/spidLogin/store/selectors/index.ts +++ b/ts/features/spidLogin/store/selectors/index.ts @@ -1,7 +1,15 @@ +import { createSelector } from "reselect"; import { GlobalState } from "../../../../store/reducers/types"; -export const nativeLoginRequestInfoSelector = (state: GlobalState) => - state.features.loginFeatures.spidLogin.nativeLogin.requestInfo; +export const spidLoginSelector = (state: GlobalState) => + state.features.loginFeatures.spidLogin; -export const standardLoginRequestInfoSelector = (state: GlobalState) => - state.features.loginFeatures.spidLogin.standardLogin.requestInfo; +export const nativeLoginRequestInfoSelector = createSelector( + spidLoginSelector, + ({ nativeLogin }) => nativeLogin.requestInfo +); + +export const standardLoginRequestInfoSelector = createSelector( + spidLoginSelector, + ({ standardLogin }) => standardLogin.requestInfo +);