From 1e8e640944780cc73a6cd9f8ce457f90986c9c7a Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Mon, 22 Jul 2024 16:55:42 +0800 Subject: [PATCH] refactor(console): keep button loading before redirecting to sign-in success page --- .../use-social-link-related-user.ts | 2 +- .../use-continue-flow-code-verification.ts | 2 +- .../use-register-flow-code-verification.ts | 4 +-- .../use-sign-in-flow-code-verification.ts | 4 +-- .../src/hooks/use-global-redirect-to.ts | 30 +++++++++++++++---- .../src/hooks/use-password-sign-in.ts | 2 +- .../src/hooks/use-send-mfa-payload.ts | 2 +- packages/experience/src/hooks/use-skip-mfa.ts | 2 +- .../src/hooks/use-social-link-account.ts | 2 +- .../src/hooks/use-social-register.ts | 2 +- .../experience/src/pages/Consent/index.tsx | 2 +- .../src/pages/Continue/SetPassword/index.tsx | 4 +-- .../Continue/SetUsername/use-set-username.ts | 2 +- .../src/pages/RegisterPassword/index.tsx | 4 +-- .../use-single-sign-on-listener.ts | 4 +-- 15 files changed, 44 insertions(+), 24 deletions(-) diff --git a/packages/experience/src/containers/SocialLinkAccount/use-social-link-related-user.ts b/packages/experience/src/containers/SocialLinkAccount/use-social-link-related-user.ts index 694772f3212..dd035d4931e 100644 --- a/packages/experience/src/containers/SocialLinkAccount/use-social-link-related-user.ts +++ b/packages/experience/src/containers/SocialLinkAccount/use-social-link-related-user.ts @@ -24,7 +24,7 @@ const useBindSocialRelatedUser = () => { } if (result?.redirectTo) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [asyncBindSocialRelatedUser, handleError, preSignInErrorHandler, redirectTo] diff --git a/packages/experience/src/containers/VerificationCode/use-continue-flow-code-verification.ts b/packages/experience/src/containers/VerificationCode/use-continue-flow-code-verification.ts index e500de48372..946d42cfa43 100644 --- a/packages/experience/src/containers/VerificationCode/use-continue-flow-code-verification.ts +++ b/packages/experience/src/containers/VerificationCode/use-continue-flow-code-verification.ts @@ -78,7 +78,7 @@ const useContinueFlowCodeVerification = ( } if (result?.redirectTo) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [ diff --git a/packages/experience/src/containers/VerificationCode/use-register-flow-code-verification.ts b/packages/experience/src/containers/VerificationCode/use-register-flow-code-verification.ts index 0dec679a846..5df3843d85f 100644 --- a/packages/experience/src/containers/VerificationCode/use-register-flow-code-verification.ts +++ b/packages/experience/src/containers/VerificationCode/use-register-flow-code-verification.ts @@ -69,7 +69,7 @@ const useRegisterFlowCodeVerification = ( } if (result?.redirectTo) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, onCancel: () => { @@ -118,7 +118,7 @@ const useRegisterFlowCodeVerification = ( } if (result?.redirectTo) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [errorCallback, errorHandlers, handleError, redirectTo, verifyVerificationCode] diff --git a/packages/experience/src/containers/VerificationCode/use-sign-in-flow-code-verification.ts b/packages/experience/src/containers/VerificationCode/use-sign-in-flow-code-verification.ts index 16a6e0f7f99..68f9987cf0e 100644 --- a/packages/experience/src/containers/VerificationCode/use-sign-in-flow-code-verification.ts +++ b/packages/experience/src/containers/VerificationCode/use-sign-in-flow-code-verification.ts @@ -72,7 +72,7 @@ const useSignInFlowCodeVerification = ( } if (result?.redirectTo) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, onCancel: () => { @@ -119,7 +119,7 @@ const useSignInFlowCodeVerification = ( } if (result?.redirectTo) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [asyncSignInWithVerificationCodeIdentifier, errorHandlers, handleError, redirectTo] diff --git a/packages/experience/src/hooks/use-global-redirect-to.ts b/packages/experience/src/hooks/use-global-redirect-to.ts index b6c83148b4d..168d052d72d 100644 --- a/packages/experience/src/hooks/use-global-redirect-to.ts +++ b/packages/experience/src/hooks/use-global-redirect-to.ts @@ -1,27 +1,47 @@ +import { noop } from '@react-spring/shared'; import { useCallback, useContext } from 'react'; import PageContext from '@/Providers/PageContextProvider/PageContext'; import UserInteractionContext from '@/Providers/UserInteractionContextProvider/UserInteractionContext'; /** - * This hook provides a function that process the app redirection after user successfully signs in. - * Use window.location.replace to handle the redirection. - * Set the global loading state to true before redirecting. - * This is to prevent the user from interacting with the app while the redirection is in progress. + * Hook for global redirection after successful login. + * + * This hook provides an async function that represents the final step in the login process. + * It sets a global loading state, clears the interaction context, and then redirects the user. + * + * The returned async function will never resolve, as the page will be redirected before + * the Promise can settle. This behavior is intentional and serves to maintain the loading + * state on the interaction element (e.g., a button) that triggered the successful login. */ function useGlobalRedirectTo() { const { setLoading } = useContext(PageContext); const { clearInteractionContextSessionStorage } = useContext(UserInteractionContext); const redirectTo = useCallback( - (url: string | URL) => { + async (url: string | URL): Promise => { + /** + * Set global loading state to true + * This prevents further user interaction during the redirect process + */ setLoading(true); /** * Clear all identifier input values from the storage once the interaction is submitted. * The Identifier cache should be session-isolated, so it should be cleared after the interaction is completed. */ clearInteractionContextSessionStorage(); + /** + * Perform the actual redirect + * This is a synchronous operation and will immediately unload the current page + */ window.location.replace(url); + + /** + * Return a Promise that never resolves + * This ensures that any async function awaiting this redirect will never continue + * Thus maintaining the loading state on the UI until the new page is loaded + */ + return new Promise(noop); }, [clearInteractionContextSessionStorage, setLoading] ); diff --git a/packages/experience/src/hooks/use-password-sign-in.ts b/packages/experience/src/hooks/use-password-sign-in.ts index 459cfa15c09..23cce8bcb07 100644 --- a/packages/experience/src/hooks/use-password-sign-in.ts +++ b/packages/experience/src/hooks/use-password-sign-in.ts @@ -53,7 +53,7 @@ const usePasswordSignIn = () => { } if (result?.redirectTo) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [asyncSignIn, checkSingleSignOn, errorHandlers, handleError, redirectTo] diff --git a/packages/experience/src/hooks/use-send-mfa-payload.ts b/packages/experience/src/hooks/use-send-mfa-payload.ts index 9d72a94719c..e407bb3231f 100644 --- a/packages/experience/src/hooks/use-send-mfa-payload.ts +++ b/packages/experience/src/hooks/use-send-mfa-payload.ts @@ -50,7 +50,7 @@ const useSendMfaPayload = () => { } if (result) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [asyncSendMfaPayload, handleError, preSignInErrorHandler, redirectTo] diff --git a/packages/experience/src/hooks/use-skip-mfa.ts b/packages/experience/src/hooks/use-skip-mfa.ts index 233bfed1d32..af480682b4a 100644 --- a/packages/experience/src/hooks/use-skip-mfa.ts +++ b/packages/experience/src/hooks/use-skip-mfa.ts @@ -22,7 +22,7 @@ const useSkipMfa = () => { } if (result) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [asyncSkipMfa, handleError, preSignInErrorHandler, redirectTo]); }; diff --git a/packages/experience/src/hooks/use-social-link-account.ts b/packages/experience/src/hooks/use-social-link-account.ts index 16c38e7f3cf..4e75ffbf153 100644 --- a/packages/experience/src/hooks/use-social-link-account.ts +++ b/packages/experience/src/hooks/use-social-link-account.ts @@ -22,7 +22,7 @@ const useLinkSocial = () => { } if (result?.redirectTo) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [asyncLinkWithSocial, handleError, redirectTo] diff --git a/packages/experience/src/hooks/use-social-register.ts b/packages/experience/src/hooks/use-social-register.ts index 8d128f53857..60178007780 100644 --- a/packages/experience/src/hooks/use-social-register.ts +++ b/packages/experience/src/hooks/use-social-register.ts @@ -25,7 +25,7 @@ const useSocialRegister = (connectorId?: string, replace?: boolean) => { } if (result?.redirectTo) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [asyncRegisterWithSocial, handleError, preSignInErrorHandler, redirectTo] diff --git a/packages/experience/src/pages/Consent/index.tsx b/packages/experience/src/pages/Consent/index.tsx index 8052e11d831..3c594989a16 100644 --- a/packages/experience/src/pages/Consent/index.tsx +++ b/packages/experience/src/pages/Consent/index.tsx @@ -43,7 +43,7 @@ const Consent = () => { } if (result?.redirectTo) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [asyncConsent, handleError, redirectTo, selectedOrganization?.id]); diff --git a/packages/experience/src/pages/Continue/SetPassword/index.tsx b/packages/experience/src/pages/Continue/SetPassword/index.tsx index 64530f584ee..da72cd53d1d 100644 --- a/packages/experience/src/pages/Continue/SetPassword/index.tsx +++ b/packages/experience/src/pages/Continue/SetPassword/index.tsx @@ -34,9 +34,9 @@ const SetPassword = () => { [navigate, preSignInErrorHandler, show] ); const successHandler: SuccessHandler = useCallback( - (result) => { + async (result) => { if (result?.redirectTo) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [redirectTo] diff --git a/packages/experience/src/pages/Continue/SetUsername/use-set-username.ts b/packages/experience/src/pages/Continue/SetUsername/use-set-username.ts index 4f51873f9c4..343ac0de6cb 100644 --- a/packages/experience/src/pages/Continue/SetUsername/use-set-username.ts +++ b/packages/experience/src/pages/Continue/SetUsername/use-set-username.ts @@ -41,7 +41,7 @@ const useSetUsername = () => { } if (result?.redirectTo) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [asyncAddProfile, errorHandlers, handleError, redirectTo] diff --git a/packages/experience/src/pages/RegisterPassword/index.tsx b/packages/experience/src/pages/RegisterPassword/index.tsx index b276b2c4ea9..4c0c722aa70 100644 --- a/packages/experience/src/pages/RegisterPassword/index.tsx +++ b/packages/experience/src/pages/RegisterPassword/index.tsx @@ -40,9 +40,9 @@ const RegisterPassword = () => { ); const successHandler: SuccessHandler = useCallback( - (result) => { + async (result) => { if (result && 'redirectTo' in result) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [redirectTo] diff --git a/packages/experience/src/pages/SocialSignInWebCallback/use-single-sign-on-listener.ts b/packages/experience/src/pages/SocialSignInWebCallback/use-single-sign-on-listener.ts index 678b1872d34..bfc0b8da19e 100644 --- a/packages/experience/src/pages/SocialSignInWebCallback/use-single-sign-on-listener.ts +++ b/packages/experience/src/pages/SocialSignInWebCallback/use-single-sign-on-listener.ts @@ -41,7 +41,7 @@ const useSingleSignOnRegister = () => { } if (result?.redirectTo) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [agreeToTermsPolicy, handleError, navigate, redirectTo, request, termsValidation] @@ -104,7 +104,7 @@ const useSingleSignOnListener = (connectorId: string) => { } if (result?.redirectTo) { - redirectTo(result.redirectTo); + await redirectTo(result.redirectTo); } }, [