/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
shared/signup/username.tsx
193 строки
6 KB
chrisnojima
refactor(styles): theme via hooks, no android remount (#29515)
08 авг 2026, 02:24
Не верифицирован
08 авг 2026, 02:24
a41d38e
Код
Авторство
О чём код?
import * as C from '@/constants' import * as Kb from '@/common-adapters' import * as React from 'react' import {SignupScreen, errorBanner, desktopInputWidth} from './common' import {startProvision} from '@/provision/flow' import * as T from '@/constants/types' import {RPCError} from '@/util/errors' import {ignorePromise} from '@/constants/utils' import logger from '@/logger' import {isValidUsername} from '@/util/simple-validators' import type {StaticScreenProps} from '@react-navigation/core' import {clearSignupDeviceNameDraft} from './device-name-draft' type Props = StaticScreenProps<{inviteCode?: string; username?: string}> const ConnectedEnterUsername = (p: Props) => { const initialUsername = p.route.params.username ?? '' const inviteCode = p.route.params.inviteCode ?? '' const waiting = C.Waiting.useAnyWaiting(C.waitingKeySignup) const {navigateAppend, navigateUp} = C.Router2 const onBack = () => { clearSignupDeviceNameDraft() navigateUp() } const [error, setError] = React.useState('') const [usernameTaken, setUsernameTaken] = React.useState('') const onUsernameChange = () => { setError('') setUsernameTaken('') } const onContinue = (username: string) => { onUsernameChange() const localError = isValidUsername(username) if (localError) { setError(localError) return } const f = async () => { logger.info(`checking ${username}`) try { await T.RPCGen.signupCheckUsernameAvailableRpcPromise({username}, C.waitingKeySignup) logger.info(`${username} success`) navigateAppend({name: 'signupEnterDevicename', params: {inviteCode, username}}) } catch (error_) { if (error_ instanceof RPCError) { logger.warn(`${username} error: ${error_.message}`) if (error_.code === T.RPCGen.StatusCode.scbadsignupusernametaken) { setUsernameTaken(username) return } setError(error_.code === T.RPCGen.StatusCode.scinputerror ? C.usernameHint : error_.desc) } } } ignorePromise(f()) } const onLogin = (username: string) => startProvision(username) return ( <EnterUsername error={error} initialUsername={initialUsername} onBack={onBack} onContinue={onContinue} onLogin={onLogin} onUsernameChange={onUsernameChange} usernameTaken={usernameTaken} waiting={waiting} /> ) } type EnterUsernameProps = { error: string initialUsername?: string onBack: () => void onContinue: (username: string) => void onLogin: (username: string) => void onUsernameChange: () => void usernameTaken?: string waiting: boolean } const EnterUsername = (props: EnterUsernameProps) => { const styles = useStyles() const { onLogin, usernameTaken, error, initialUsername, onBack, onContinue: _onContinue, onUsernameChange, waiting, } = props const [username, onChangeUsername] = React.useState(initialUsername || '') const [acceptedEULA, setAcceptedEULA] = React.useState(false) const eulaUrlProps = Kb.useClickURL('https://keybase.io/docs/acceptable-use-policy') const usernameTrimmed = username.trim() const disabled = !usernameTrimmed || usernameTrimmed === usernameTaken || !acceptedEULA const _onChangeUsername = (username: string) => { onChangeUsername(username) onUsernameChange() } const onContinue = () => { if (disabled || waiting) { return } onChangeUsername(usernameTrimmed) // maybe trim the input _onContinue(usernameTrimmed) } const eulaLabel = ( <Kb.Text type={isMobile ? 'BodySmall' : 'Body'} style={styles.eulaText}> I accept the{' '} <Kb.Text type={isMobile ? 'BodySmallPrimaryLink' : 'BodyPrimaryLink'} {...eulaUrlProps}> Keybase Acceptable Use Policy </Kb.Text> </Kb.Text> ) const eulaBlock = ( <Kb.Checkbox label={eulaLabel} checked={acceptedEULA} onCheck={() => setAcceptedEULA(s => !s)} /> ) return ( <SignupScreen banners={ <> {usernameTaken ? ( <Kb.Banner key="usernameTaken" color="blue"> <Kb.BannerParagraph bannerColor="blue" content={[ 'Sorry, this username is already taken. Did you mean to ', { onClick: () => usernameTaken && onLogin(usernameTaken), text: `log in as ${usernameTaken}`, }, '?', ]} /> </Kb.Banner> ) : null} {errorBanner(error)} </> } buttons={[ { disabled, label: 'Continue', onClick: onContinue, type: 'Success', waiting: waiting, }, ]} footer={isMobile ? eulaBlock : undefined} hideDesktopHeader={!isMobile} onBack={onBack} title="Create account" > <Kb.ScrollView> <Kb.Box2 alignItems="center" gap={isMobile ? 'small' : 'medium'} direction="vertical" flex={1} fullWidth={true} > <Kb.Avatar size={C.isLargeScreen ? 96 : 64} /> <Kb.Box2 direction="vertical" fullWidth={Kb.Styles.isPhone} gap="tiny"> <Kb.Input3 textType="BodySemibold" autoFocus={true} containerStyle={styles.input} placeholder="Pick a username" maxLength={C.maxUsernameLength} onChangeText={_onChangeUsername} onEnterKeyDown={onContinue} value={username} /> <Kb.Text type="BodySmall">Your username is unique and can not be changed in the future.</Kb.Text> </Kb.Box2> {!isMobile && eulaBlock} </Kb.Box2> </Kb.ScrollView> </SignupScreen> ) } const useStyles = Kb.Styles.createStyleHook(() => ({ eulaText: {alignSelf: 'center' as const}, input: desktopInputWidth, })) export default ConnectedEnterUsername