add intro step
This commit is contained in:
@@ -0,0 +1,78 @@
|
|||||||
|
import {View} from 'react-native'
|
||||||
|
import * as Contacts from 'expo-contacts'
|
||||||
|
import {msg, Trans} from '@lingui/macro'
|
||||||
|
import {useLingui} from '@lingui/react'
|
||||||
|
import {useQuery} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
|
import {Admonition} from '#/components/Admonition'
|
||||||
|
import {Button, ButtonText} from '#/components/Button'
|
||||||
|
import {ContactsHeroImage} from '#/components/contacts/components/HeroImage'
|
||||||
|
import {InlineLinkText} from '#/components/Link'
|
||||||
|
import {Text} from '#/components/Typography'
|
||||||
|
import {OnboardingControls} from '../Layout'
|
||||||
|
import {useOnboardingInternalState} from '../state'
|
||||||
|
|
||||||
|
export function StepFindContactsIntro() {
|
||||||
|
const {_} = useLingui()
|
||||||
|
const t = useTheme()
|
||||||
|
const {dispatch} = useOnboardingInternalState()
|
||||||
|
|
||||||
|
const {data: isAvailable, isSuccess} = useQuery({
|
||||||
|
queryKey: ['contacts-available'],
|
||||||
|
queryFn: async () => await Contacts.isAvailableAsync(),
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={[a.w_full, a.gap_lg]}>
|
||||||
|
<ContactsHeroImage />
|
||||||
|
<Text style={[a.text_3xl, a.leading_snug, a.font_bold]}>
|
||||||
|
<Trans>Bluesky is more fun with Friends</Trans>
|
||||||
|
</Text>
|
||||||
|
<Text style={[a.text_md, a.leading_snug, t.atoms.text_contrast_medium]}>
|
||||||
|
<Trans>
|
||||||
|
Find your friends on Bluesky by verifying your phone number and
|
||||||
|
matching with your contacts. We protect your information and you
|
||||||
|
control what happens next.{' '}
|
||||||
|
<InlineLinkText
|
||||||
|
to="#"
|
||||||
|
label={_(msg`Learn more`)}
|
||||||
|
style={[a.text_md, a.leading_snug]}>
|
||||||
|
TODO: Learn more
|
||||||
|
</InlineLinkText>
|
||||||
|
</Trans>
|
||||||
|
</Text>
|
||||||
|
{!isAvailable && isSuccess && (
|
||||||
|
<Admonition type="error">
|
||||||
|
<Trans>
|
||||||
|
Contact sync is not available on this device, as the app is unable
|
||||||
|
to access your contacts.
|
||||||
|
</Trans>
|
||||||
|
</Admonition>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<OnboardingControls.Portal>
|
||||||
|
<View style={[a.gap_md]}>
|
||||||
|
<Button
|
||||||
|
onPress={() => dispatch({type: 'next'})}
|
||||||
|
label={_(msg`Upload contacts`)}
|
||||||
|
size="large"
|
||||||
|
color="primary">
|
||||||
|
<ButtonText>
|
||||||
|
<Trans>Upload contacts</Trans>
|
||||||
|
</ButtonText>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onPress={() => dispatch({type: 'skip-contacts'})}
|
||||||
|
label={_(msg`Skip`)}
|
||||||
|
size="large"
|
||||||
|
color="secondary">
|
||||||
|
<ButtonText>
|
||||||
|
<Trans>Skip</Trans>
|
||||||
|
</ButtonText>
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</OnboardingControls.Portal>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ import {Portal} from '#/components/Portal'
|
|||||||
import {ScreenTransition} from '#/components/ScreenTransition'
|
import {ScreenTransition} from '#/components/ScreenTransition'
|
||||||
import {ENV} from '#/env'
|
import {ENV} from '#/env'
|
||||||
import {StepFindContacts} from './StepFindContacts'
|
import {StepFindContacts} from './StepFindContacts'
|
||||||
|
import {StepFindContactsIntro} from './StepFindContactsIntro'
|
||||||
import {StepSuggestedAccounts} from './StepSuggestedAccounts'
|
import {StepSuggestedAccounts} from './StepSuggestedAccounts'
|
||||||
import {StepSuggestedStarterpacks} from './StepSuggestedStarterpacks'
|
import {StepSuggestedStarterpacks} from './StepSuggestedStarterpacks'
|
||||||
|
|
||||||
@@ -67,6 +68,7 @@ export function Onboarding() {
|
|||||||
key={state.activeStep}
|
key={state.activeStep}
|
||||||
direction={state.stepTransitionDirection}
|
direction={state.stepTransitionDirection}
|
||||||
style={a.flex_1}>
|
style={a.flex_1}>
|
||||||
|
{/* FindContactsFlow cannot be nested in Layout */}
|
||||||
{state.activeStep === 'find-contacts' ? (
|
{state.activeStep === 'find-contacts' ? (
|
||||||
<StepFindContacts />
|
<StepFindContacts />
|
||||||
) : (
|
) : (
|
||||||
@@ -79,6 +81,9 @@ export function Onboarding() {
|
|||||||
{state.activeStep === 'suggested-starterpacks' && (
|
{state.activeStep === 'suggested-starterpacks' && (
|
||||||
<StepSuggestedStarterpacks />
|
<StepSuggestedStarterpacks />
|
||||||
)}
|
)}
|
||||||
|
{state.activeStep === 'find-contacts-intro' && (
|
||||||
|
<StepFindContactsIntro />
|
||||||
|
)}
|
||||||
{state.activeStep === 'finished' && <StepFinished />}
|
{state.activeStep === 'finished' && <StepFinished />}
|
||||||
</Layout>
|
</Layout>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ type OnboardingScreen =
|
|||||||
| 'interests'
|
| 'interests'
|
||||||
| 'suggested-accounts'
|
| 'suggested-accounts'
|
||||||
| 'suggested-starterpacks'
|
| 'suggested-starterpacks'
|
||||||
|
| 'find-contacts-intro'
|
||||||
| 'find-contacts'
|
| 'find-contacts'
|
||||||
| 'finished'
|
| 'finished'
|
||||||
|
|
||||||
@@ -47,6 +48,9 @@ export type OnboardingAction =
|
|||||||
| {
|
| {
|
||||||
type: 'prev'
|
type: 'prev'
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
type: 'skip-contacts'
|
||||||
|
}
|
||||||
| {
|
| {
|
||||||
type: 'finish'
|
type: 'finish'
|
||||||
}
|
}
|
||||||
@@ -82,6 +86,7 @@ export function createInitialOnboardingState(
|
|||||||
interests: true,
|
interests: true,
|
||||||
'suggested-accounts': true,
|
'suggested-accounts': true,
|
||||||
'suggested-starterpacks': starterPacksStepEnabled,
|
'suggested-starterpacks': starterPacksStepEnabled,
|
||||||
|
'find-contacts-intro': findContactsStepEnabled,
|
||||||
'find-contacts': findContactsStepEnabled,
|
'find-contacts': findContactsStepEnabled,
|
||||||
finished: true,
|
finished: true,
|
||||||
}
|
}
|
||||||
@@ -130,11 +135,24 @@ export function reducer(
|
|||||||
const prevIndex = stepOrder.indexOf(next.activeStep) - 1
|
const prevIndex = stepOrder.indexOf(next.activeStep) - 1
|
||||||
const prevStep = stepOrder[prevIndex]
|
const prevStep = stepOrder[prevIndex]
|
||||||
if (prevStep) {
|
if (prevStep) {
|
||||||
|
// override back behaviour for the find contacts screen
|
||||||
|
// so returning to the flow takes you to the intro screen
|
||||||
|
if (prevStep === 'find-contacts') {
|
||||||
|
next.activeStep = 'find-contacts-intro'
|
||||||
|
} else {
|
||||||
next.activeStep = prevStep
|
next.activeStep = prevStep
|
||||||
}
|
}
|
||||||
|
}
|
||||||
next.stepTransitionDirection = 'Backward'
|
next.stepTransitionDirection = 'Backward'
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
case 'skip-contacts': {
|
||||||
|
const nextIndex = stepOrder.indexOf('find-contacts') + 1
|
||||||
|
const nextStep = stepOrder[nextIndex] ?? 'finished'
|
||||||
|
next.activeStep = nextStep
|
||||||
|
next.stepTransitionDirection = 'Forward'
|
||||||
|
break
|
||||||
|
}
|
||||||
case 'finish': {
|
case 'finish': {
|
||||||
next = createInitialOnboardingState({
|
next = createInitialOnboardingState({
|
||||||
starterPacksStepEnabled: s.screens['suggested-starterpacks'],
|
starterPacksStepEnabled: s.screens['suggested-starterpacks'],
|
||||||
@@ -187,6 +205,7 @@ function getStepOrder(s: OnboardingState): OnboardingScreen[] {
|
|||||||
s.screens.interests && ('interests' as const),
|
s.screens.interests && ('interests' as const),
|
||||||
s.screens['suggested-accounts'] && ('suggested-accounts' as const),
|
s.screens['suggested-accounts'] && ('suggested-accounts' as const),
|
||||||
s.screens['suggested-starterpacks'] && ('suggested-starterpacks' as const),
|
s.screens['suggested-starterpacks'] && ('suggested-starterpacks' as const),
|
||||||
|
s.screens['find-contacts-intro'] && ('find-contacts-intro' as const),
|
||||||
s.screens['find-contacts'] && ('find-contacts' as const),
|
s.screens['find-contacts'] && ('find-contacts' as const),
|
||||||
s.screens.finished && ('finished' as const),
|
s.screens.finished && ('finished' as const),
|
||||||
].filter(x => !!x)
|
].filter(x => !!x)
|
||||||
|
|||||||
Reference in New Issue
Block a user