Skip to content

Commit

Permalink
refactor(auth2): More smoothing out of auth screens (#10895)
Browse files Browse the repository at this point in the history
* refactor(auth): switch to standard formik mode

* fix(auth2): fix weird keyboard performance issues

* refactor(auth2): more smoothing out

* test(auth2): stub out test files

* chore(auth2): be sure to dismiss keyboard after each step
  • Loading branch information
damassi authored Oct 6, 2024
1 parent b32d1aa commit a4eee80
Show file tree
Hide file tree
Showing 23 changed files with 365 additions and 260 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const MyCollectionArtworkFormArtist: React.FC<
}

const handleBack = () => {
// TOOD: The state doesn't need to be stored in the global store
// TODO: The state doesn't need to be stored in the global store
GlobalStore.actions.myCollection.artwork.resetForm()
goBack()
}
Expand Down
5 changes: 2 additions & 3 deletions src/app/Scenes/Onboarding/Auth2/AuthContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { OnboardingWebViewRoute } from "app/Scenes/Onboarding/OnboardingWebView"
import { action, Action, createContextStore } from "easy-peasy"

export type AuthScreens = {
WelcomeStep: undefined
LoginEmailStep: undefined
LoginWelcomeStep: undefined
LoginPasswordStep: { email: string }
LoginOTPStep: { otpMode: "standard" | "on_demand"; email: string; password: string }
ForgotPasswordStep: { requestedPasswordReset: boolean } | undefined
Expand All @@ -29,7 +28,7 @@ interface AuthContextModel {

export const AuthContext = createContextStore<AuthContextModel>({
isMounted: false,
currentScreen: { name: "WelcomeStep" },
currentScreen: { name: "LoginWelcomeStep" },
previousScreens: [],
isModalExpanded: false,

Expand Down
8 changes: 4 additions & 4 deletions src/app/Scenes/Onboarding/Auth2/AuthScenes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ import { AuthScreen } from "app/Scenes/Onboarding/Auth2/components/AuthScreen"
import { ForgotPasswordStep } from "app/Scenes/Onboarding/Auth2/scenes/ForgotPasswordStep"
import { LoginOTPStep } from "app/Scenes/Onboarding/Auth2/scenes/LoginOTPStep"
import { LoginPasswordStep } from "app/Scenes/Onboarding/Auth2/scenes/LoginPasswordStep"
import { LoginWelcomeStep } from "app/Scenes/Onboarding/Auth2/scenes/LoginWelcomeStep"
import { SignUpNameStep } from "app/Scenes/Onboarding/Auth2/scenes/SignUpNameStep"
import { SignUpPasswordStep } from "app/Scenes/Onboarding/Auth2/scenes/SignUpPasswordStep"
import { WelcomeStep } from "app/Scenes/Onboarding/Auth2/scenes/WelcomeStep"
import { ScrollView } from "react-native-gesture-handler"

export const AuthScenes: React.FC = () => {
return (
<>
<ScrollView keyboardShouldPersistTaps="always">
<AuthScreen name="WelcomeStep">
<WelcomeStep />
<ScrollView keyboardShouldPersistTaps="always" scrollEnabled={false}>
<AuthScreen name="LoginWelcomeStep">
<LoginWelcomeStep />
</AuthScreen>

<AuthScreen name="LoginPasswordStep">
Expand Down
5 changes: 5 additions & 0 deletions src/app/Scenes/Onboarding/Auth2/__tests__/AuthApp.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
describe("AuthApp", () => {
it("renders correctly", () => {
// TODO
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
describe("AuthContext", () => {
it("renders correctly", () => {
// TODO
})
})
5 changes: 5 additions & 0 deletions src/app/Scenes/Onboarding/Auth2/__tests__/AuthScenes.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
describe("AuthScenes", () => {
it("renders correctly", () => {
// TODO
})
})
4 changes: 2 additions & 2 deletions src/app/Scenes/Onboarding/Auth2/components/AuthModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Dimensions, KeyboardAvoidingView, Platform } from "react-native"
import { Easing } from "react-native-reanimated"

const HEIGHT = {
WelcomeStep: 320,
LoginWelcomeStep: 320,
LoginEmailStep: 320,
LoginPasswordStep: 320,
ForgotPasswordStep: 320,
Expand All @@ -25,7 +25,7 @@ export const AuthModal: React.FC = ({ children }) => {

const height = (() => {
if (isModalExpanded) {
return HEIGHT[currentScreen?.name ?? "WelcomeStep"]
return HEIGHT[currentScreen?.name ?? "LoginWelcomeStep"]
}

return HEIGHT.collapsed
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
describe("AuthScreen", () => {
it("renders correctly", () => {
// TODO
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
describe("useAuthNavigation", () => {
it("renders correctly", () => {
// TODO
})
})
10 changes: 8 additions & 2 deletions src/app/Scenes/Onboarding/Auth2/hooks/useInputAutofocus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const useInputAutofocus = ({
screenName,
inputRef,
enabled = true,
delay = 0,
delay = 100,
}: UseInputAutofocusProps) => {
const currentScreen = useAuthScreen()

Expand All @@ -27,10 +27,16 @@ export const useInputAutofocus = ({
return
}

let timeout: NodeJS.Timeout

requestAnimationFrame(() => {
setTimeout(() => {
timeout = setTimeout(() => {
inputRef.current?.focus()
}, delay)
})

return () => {
clearTimeout(timeout)
}
}, [currentScreen])
}
60 changes: 29 additions & 31 deletions src/app/Scenes/Onboarding/Auth2/scenes/ForgotPasswordStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from "app/Scenes/Onboarding/Auth2/hooks/useAuthNavigation"
import { useInputAutofocus } from "app/Scenes/Onboarding/Auth2/hooks/useInputAutofocus"
import { GlobalStore } from "app/store/GlobalStore"
import { FormikProvider, useFormik, useFormikContext } from "formik"
import { Formik, useFormikContext } from "formik"
import { useRef } from "react"
import * as Yup from "yup"

Expand All @@ -16,38 +16,36 @@ interface ForgotPasswordStepFormValues {
export const ForgotPasswordStep: React.FC = () => {
const navigation = useAuthNavigation()

const formik = useFormik<ForgotPasswordStepFormValues>({
initialValues: { email: "" },
onSubmit: async ({ email }, { setErrors, resetForm }) => {
const res = await GlobalStore.actions.auth.forgotPassword({
email,
})
if (!res) {
// For security purposes, we are returning a generic error message
setErrors({
email:
"Couldn’t send reset password link. Please try again, or contact [email protected]",
})
} else {
navigation.navigate({
name: "ForgotPasswordStep",
params: { requestedPasswordReset: true },
return (
<Formik<ForgotPasswordStepFormValues>
initialValues={{ email: "" }}
onSubmit={async ({ email }, { setErrors, resetForm }) => {
const res = await GlobalStore.actions.auth.forgotPassword({
email,
})

resetForm()
}
},
validationSchema: Yup.object().shape({
email: Yup.string()
.email("Please provide a valid email address")
.required("Email field is required"),
}),
})

return (
<FormikProvider value={formik}>
if (!res) {
setErrors({
email:
"Couldn’t send reset password link. Please try again, or contact [email protected]",
})
} else {
navigation.navigate({
name: "ForgotPasswordStep",
params: { requestedPasswordReset: true },
})

resetForm()
}
}}
validationSchema={Yup.object().shape({
email: Yup.string()
.email("Please provide a valid email address")
.required("Email field is required"),
})}
>
<ForgotPasswordStepForm />
</FormikProvider>
</Formik>
)
}

Expand Down Expand Up @@ -145,7 +143,7 @@ const ForgotPasswordStepForm: React.FC = () => {

<Button
variant="fillDark"
onPress={() => navigation.navigate({ name: "WelcomeStep" })}
onPress={() => navigation.navigate({ name: "LoginWelcomeStep" })}
block
haptic="impactMedium"
testID="returnToLoginButton"
Expand Down
61 changes: 34 additions & 27 deletions src/app/Scenes/Onboarding/Auth2/scenes/LoginOTPStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import {
useAuthScreen,
} from "app/Scenes/Onboarding/Auth2/hooks/useAuthNavigation"
import { useInputAutofocus } from "app/Scenes/Onboarding/Auth2/hooks/useInputAutofocus"
import { waitForSubmit } from "app/Scenes/Onboarding/Auth2/utils/waitForSubmit"
import { GlobalStore } from "app/store/GlobalStore"
import { FormikProvider, useFormik, useFormikContext } from "formik"
import { Formik, useFormikContext } from "formik"
import { useRef, useState } from "react"
import { Keyboard } from "react-native"
import * as Yup from "yup"

interface LoginOTPStepFormValues {
Expand All @@ -26,34 +28,39 @@ interface LoginOTPStepFormValues {
export const LoginOTPStep: React.FC = () => {
const screen = useAuthScreen()

const formik = useFormik<LoginOTPStepFormValues>({
initialValues: { otp: "" },
onSubmit: async ({ otp }, { setErrors, resetForm }) => {
const res = await GlobalStore.actions.auth.signIn({
oauthProvider: "email",
oauthMode: "email",
email: screen.params?.email,
password: screen.params?.password,
otp: otp.trim(),
})

if (res === "invalid_otp") {
setErrors({ otp: "Invalid two-factor authentication code" })
} else if (res !== "success") {
setErrors({ otp: "Something went wrong. Please try again, or contact [email protected]" })
}

if (res === "success") {
resetForm()
}
},
validationSchema: Yup.string().test("otp", "This field is required", (value) => value !== ""),
})

return (
<FormikProvider value={formik}>
<Formik<LoginOTPStepFormValues>
initialValues={{ otp: "" }}
validateOnChange={false}
validationSchema={Yup.object().shape({
otp: Yup.string().required("This field is required"),
})}
onSubmit={async ({ otp }, { setErrors, resetForm }) => {
Keyboard.dismiss()

const res = await GlobalStore.actions.auth.signIn({
oauthProvider: "email",
oauthMode: "email",
email: screen.params?.email,
password: screen.params?.password,
otp: otp.trim(),
})

await waitForSubmit()

if (res === "invalid_otp") {
setErrors({ otp: "Invalid two-factor authentication code" })
} else if (res !== "success") {
setErrors({ otp: "Something went wrong. Please try again, or contact [email protected]" })
}

if (res === "success") {
resetForm()
}
}}
>
<LoginOTPStepForm />
</FormikProvider>
</Formik>
)
}

Expand Down
Loading

0 comments on commit a4eee80

Please sign in to comment.