Skip to content

Commit

Permalink
Submit fix (#4978)
Browse files Browse the repository at this point in the history
* Fix submit logic

* Fix type

* Align submit task creation 1:1 with callsites

* blegh. `useThrottledValue`

* make `useThrottledValue`'s time required

---------

Co-authored-by: Hailey <[email protected]>
  • Loading branch information
gaearon and haileyok authored Aug 22, 2024
1 parent df5bf28 commit 27bb383
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 32 deletions.
2 changes: 1 addition & 1 deletion src/components/hooks/useThrottledValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {useEffect, useRef, useState} from 'react'

import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'

export function useThrottledValue<T>(value: T, time?: number) {
export function useThrottledValue<T>(value: T, time: number) {
const pendingValueRef = useRef(value)
const [throttledValue, setThrottledValue] = useState(value)

Expand Down
11 changes: 7 additions & 4 deletions src/screens/Signup/StepCaptcha/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {createFullHandle} from '#/lib/strings/handles'
import {logger} from '#/logger'
import {logEvent} from 'lib/statsig/statsig'
import {ScreenTransition} from '#/screens/Login/ScreenTransition'
import {useSignupContext, useSubmitSignup} from '#/screens/Signup/state'
import {useSignupContext} from '#/screens/Signup/state'
import {CaptchaWebView} from '#/screens/Signup/StepCaptcha/CaptchaWebView'
import {atoms as a, useTheme} from '#/alf'
import {FormError} from '#/components/forms/FormError'
Expand All @@ -20,7 +20,6 @@ export function StepCaptcha() {
const {_} = useLingui()
const theme = useTheme()
const {state, dispatch} = useSignupContext()
const submit = useSubmitSignup({state, dispatch})

const [completed, setCompleted] = React.useState(false)

Expand All @@ -42,9 +41,13 @@ export function StepCaptcha() {
(code: string) => {
setCompleted(true)
logEvent('signup:captchaSuccess', {})
submit(code)
const submitTask = {code, mutableProcessed: false}
dispatch({
type: 'submit',
task: submitTask,
})
},
[submit],
[dispatch],
)

const onError = React.useCallback(
Expand Down
11 changes: 6 additions & 5 deletions src/screens/Signup/StepHandle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import {logEvent} from '#/lib/statsig/statsig'
import {createFullHandle, validateHandle} from '#/lib/strings/handles'
import {useAgent} from '#/state/session'
import {ScreenTransition} from '#/screens/Login/ScreenTransition'
import {useSignupContext, useSubmitSignup} from '#/screens/Signup/state'
import {useSignupContext} from '#/screens/Signup/state'
import {atoms as a, useTheme} from '#/alf'
import * as TextField from '#/components/forms/TextField'
import {useThrottledValue} from '#/components/hooks/useThrottledValue'
import {At_Stroke2_Corner0_Rounded as At} from '#/components/icons/At'
import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
import {TimesLarge_Stroke2_Corner0_Rounded as Times} from '#/components/icons/Times'
Expand All @@ -20,10 +21,10 @@ export function StepHandle() {
const {_} = useLingui()
const t = useTheme()
const {state, dispatch} = useSignupContext()
const submit = useSubmitSignup({state, dispatch})
const agent = useAgent()
const handleValueRef = useRef<string>(state.handle)
const [draftValue, setDraftValue] = React.useState(state.handle)
const isLoading = useThrottledValue(state.isLoading, 500)

const onNextPress = React.useCallback(async () => {
const handle = handleValueRef.current.trim()
Expand Down Expand Up @@ -64,7 +65,8 @@ export function StepHandle() {
})
// phoneVerificationRequired is actually whether a captcha is required
if (!state.serviceDescription?.phoneVerificationRequired) {
submit()
const submitTask = {code: undefined, mutableProcessed: false}
dispatch({type: 'submit', task: submitTask})
return
}
dispatch({type: 'next'})
Expand All @@ -74,7 +76,6 @@ export function StepHandle() {
state.activeStep,
state.serviceDescription?.phoneVerificationRequired,
state.userDomain,
submit,
agent,
])

Expand Down Expand Up @@ -175,7 +176,7 @@ export function StepHandle() {
)}
</View>
<BackNextButtons
isLoading={state.isLoading}
isLoading={isLoading}
isNextDisabled={!validCheck.overall}
onBackPress={onBackPress}
onNextPress={onNextPress}
Expand Down
11 changes: 11 additions & 0 deletions src/screens/Signup/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
reducer,
SignupContext,
SignupStep,
useSubmitSignup,
} from '#/screens/Signup/state'
import {StepCaptcha} from '#/screens/Signup/StepCaptcha'
import {StepHandle} from '#/screens/Signup/StepHandle'
Expand All @@ -33,6 +34,7 @@ export function Signup({onPressBack}: {onPressBack: () => void}) {
const {screen} = useAnalytics()
const [state, dispatch] = React.useReducer(reducer, initialState)
const {gtMobile} = useBreakpoints()
const submit = useSubmitSignup()

const activeStarterPack = useActiveStarterPack()
const {
Expand Down Expand Up @@ -81,6 +83,15 @@ export function Signup({onPressBack}: {onPressBack: () => void}) {
}
}, [_, serviceInfo, isError])

React.useEffect(() => {
if (state.pendingSubmit) {
if (!state.pendingSubmit.mutableProcessed) {
state.pendingSubmit.mutableProcessed = true
submit(state, dispatch)
}
}
}, [state, dispatch, submit])

return (
<SignupContext.Provider value={{state, dispatch}}>
<LoggedOutLayout
Expand Down
43 changes: 21 additions & 22 deletions src/screens/Signup/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ export enum SignupStep {
CAPTCHA,
}

type SubmitTask = {
code: string | undefined
mutableProcessed: boolean // OK to mutate assuming it's never read in render.
}

export type SignupState = {
hasPrev: boolean
activeStep: SignupStep
Expand All @@ -41,6 +46,8 @@ export type SignupState = {

error: string
isLoading: boolean

pendingSubmit: null | SubmitTask
}

export type SignupAction =
Expand All @@ -58,6 +65,7 @@ export type SignupAction =
| {type: 'setVerificationCode'; value: string}
| {type: 'setError'; value: string}
| {type: 'setIsLoading'; value: boolean}
| {type: 'submit'; task: SubmitTask}

export const initialState: SignupState = {
hasPrev: false,
Expand All @@ -74,6 +82,8 @@ export const initialState: SignupState = {

error: '',
isLoading: false,

pendingSubmit: null,
}

export function is13(date: Date) {
Expand Down Expand Up @@ -149,6 +159,10 @@ export function reducer(s: SignupState, a: SignupAction): SignupState {
next.error = a.value
break
}
case 'submit': {
next.pendingSubmit = a.task
break
}
}

next.hasPrev = next.activeStep !== SignupStep.INFO
Expand All @@ -169,19 +183,17 @@ interface IContext {
export const SignupContext = React.createContext<IContext>({} as IContext)
export const useSignupContext = () => React.useContext(SignupContext)

export function useSubmitSignup({
state,
dispatch,
}: {
state: SignupState
dispatch: (action: SignupAction) => void
}) {
export function useSubmitSignup() {
const {_} = useLingui()
const {createAccount} = useSessionApi()
const onboardingDispatch = useOnboardingDispatch()

return useCallback(
async (verificationCode?: string) => {
async (
state: SignupState,
dispatch: (action: SignupAction) => void,
verificationCode?: string,
) => {
if (!state.email) {
dispatch({type: 'setStep', value: SignupStep.INFO})
return dispatch({
Expand Down Expand Up @@ -270,19 +282,6 @@ export function useSubmitSignup({
dispatch({type: 'setIsLoading', value: false})
}
},
[
state.email,
state.password,
state.handle,
state.serviceDescription?.phoneVerificationRequired,
state.serviceUrl,
state.userDomain,
state.inviteCode,
state.dateOfBirth,
dispatch,
_,
onboardingDispatch,
createAccount,
],
[_, onboardingDispatch, createAccount],
)
}

0 comments on commit 27bb383

Please sign in to comment.