change gutter, add email screen

This commit is contained in:
Samuel Newman
2025-07-16 11:04:12 +03:00
parent afbe97e4ca
commit 37d2c90c09
9 changed files with 171 additions and 40 deletions
+5 -1
View File
@@ -182,7 +182,11 @@ function AccountItem({
{isCurrentAccount ? ( {isCurrentAccount ? (
<View <View
style={[ style={[
{width: 20, height: 20, backgroundColor: t.palette.primary_500}, {
width: 20,
height: 20,
backgroundColor: t.palette.positive_600,
},
a.rounded_full, a.rounded_full,
a.justify_center, a.justify_center,
a.align_center, a.align_center,
@@ -3,6 +3,7 @@ import {
type NativeStackScreenProps, type NativeStackScreenProps,
} from '#/lib/routes/types' } from '#/lib/routes/types'
import {Logo} from '#/view/icons/Logo' import {Logo} from '#/view/icons/Logo'
import {atoms as a} from '#/alf'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import * as Layout from './components/Layout' import * as Layout from './components/Layout'
@@ -21,7 +22,7 @@ export function ForgotPasswordScreenInner() {
</Layout.Header.Content> </Layout.Header.Content>
<Layout.Header.Slot /> <Layout.Header.Slot />
</Layout.Header.Outer> </Layout.Header.Outer>
<Layout.Content> <Layout.Content contentContainerStyle={[a.px_2xl, a.py_lg]}>
<Text>TODO</Text> <Text>TODO</Text>
</Layout.Content> </Layout.Content>
</Layout.Screen> </Layout.Screen>
@@ -3,6 +3,7 @@ import {
type NativeStackScreenProps, type NativeStackScreenProps,
} from '#/lib/routes/types' } from '#/lib/routes/types'
import {Logo} from '#/view/icons/Logo' import {Logo} from '#/view/icons/Logo'
import {atoms as a} from '#/alf'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import * as Layout from './components/Layout' import * as Layout from './components/Layout'
@@ -21,7 +22,7 @@ export function PasswordUpdatedScreenInner() {
</Layout.Header.Content> </Layout.Header.Content>
<Layout.Header.Slot /> <Layout.Header.Slot />
</Layout.Header.Outer> </Layout.Header.Outer>
<Layout.Content> <Layout.Content contentContainerStyle={[a.px_2xl, a.py_lg]}>
<Text>TODO</Text> <Text>TODO</Text>
</Layout.Content> </Layout.Content>
</Layout.Screen> </Layout.Screen>
@@ -3,6 +3,7 @@ import {
type NativeStackScreenProps, type NativeStackScreenProps,
} from '#/lib/routes/types' } from '#/lib/routes/types'
import {Logo} from '#/view/icons/Logo' import {Logo} from '#/view/icons/Logo'
import {atoms as a} from '#/alf'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import * as Layout from './components/Layout' import * as Layout from './components/Layout'
@@ -21,7 +22,7 @@ export function SetNewPasswordScreenInner() {
</Layout.Header.Content> </Layout.Header.Content>
<Layout.Header.Slot /> <Layout.Header.Slot />
</Layout.Header.Outer> </Layout.Header.Outer>
<Layout.Content> <Layout.Content contentContainerStyle={[a.px_2xl, a.py_lg]}>
<Text>TODO</Text> <Text>TODO</Text>
</Layout.Content> </Layout.Content>
</Layout.Screen> </Layout.Screen>
+36 -28
View File
@@ -1,8 +1,10 @@
import {useEffect, useRef, useState} from 'react' import {useEffect, useRef, useState} from 'react'
import {KeyboardAvoidingView} from 'react-native-keyboard-controller'
import {msg, Trans} from '@lingui/macro' import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {DEFAULT_SERVICE} from '#/lib/constants' import {DEFAULT_SERVICE} from '#/lib/constants'
import {useEnableKeyboardControllerScreen} from '#/lib/hooks/useEnableKeyboardController'
import { import {
type AuthNavigatorParams, type AuthNavigatorParams,
type NativeStackScreenProps, type NativeStackScreenProps,
@@ -87,6 +89,8 @@ export function SignInScreenInner({
failedAttemptCountRef.current += 1 failedAttemptCountRef.current += 1
} }
useEnableKeyboardControllerScreen(true)
return ( return (
<Layout.Screen testID="SignInScreen"> <Layout.Screen testID="SignInScreen">
<Layout.Header.Outer noBottomBorder> <Layout.Header.Outer noBottomBorder>
@@ -96,34 +100,38 @@ export function SignInScreenInner({
</Layout.Header.Content> </Layout.Header.Content>
<Layout.Header.Slot /> <Layout.Header.Slot />
</Layout.Header.Outer> </Layout.Header.Outer>
<Layout.Content contentContainerStyle={[a.p_xl]}> <KeyboardAvoidingView style={[a.flex_1]} behavior="padding">
<Layout.TitleText> <Layout.Content
<Trans>Log in</Trans> style={[a.flex_1]}
</Layout.TitleText> contentContainerStyle={[a.px_2xl, a.py_lg]}>
<SignInForm <Layout.TitleText>
error={error} <Trans>Log in</Trans>
serviceUrl={serviceUrl} </Layout.TitleText>
serviceDescription={serviceDescription} <SignInForm
initialHandle={requestedAccount?.handle} error={error}
setError={setError} serviceUrl={serviceUrl}
onAttemptFailed={onAttemptFailed} serviceDescription={serviceDescription}
onAttemptSuccess={onAttemptSuccess} initialHandle={requestedAccount?.handle}
setServiceUrl={setServiceUrl} setError={setError}
onPressForgotPassword={onPressForgotPassword} onAttemptFailed={onAttemptFailed}
onPressRetryConnect={refetchService} onAttemptSuccess={onAttemptSuccess}
/> setServiceUrl={setServiceUrl}
<Text style={[a.text_md, a.text_center, a.w_full, a.mt_2xl]}> onPressForgotPassword={onPressForgotPassword}
<Trans> onPressRetryConnect={refetchService}
New to Bluesky?{' '} />
<Text <Text style={[a.text_md, a.text_center, a.w_full, a.mt_2xl]}>
role="link" <Trans>
onPress={signUp} New to Bluesky?{' '}
style={[a.text_md, {color: t.palette.primary_500}]}> <Text
Create account role="link"
</Text> onPress={signUp}
</Trans> style={[a.text_md, {color: t.palette.primary_500}]}>
</Text> Create account
</Layout.Content> </Text>
</Trans>
</Text>
</Layout.Content>
</KeyboardAvoidingView>
</Layout.Screen> </Layout.Screen>
) )
} }
@@ -3,6 +3,7 @@ import {
type NativeStackScreenProps, type NativeStackScreenProps,
} from '#/lib/routes/types' } from '#/lib/routes/types'
import {Logo} from '#/view/icons/Logo' import {Logo} from '#/view/icons/Logo'
import {atoms as a} from '#/alf'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import * as Layout from './components/Layout' import * as Layout from './components/Layout'
@@ -21,7 +22,7 @@ export function SignUpCaptchaScreenInner() {
</Layout.Header.Content> </Layout.Header.Content>
<Layout.Header.Slot /> <Layout.Header.Slot />
</Layout.Header.Outer> </Layout.Header.Outer>
<Layout.Content> <Layout.Content contentContainerStyle={[a.px_2xl, a.py_lg]}>
<Text>TODO</Text> <Text>TODO</Text>
</Layout.Content> </Layout.Content>
</Layout.Screen> </Layout.Screen>
@@ -3,6 +3,7 @@ import {
type NativeStackScreenProps, type NativeStackScreenProps,
} from '#/lib/routes/types' } from '#/lib/routes/types'
import {Logo} from '#/view/icons/Logo' import {Logo} from '#/view/icons/Logo'
import {atoms as a} from '#/alf'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import * as Layout from './components/Layout' import * as Layout from './components/Layout'
@@ -21,7 +22,7 @@ export function SignUpHandleScreenInner() {
</Layout.Header.Content> </Layout.Header.Content>
<Layout.Header.Slot /> <Layout.Header.Slot />
</Layout.Header.Outer> </Layout.Header.Outer>
<Layout.Content> <Layout.Content contentContainerStyle={[a.px_2xl, a.py_lg]}>
<Text>TODO</Text> <Text>TODO</Text>
</Layout.Content> </Layout.Content>
</Layout.Screen> </Layout.Screen>
+118 -4
View File
@@ -1,9 +1,21 @@
import {useState} from 'react'
import {View} from 'react-native'
import {KeyboardAvoidingView} from 'react-native-keyboard-controller'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useEnableKeyboardControllerScreen} from '#/lib/hooks/useEnableKeyboardController'
import { import {
type AuthNavigatorParams, type AuthNavigatorParams,
type NativeStackScreenProps, type NativeStackScreenProps,
} from '#/lib/routes/types' } from '#/lib/routes/types'
import {Logo} from '#/view/icons/Logo' import {Logo} from '#/view/icons/Logo'
import {Text} from '#/components/Typography' import {atoms as a, native, platform, tokens} from '#/alf'
import {Button, ButtonText} from '#/components/Button'
import * as TextField from '#/components/forms/TextField'
import {Envelope_Stroke2_Corner0_Rounded as EnvelopeIcon} from '#/components/icons/Envelope'
import {Policies} from '../Signup/StepInfo/Policies'
import * as Layout from './components/Layout' import * as Layout from './components/Layout'
type Props = NativeStackScreenProps<AuthNavigatorParams, 'SignUpInfo'> type Props = NativeStackScreenProps<AuthNavigatorParams, 'SignUpInfo'>
@@ -12,6 +24,13 @@ export function SignUpInfoScreen({}: Props) {
} }
export function SignUpInfoScreenInner() { export function SignUpInfoScreenInner() {
const {_} = useLingui()
const [email, setEmail] = useState('')
const {bottom} = useSafeAreaInsets()
useEnableKeyboardControllerScreen(true)
return ( return (
<Layout.Screen testID="SignUpInfoScreen"> <Layout.Screen testID="SignUpInfoScreen">
<Layout.Header.Outer noBottomBorder> <Layout.Header.Outer noBottomBorder>
@@ -21,9 +40,104 @@ export function SignUpInfoScreenInner() {
</Layout.Header.Content> </Layout.Header.Content>
<Layout.Header.Slot /> <Layout.Header.Slot />
</Layout.Header.Outer> </Layout.Header.Outer>
<Layout.Content> <KeyboardAvoidingView
<Text>TODO</Text> style={[a.flex_1]}
</Layout.Content> behavior="padding"
keyboardVerticalOffset={Math.min(
0,
tokens.space._2xl -
(bottom +
platform({
ios: tokens.space.xs,
android: tokens.space.sm,
default: 0,
})),
)}>
<Layout.Content
style={[a.flex_1]}
contentContainerStyle={[a.px_2xl, a.py_lg]}>
<Layout.TitleText>
<Trans>Email</Trans>
</Layout.TitleText>
<View style={[a.mt_lg]}>
<TextField.Root>
<TextField.Icon icon={EnvelopeIcon} />
<TextField.Input
testID="emailInput"
value={email}
onChangeText={value => {
// emailValueRef.current = value.trim()
// if (hasWarnedEmail) {
// setHasWarnedEmail(false)
// }
// if (
// state.errorField === 'email' &&
// value.trim().length > 0 &&
// EmailValidator.validate(value.trim())
// ) {
// dispatch({type: 'clearError'})
// }
setEmail(value)
}}
label={_(msg`name@email.com`)}
autoFocus
autoCapitalize="none"
autoComplete="email"
keyboardType="email-address"
returnKeyType="next"
submitBehavior={native('submit')}
onSubmitEditing={
// TODO
() => console.log('submit')
}
/>
</TextField.Root>
</View>
</Layout.Content>
<View
style={[
a.px_2xl,
{
paddingBottom: Math.max(
tokens.space._2xl,
bottom +
platform({
ios: tokens.space.xs,
android: tokens.space.sm,
default: 0,
}),
),
},
a.gap_md,
]}>
<Policies
serviceDescription={{
availableUserDomains: ['bsky.social'],
did: 'did:plc:example',
links: {
privacyPolicy: 'https://example.com/pp',
termsOfService: 'https://example.com/terms',
},
}}
needsGuardian={true}
under13={false}
// needsGuardian={!is18(state.dateOfBirth)}
// under13={!is13(state.dateOfBirth)}
/>
<Button
testID="emailNextButton"
label={_(msg`Continue`)}
accessibilityHint={_(msg`Go to the next step`)}
variant="solid"
color="primary"
size="large">
<ButtonText>
<Trans>Continue</Trans>
</ButtonText>
{/* {isProcessing && <ButtonIcon icon={Loader} />} */}
</Button>
</View>
</KeyboardAvoidingView>
</Layout.Screen> </Layout.Screen>
) )
} }
@@ -172,7 +172,7 @@ export function SignInForm({
} }
return ( return (
<View style={[a.pt_2xl, a.gap_md]}> <View style={[a.pt_2xl, a.gap_lg]}>
<View> <View>
<TextField.LabelText> <TextField.LabelText>
<Trans>Username or email address</Trans> <Trans>Username or email address</Trans>
@@ -245,7 +245,7 @@ export function SignInForm({
accessibilityHint={_(msg`Opens password reset form`)} accessibilityHint={_(msg`Opens password reset form`)}
variant="ghost" variant="ghost"
color="secondary"> color="secondary">
<ButtonText> <ButtonText style={[a.font_normal]}>
<Trans>Forgot password?</Trans> <Trans>Forgot password?</Trans>
</ButtonText> </ButtonText>
</Button> </Button>