Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ELI5] Add new user hint for handle screen #6937

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 75 additions & 56 deletions src/screens/Signup/StepHandle.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, {useRef} from 'react'
import {View} from 'react-native'
import {LayoutAnimation, View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'

Expand All @@ -9,10 +9,11 @@ import {
maxServiceHandleLength,
validateHandle,
} from '#/lib/strings/handles'
import {useAgent} from '#/state/session'
import {useAgent, useSession} from '#/state/session'
import {ScreenTransition} from '#/screens/Login/ScreenTransition'
import {useSignupContext} from '#/screens/Signup/state'
import {atoms as a, useTheme} from '#/alf'
import {Admonition} from '#/components/Admonition'
import * as TextField from '#/components/forms/TextField'
import {useThrottledValue} from '#/components/hooks/useThrottledValue'
import {At_Stroke2_Corner0_Rounded as At} from '#/components/icons/At'
Expand All @@ -29,6 +30,9 @@ export function StepHandle() {
const handleValueRef = useRef<string>(state.handle)
const [draftValue, setDraftValue] = React.useState(state.handle)
const isLoading = useThrottledValue(state.isLoading, 500)
const {accounts} = useSession()

const isFirstTimeUser = accounts.length === 0

const onNextPress = React.useCallback(async () => {
const handle = handleValueRef.current.trim()
Expand Down Expand Up @@ -111,6 +115,12 @@ export function StepHandle() {
dispatch({type: 'setError', value: ''})
}

if (val === '' || handleValueRef.current === '') {
LayoutAnimation.configureNext(
LayoutAnimation.Presets.easeInEaseOut,
)
}

// These need to always be in sync.
handleValueRef.current = val
setDraftValue(val)
Expand All @@ -124,64 +134,73 @@ export function StepHandle() {
/>
</TextField.Root>
</View>
{draftValue !== '' && (
<Text style={[a.text_md]}>
<Trans>Your full username will be</Trans>{' '}
<Text style={[a.text_md, a.font_bold]}>
@{createFullHandle(draftValue, state.userDomain)}
</Text>
</Text>
)}

{draftValue !== '' && (
<View
style={[
a.w_full,
a.rounded_sm,
a.border,
a.p_md,
a.gap_sm,
t.atoms.border_contrast_low,
]}>
{state.error ? (
<View style={[a.w_full, a.flex_row, a.align_center, a.gap_sm]}>
<IsValidIcon valid={false} />
<Text style={[a.text_md, a.flex_1]}>{state.error}</Text>
</View>
) : undefined}
{validCheck.hyphenStartOrEnd ? (
<View style={[a.w_full, a.flex_row, a.align_center, a.gap_sm]}>
<IsValidIcon valid={validCheck.handleChars} />
<Text style={[a.text_md, a.flex_1]}>
<Trans>Only contains letters, numbers, and hyphens</Trans>
</Text>
</View>
) : (
<View style={[a.w_full, a.flex_row, a.align_center, a.gap_sm]}>
<IsValidIcon valid={validCheck.hyphenStartOrEnd} />
<Text style={[a.text_md, a.flex_1]}>
<Trans>Doesn't begin or end with a hyphen</Trans>
</Text>
</View>
)}
<View style={[a.w_full, a.flex_row, a.align_center, a.gap_sm]}>
<IsValidIcon
valid={validCheck.frontLength && validCheck.totalLength}
/>
{!validCheck.totalLength ? (
<Text style={[a.text_md, a.flex_1]}>
<Trans>
No longer than {maxServiceHandleLength(state.userDomain)}{' '}
characters
</Trans>
</Text>
{draftValue === '' ? (
isFirstTimeUser && (
<Admonition type="tip">
<Trans>
This is the unique name for your account. Pick something
memorable!
</Trans>
</Admonition>
)
) : (
<>
<Text style={[a.text_md]}>
<Trans>Your full username will be</Trans>{' '}
<Text style={[a.text_md, a.font_bold]}>
@{createFullHandle(draftValue, state.userDomain)}
</Text>
</Text>
<View
style={[
a.w_full,
a.rounded_sm,
a.border,
a.p_md,
a.gap_sm,
t.atoms.border_contrast_low,
]}>
{state.error ? (
<View style={[a.w_full, a.flex_row, a.align_center, a.gap_sm]}>
<IsValidIcon valid={false} />
<Text style={[a.text_md, a.flex_1]}>{state.error}</Text>
</View>
) : undefined}
{validCheck.hyphenStartOrEnd ? (
<View style={[a.w_full, a.flex_row, a.align_center, a.gap_sm]}>
<IsValidIcon valid={validCheck.handleChars} />
<Text style={[a.text_md, a.flex_1]}>
<Trans>Only contains letters, numbers, and hyphens</Trans>
</Text>
</View>
) : (
<Text style={[a.text_md, a.flex_1]}>
<Trans>At least 3 characters</Trans>
</Text>
<View style={[a.w_full, a.flex_row, a.align_center, a.gap_sm]}>
<IsValidIcon valid={validCheck.hyphenStartOrEnd} />
<Text style={[a.text_md, a.flex_1]}>
<Trans>Doesn't begin or end with a hyphen</Trans>
</Text>
</View>
)}
<View style={[a.w_full, a.flex_row, a.align_center, a.gap_sm]}>
<IsValidIcon
valid={validCheck.frontLength && validCheck.totalLength}
/>
{!validCheck.totalLength ? (
<Text style={[a.text_md, a.flex_1]}>
<Trans>
No longer than {maxServiceHandleLength(state.userDomain)}{' '}
characters
</Trans>
</Text>
) : (
<Text style={[a.text_md, a.flex_1]}>
<Trans>At least 3 characters</Trans>
</Text>
)}
</View>
</View>
</View>
</>
)}
</View>
<BackNextButtons
Expand Down
Loading