Submit fix (#4978)
* Fix submit logic * Fix type * Align submit task creation 1:1 with callsites * blegh. `useThrottledValue` * make `useThrottledValue`'s time required --------- Co-authored-by: Hailey <me@haileyok.com>zio/stable
parent
df5bf28e61
commit
27bb383268
|
@ -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)
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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(
|
||||
|
|
|
@ -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'
|
||||
|
@ -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()
|
||||
|
@ -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'})
|
||||
|
@ -74,7 +76,6 @@ export function StepHandle() {
|
|||
state.activeStep,
|
||||
state.serviceDescription?.phoneVerificationRequired,
|
||||
state.userDomain,
|
||||
submit,
|
||||
agent,
|
||||
])
|
||||
|
||||
|
@ -175,7 +176,7 @@ export function StepHandle() {
|
|||
)}
|
||||
</View>
|
||||
<BackNextButtons
|
||||
isLoading={state.isLoading}
|
||||
isLoading={isLoading}
|
||||
isNextDisabled={!validCheck.overall}
|
||||
onBackPress={onBackPress}
|
||||
onNextPress={onNextPress}
|
||||
|
|
|
@ -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'
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -41,6 +46,8 @@ export type SignupState = {
|
|||
|
||||
error: string
|
||||
isLoading: boolean
|
||||
|
||||
pendingSubmit: null | SubmitTask
|
||||
}
|
||||
|
||||
export type SignupAction =
|
||||
|
@ -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,
|
||||
|
@ -74,6 +82,8 @@ export const initialState: SignupState = {
|
|||
|
||||
error: '',
|
||||
isLoading: false,
|
||||
|
||||
pendingSubmit: null,
|
||||
}
|
||||
|
||||
export function is13(date: Date) {
|
||||
|
@ -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
|
||||
|
@ -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({
|
||||
|
@ -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],
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue