feat: optimize sign in experience (#4099)

This commit is contained in:
Qi
2023-09-02 14:07:38 +08:00
committed by GitHub
parent be9ae57a8e
commit 3edfc46307
4 changed files with 59 additions and 49 deletions

View File

@@ -22,11 +22,7 @@ export const AfterSignInSendEmail = ({
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const loginStatus = useCurrentLoginStatus(); const loginStatus = useCurrentLoginStatus();
const { resendCountDown, allowSendEmail, signIn } = useAuth({ const { resendCountDown, allowSendEmail, signIn } = useAuth();
onNoAccess: useCallback(() => {
setAuthState('noAccess');
}, [setAuthState]),
});
if (loginStatus === 'authenticated') { if (loginStatus === 'authenticated') {
onSignedIn?.(); onSignedIn?.();
} }

View File

@@ -21,11 +21,7 @@ export const AfterSignUpSendEmail: FC<AuthPanelProps> = ({
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const loginStatus = useCurrentLoginStatus(); const loginStatus = useCurrentLoginStatus();
const { resendCountDown, allowSendEmail, signUp } = useAuth({ const { resendCountDown, allowSendEmail, signUp } = useAuth();
onNoAccess: useCallback(() => {
setAuthState('noAccess');
}, [setAuthState]),
});
if (loginStatus === 'authenticated') { if (loginStatus === 'authenticated') {
onSignedIn?.(); onSignedIn?.();

View File

@@ -16,7 +16,7 @@ import { useCurrentLoginStatus } from '../../../hooks/affine/use-current-login-s
import { emailRegex } from '../../../utils/email-regex'; import { emailRegex } from '../../../utils/email-regex';
import type { AuthPanelProps } from './index'; import type { AuthPanelProps } from './index';
import * as style from './style.css'; import * as style from './style.css';
import { useAuth } from './use-auth'; import { INTERNAL_BETA_URL, useAuth } from './use-auth';
function validateEmail(email: string) { function validateEmail(email: string) {
return emailRegex.test(email); return emailRegex.test(email);
@@ -31,12 +31,14 @@ export const SignIn: FC<AuthPanelProps> = ({
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const loginStatus = useCurrentLoginStatus(); const loginStatus = useCurrentLoginStatus();
const { resendCountDown, allowSendEmail, signIn, signUp, signInWithGoogle } = const {
useAuth({ isMutating: isSigningIn,
onNoAccess: useCallback(() => { resendCountDown,
setAuthState('noAccess'); allowSendEmail,
}, [setAuthState]), signIn,
}); signUp,
signInWithGoogle,
} = useAuth();
const { trigger: verifyUser, isMutating } = useMutation({ const { trigger: verifyUser, isMutating } = useMutation({
mutation: getUserQuery, mutation: getUserQuery,
@@ -55,16 +57,20 @@ export const SignIn: FC<AuthPanelProps> = ({
setIsValidEmail(true); setIsValidEmail(true);
const { user } = await verifyUser({ email }); const { user } = await verifyUser({ email });
setAuthEmail(email); setAuthEmail(email);
if (user) { if (user) {
const res = await signIn(email);
if (res?.status === 403 && res?.url === INTERNAL_BETA_URL) {
return setAuthState('noAccess');
}
setAuthState('afterSignInSendEmail'); setAuthState('afterSignInSendEmail');
await signIn(email);
} else { } else {
const res = await signUp(email);
if (res?.status === 403 && res?.url === INTERNAL_BETA_URL) {
return setAuthState('noAccess');
}
setAuthState('afterSignUpSendEmail'); setAuthState('afterSignUpSendEmail');
await signUp(email);
} }
}, [email, setAuthEmail, setAuthState, signIn, signUp, verifyUser]); }, [email, setAuthEmail, setAuthState, signIn, signUp, verifyUser]);
@@ -112,7 +118,7 @@ export const SignIn: FC<AuthPanelProps> = ({
size="extraLarge" size="extraLarge"
data-testid="continue-login-button" data-testid="continue-login-button"
block block
loading={isMutating} loading={isMutating || isSigningIn}
disabled={!allowSendEmail} disabled={!allowSendEmail}
icon={ icon={
allowSendEmail || isMutating ? ( allowSendEmail || isMutating ? (

View File

@@ -7,7 +7,7 @@ import { useCallback } from 'react';
import { signInCloud } from '../../../utils/cloud-utils'; import { signInCloud } from '../../../utils/cloud-utils';
const COUNT_DOWN_TIME = 60; const COUNT_DOWN_TIME = 60;
const INTERNAL_BETA_URL = `https://community.affine.pro/c/insider-general/`; export const INTERNAL_BETA_URL = `https://community.affine.pro/c/insider-general/`;
function handleSendEmailError( function handleSendEmailError(
res: SignInResponse | undefined | void, res: SignInResponse | undefined | void,
@@ -20,21 +20,16 @@ function handleSendEmailError(
type: 'error', type: 'error',
}); });
} }
// if (res?.status === 403 && res?.url === INTERNAL_BETA_URL) {
// pushNotification({
// title: 'Sign up error',
// message: `You don't have early access permission\nVisit ${INTERNAL_BETA_URL} for more information`,
// type: 'error',
// });
// }
} }
type AuthStoreAtom = { type AuthStoreAtom = {
allowSendEmail: boolean; allowSendEmail: boolean;
resendCountDown: number; resendCountDown: number;
isMutating: boolean;
}; };
export const authStoreAtom = atom<AuthStoreAtom>({ export const authStoreAtom = atom<AuthStoreAtom>({
isMutating: false,
allowSendEmail: true, allowSendEmail: true,
resendCountDown: COUNT_DOWN_TIME, resendCountDown: COUNT_DOWN_TIME,
}); });
@@ -46,6 +41,7 @@ const countDownAtom = atom(
const countDown = get(authStoreAtom).resendCountDown; const countDown = get(authStoreAtom).resendCountDown;
if (countDown === 0) { if (countDown === 0) {
set(authStoreAtom, { set(authStoreAtom, {
isMutating: false,
allowSendEmail: true, allowSendEmail: true,
resendCountDown: COUNT_DOWN_TIME, resendCountDown: COUNT_DOWN_TIME,
}); });
@@ -53,6 +49,7 @@ const countDownAtom = atom(
return; return;
} }
set(authStoreAtom, { set(authStoreAtom, {
isMutating: false,
resendCountDown: countDown - 1, resendCountDown: countDown - 1,
allowSendEmail: false, allowSendEmail: false,
}); });
@@ -60,18 +57,19 @@ const countDownAtom = atom(
} }
); );
export const useAuth = ({ onNoAccess }: { onNoAccess: () => void }) => { export const useAuth = () => {
const pushNotification = useSetAtom(pushNotificationAtom); const pushNotification = useSetAtom(pushNotificationAtom);
const [authStore, setAuthStore] = useAtom(authStoreAtom); const [authStore, setAuthStore] = useAtom(authStoreAtom);
const startResendCountDown = useSetAtom(countDownAtom); const startResendCountDown = useSetAtom(countDownAtom);
const signIn = useCallback( const signIn = useCallback(
async (email: string) => { async (email: string) => {
setAuthStore(() => ({ setAuthStore(prev => {
allowSendEmail: false, return {
resendCountDown: COUNT_DOWN_TIME, ...prev,
})); isMutating: true,
startResendCountDown(); };
});
const res = await signInCloud('email', { const res = await signInCloud('email', {
email: email, email: email,
@@ -81,20 +79,27 @@ export const useAuth = ({ onNoAccess }: { onNoAccess: () => void }) => {
handleSendEmailError(res, pushNotification); handleSendEmailError(res, pushNotification);
if (res?.status === 403 && res?.url === INTERNAL_BETA_URL) { setAuthStore({
onNoAccess(); isMutating: false,
} allowSendEmail: false,
resendCountDown: COUNT_DOWN_TIME,
});
startResendCountDown();
return res;
}, },
[onNoAccess, pushNotification, setAuthStore, startResendCountDown] [pushNotification, setAuthStore, startResendCountDown]
); );
const signUp = useCallback( const signUp = useCallback(
async (email: string) => { async (email: string) => {
setAuthStore({ setAuthStore(prev => {
allowSendEmail: false, return {
resendCountDown: COUNT_DOWN_TIME, ...prev,
isMutating: true,
};
}); });
startResendCountDown();
const res = await signInCloud('email', { const res = await signInCloud('email', {
email: email, email: email,
@@ -104,11 +109,17 @@ export const useAuth = ({ onNoAccess }: { onNoAccess: () => void }) => {
handleSendEmailError(res, pushNotification); handleSendEmailError(res, pushNotification);
if (res?.status === 403 && res?.url === INTERNAL_BETA_URL) { setAuthStore({
onNoAccess(); isMutating: false,
} allowSendEmail: false,
resendCountDown: COUNT_DOWN_TIME,
});
startResendCountDown();
return res;
}, },
[onNoAccess, pushNotification, setAuthStore, startResendCountDown] [pushNotification, setAuthStore, startResendCountDown]
); );
const signInWithGoogle = useCallback(() => { const signInWithGoogle = useCallback(() => {
@@ -118,6 +129,7 @@ export const useAuth = ({ onNoAccess }: { onNoAccess: () => void }) => {
return { return {
allowSendEmail: authStore.allowSendEmail, allowSendEmail: authStore.allowSendEmail,
resendCountDown: authStore.resendCountDown, resendCountDown: authStore.resendCountDown,
isMutating: authStore.isMutating,
signUp, signUp,
signIn, signIn,
signInWithGoogle, signInWithGoogle,