Internationalization & localization (#1822)
* install and setup lingui * setup dynamic locale activation and async loading * first pass of automated replacement of text messages * add some more documentaton * fix nits * add `es` and `hi`locales for testing purposes * make accessibilityLabel localized * compile and extract new messages * fix merge conflicts * fix eslint warning * change instructions from sending email to opening PR * fix comments
This commit is contained in:
@@ -15,6 +15,8 @@ import {s} from 'lib/styles'
|
||||
import {useStores} from 'state/index'
|
||||
import {CreateAccountModel} from 'state/models/ui/create-account'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useOnboardingDispatch} from '#/state/shell'
|
||||
|
||||
import {Step1} from './Step1'
|
||||
@@ -30,6 +32,7 @@ export const CreateAccount = observer(function CreateAccountImpl({
|
||||
const pal = usePalette('default')
|
||||
const store = useStores()
|
||||
const model = React.useMemo(() => new CreateAccountModel(store), [store])
|
||||
const {_} = useLingui()
|
||||
const onboardingDispatch = useOnboardingDispatch()
|
||||
|
||||
React.useEffect(() => {
|
||||
@@ -73,8 +76,8 @@ export const CreateAccount = observer(function CreateAccountImpl({
|
||||
return (
|
||||
<LoggedOutLayout
|
||||
leadin={`Step ${model.step}`}
|
||||
title="Create Account"
|
||||
description="We're so excited to have you join us!">
|
||||
title={_(msg`Create Account`)}
|
||||
description={_(msg`We're so excited to have you join us!`)}>
|
||||
<ScrollView testID="createAccount" style={pal.view}>
|
||||
<KeyboardAvoidingView behavior="padding">
|
||||
<View style={styles.stepContainer}>
|
||||
@@ -88,7 +91,7 @@ export const CreateAccount = observer(function CreateAccountImpl({
|
||||
testID="backBtn"
|
||||
accessibilityRole="button">
|
||||
<Text type="xl" style={pal.link}>
|
||||
Back
|
||||
<Trans>Back</Trans>
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<View style={s.flex1} />
|
||||
@@ -101,7 +104,7 @@ export const CreateAccount = observer(function CreateAccountImpl({
|
||||
<ActivityIndicator />
|
||||
) : (
|
||||
<Text type="xl-bold" style={[pal.link, s.pr5]}>
|
||||
Next
|
||||
<Trans>Next</Trans>
|
||||
</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
@@ -110,18 +113,18 @@ export const CreateAccount = observer(function CreateAccountImpl({
|
||||
testID="retryConnectBtn"
|
||||
onPress={onPressRetryConnect}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Retry"
|
||||
accessibilityLabel={_(msg`Retry`)}
|
||||
accessibilityHint="Retries account creation"
|
||||
accessibilityLiveRegion="polite">
|
||||
<Text type="xl-bold" style={[pal.link, s.pr5]}>
|
||||
Retry
|
||||
<Trans>Retry</Trans>
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
) : model.isFetchingServiceDescription ? (
|
||||
<>
|
||||
<ActivityIndicator color="#fff" />
|
||||
<Text type="xl" style={[pal.text, s.pr5]}>
|
||||
Connecting...
|
||||
<Trans>Connecting...</Trans>
|
||||
</Text>
|
||||
</>
|
||||
) : undefined}
|
||||
|
||||
@@ -12,6 +12,8 @@ import {HelpTip} from '../util/HelpTip'
|
||||
import {TextInput} from '../util/TextInput'
|
||||
import {Button} from 'view/com/util/forms/Button'
|
||||
import {ErrorMessage} from 'view/com/util/error/ErrorMessage'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {LOCAL_DEV_SERVICE, STAGING_SERVICE, PROD_SERVICE} from 'state/index'
|
||||
import {LOGIN_INCLUDE_DEV_SERVERS} from 'lib/build-flags'
|
||||
@@ -27,6 +29,7 @@ export const Step1 = observer(function Step1Impl({
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const [isDefaultSelected, setIsDefaultSelected] = React.useState(true)
|
||||
const {_} = useLingui()
|
||||
|
||||
const onPressDefault = React.useCallback(() => {
|
||||
setIsDefaultSelected(true)
|
||||
@@ -63,9 +66,9 @@ export const Step1 = observer(function Step1Impl({
|
||||
|
||||
return (
|
||||
<View>
|
||||
<StepHeader step="1" title="Your hosting provider" />
|
||||
<StepHeader step="1" title={_(msg`Your hosting provider`)} />
|
||||
<Text style={[pal.text, s.mb10]}>
|
||||
This is the service that keeps you online.
|
||||
<Trans>This is the service that keeps you online.</Trans>
|
||||
</Text>
|
||||
<Option
|
||||
testID="blueskyServerBtn"
|
||||
@@ -81,17 +84,17 @@ export const Step1 = observer(function Step1Impl({
|
||||
onPress={onPressOther}>
|
||||
<View style={styles.otherForm}>
|
||||
<Text nativeID="addressProvider" style={[pal.text, s.mb5]}>
|
||||
Enter the address of your provider:
|
||||
<Trans>Enter the address of your provider:</Trans>
|
||||
</Text>
|
||||
<TextInput
|
||||
testID="customServerInput"
|
||||
icon="globe"
|
||||
placeholder="Hosting provider address"
|
||||
placeholder={_(msg`Hosting provider address`)}
|
||||
value={model.serviceUrl}
|
||||
editable
|
||||
onChange={onChangeServiceUrl}
|
||||
accessibilityHint="Input hosting provider address"
|
||||
accessibilityLabel="Hosting provider address"
|
||||
accessibilityLabel={_(msg`Hosting provider address`)}
|
||||
accessibilityLabelledBy="addressProvider"
|
||||
/>
|
||||
{LOGIN_INCLUDE_DEV_SERVERS && (
|
||||
@@ -100,13 +103,13 @@ export const Step1 = observer(function Step1Impl({
|
||||
testID="stagingServerBtn"
|
||||
type="default"
|
||||
style={s.mr5}
|
||||
label="Staging"
|
||||
label={_(msg`Staging`)}
|
||||
onPress={() => onDebugChangeServiceUrl(STAGING_SERVICE)}
|
||||
/>
|
||||
<Button
|
||||
testID="localDevServerBtn"
|
||||
type="default"
|
||||
label="Dev Server"
|
||||
label={_(msg`Dev Server`)}
|
||||
onPress={() => onDebugChangeServiceUrl(LOCAL_DEV_SERVICE)}
|
||||
/>
|
||||
</View>
|
||||
@@ -116,7 +119,7 @@ export const Step1 = observer(function Step1Impl({
|
||||
{model.error ? (
|
||||
<ErrorMessage message={model.error} style={styles.error} />
|
||||
) : (
|
||||
<HelpTip text="You can change hosting providers at any time." />
|
||||
<HelpTip text={_(msg`You can change hosting providers at any time.`)} />
|
||||
)}
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -11,6 +11,8 @@ import {TextInput} from '../util/TextInput'
|
||||
import {Policies} from './Policies'
|
||||
import {ErrorMessage} from 'view/com/util/error/ErrorMessage'
|
||||
import {isWeb} from 'platform/detection'
|
||||
import {Trans, msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useModalControls} from '#/state/modals'
|
||||
|
||||
/** STEP 2: Your account
|
||||
@@ -28,6 +30,7 @@ export const Step2 = observer(function Step2Impl({
|
||||
model: CreateAccountModel
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
const {openModal} = useModalControls()
|
||||
|
||||
const onPressWaitlist = React.useCallback(() => {
|
||||
@@ -36,7 +39,7 @@ export const Step2 = observer(function Step2Impl({
|
||||
|
||||
return (
|
||||
<View>
|
||||
<StepHeader step="2" title="Your account" />
|
||||
<StepHeader step="2" title={_(msg`Your account`)} />
|
||||
|
||||
{model.isInviteCodeRequired && (
|
||||
<View style={s.pb20}>
|
||||
@@ -46,11 +49,11 @@ export const Step2 = observer(function Step2Impl({
|
||||
<TextInput
|
||||
testID="inviteCodeInput"
|
||||
icon="ticket"
|
||||
placeholder="Required for this provider"
|
||||
placeholder={_(msg`Required for this provider`)}
|
||||
value={model.inviteCode}
|
||||
editable
|
||||
onChange={model.setInviteCode}
|
||||
accessibilityLabel="Invite code"
|
||||
accessibilityLabel={_(msg`Invite code`)}
|
||||
accessibilityHint="Input invite code to proceed"
|
||||
/>
|
||||
</View>
|
||||
@@ -61,10 +64,12 @@ export const Step2 = observer(function Step2Impl({
|
||||
Don't have an invite code?{' '}
|
||||
<TouchableWithoutFeedback
|
||||
onPress={onPressWaitlist}
|
||||
accessibilityLabel="Join the waitlist."
|
||||
accessibilityLabel={_(msg`Join the waitlist.`)}
|
||||
accessibilityHint="">
|
||||
<View style={styles.touchable}>
|
||||
<Text style={pal.link}>Join the waitlist.</Text>
|
||||
<Text style={pal.link}>
|
||||
<Trans>Join the waitlist.</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</Text>
|
||||
@@ -72,16 +77,16 @@ export const Step2 = observer(function Step2Impl({
|
||||
<>
|
||||
<View style={s.pb20}>
|
||||
<Text type="md-medium" style={[pal.text, s.mb2]} nativeID="email">
|
||||
Email address
|
||||
<Trans>Email address</Trans>
|
||||
</Text>
|
||||
<TextInput
|
||||
testID="emailInput"
|
||||
icon="envelope"
|
||||
placeholder="Enter your email address"
|
||||
placeholder={_(msg`Enter your email address`)}
|
||||
value={model.email}
|
||||
editable
|
||||
onChange={model.setEmail}
|
||||
accessibilityLabel="Email"
|
||||
accessibilityLabel={_(msg`Email`)}
|
||||
accessibilityHint="Input email for Bluesky waitlist"
|
||||
accessibilityLabelledBy="email"
|
||||
/>
|
||||
@@ -92,17 +97,17 @@ export const Step2 = observer(function Step2Impl({
|
||||
type="md-medium"
|
||||
style={[pal.text, s.mb2]}
|
||||
nativeID="password">
|
||||
Password
|
||||
<Trans>Password</Trans>
|
||||
</Text>
|
||||
<TextInput
|
||||
testID="passwordInput"
|
||||
icon="lock"
|
||||
placeholder="Choose your password"
|
||||
placeholder={_(msg`Choose your password`)}
|
||||
value={model.password}
|
||||
editable
|
||||
secureTextEntry
|
||||
onChange={model.setPassword}
|
||||
accessibilityLabel="Password"
|
||||
accessibilityLabel={_(msg`Password`)}
|
||||
accessibilityHint="Set password"
|
||||
accessibilityLabelledBy="password"
|
||||
/>
|
||||
@@ -113,7 +118,7 @@ export const Step2 = observer(function Step2Impl({
|
||||
type="md-medium"
|
||||
style={[pal.text, s.mb2]}
|
||||
nativeID="birthDate">
|
||||
Your birth date
|
||||
<Trans>Your birth date</Trans>
|
||||
</Text>
|
||||
<DateInput
|
||||
testID="birthdayInput"
|
||||
@@ -122,7 +127,7 @@ export const Step2 = observer(function Step2Impl({
|
||||
buttonType="default-light"
|
||||
buttonStyle={[pal.border, styles.dateInputButton]}
|
||||
buttonLabelType="lg"
|
||||
accessibilityLabel="Birthday"
|
||||
accessibilityLabel={_(msg`Birthday`)}
|
||||
accessibilityHint="Enter your birth date"
|
||||
accessibilityLabelledBy="birthDate"
|
||||
/>
|
||||
|
||||
@@ -9,6 +9,8 @@ import {TextInput} from '../util/TextInput'
|
||||
import {createFullHandle} from 'lib/strings/handles'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {ErrorMessage} from 'view/com/util/error/ErrorMessage'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
/** STEP 3: Your user handle
|
||||
* @field User handle
|
||||
@@ -19,9 +21,10 @@ export const Step3 = observer(function Step3Impl({
|
||||
model: CreateAccountModel
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
return (
|
||||
<View>
|
||||
<StepHeader step="3" title="Your user handle" />
|
||||
<StepHeader step="3" title={_(msg`Your user handle`)} />
|
||||
<View style={s.pb10}>
|
||||
<TextInput
|
||||
testID="handleInput"
|
||||
@@ -31,12 +34,12 @@ export const Step3 = observer(function Step3Impl({
|
||||
editable
|
||||
onChange={model.setHandle}
|
||||
// TODO: Add explicit text label
|
||||
accessibilityLabel="User handle"
|
||||
accessibilityLabel={_(msg`User handle`)}
|
||||
accessibilityHint="Input your user handle"
|
||||
/>
|
||||
<Text type="lg" style={[pal.text, s.pl5, s.pt10]}>
|
||||
Your full handle will be{' '}
|
||||
<Text type="lg-bold" style={pal.text}>
|
||||
<Trans>Your full handle will be</Trans>
|
||||
<Text type="lg-bold" style={[pal.text, s.ml5]}>
|
||||
@{createFullHandle(model.handle, model.userDomain)}
|
||||
</Text>
|
||||
</Text>
|
||||
|
||||
Reference in New Issue
Block a user