import React, {useRef} from 'react' import {View} from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {logEvent} from '#/lib/statsig/statsig' import { createFullHandle, maxServiceHandleLength, validateServiceHandle, } from '#/lib/strings/handles' import {useAgent} from '#/state/session' import {ScreenTransition} from '#/screens/Login/ScreenTransition' 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' import {Text} from '#/components/Typography' import {BackNextButtons} from './BackNextButtons' export function StepHandle() { const {_} = useLingui() const t = useTheme() const {state, dispatch} = useSignupContext() const agent = useAgent() const handleValueRef = useRef(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() dispatch({ type: 'setHandle', value: handle, }) const newValidCheck = validateServiceHandle(handle, state.userDomain) if (!newValidCheck.overall) { return } try { dispatch({type: 'setIsLoading', value: true}) const res = await agent.resolveHandle({ handle: createFullHandle(handle, state.userDomain), }) if (res.data.did) { dispatch({ type: 'setError', value: _(msg`That handle is already taken.`), }) return } } catch (e) { // Don't have to handle } finally { dispatch({type: 'setIsLoading', value: false}) } logEvent('signup:nextPressed', { activeStep: state.activeStep, phoneVerificationRequired: state.serviceDescription?.phoneVerificationRequired, }) // phoneVerificationRequired is actually whether a captcha is required if (!state.serviceDescription?.phoneVerificationRequired) { dispatch({ type: 'submit', task: {verificationCode: undefined, mutableProcessed: false}, }) return } dispatch({type: 'next'}) }, [ _, dispatch, state.activeStep, state.serviceDescription?.phoneVerificationRequired, state.userDomain, agent, ]) const onBackPress = React.useCallback(() => { const handle = handleValueRef.current.trim() dispatch({ type: 'setHandle', value: handle, }) dispatch({type: 'prev'}) logEvent('signup:backPressed', { activeStep: state.activeStep, }) }, [dispatch, state.activeStep]) const validCheck = validateServiceHandle(draftValue, state.userDomain) return ( { if (state.error) { dispatch({type: 'setError', value: ''}) } // These need to always be in sync. handleValueRef.current = val setDraftValue(val) }} label={_(msg`Type your desired username`)} defaultValue={draftValue} autoCapitalize="none" autoCorrect={false} autoFocus autoComplete="off" /> {draftValue !== '' && ( Your full username will be{' '} @{createFullHandle(draftValue, state.userDomain)} )} {draftValue !== '' && ( {state.error ? ( {state.error} ) : undefined} {validCheck.hyphenStartOrEnd ? ( Only contains letters, numbers, and hyphens ) : ( Doesn't begin or end with a hyphen )} {!validCheck.totalLength ? ( No longer than {maxServiceHandleLength(state.userDomain)}{' '} characters ) : ( At least 3 characters )} )} ) } function IsValidIcon({valid}: {valid: boolean}) { const t = useTheme() if (!valid) { return } return }